Module:PageFilter
Jump to navigation
Jump to search
Documentation for this module may be created at Module:PageFilter/doc
local M = {}
local queryTables, queryFields = {
character = 'characters',
summon = 'summons',
weapon = 'weapons',
}, {
character = 'id,_pageName=link,rarity,type,element,race,weapon,series',
summon = '_pageName=link,id,rarity,element,evo_max,obtain,series',
weapon = '_pageName=link,rarity,type,element,evo_max,obtain,series',
}
function M.getFilterQueryInfo(filterObjectType)
return queryTables[filterObjectType], queryFields[filterObjectType]
end
local dataTransforms = {}
function dataTransforms.character(args)
args.race = args.race or 'none'
args.shortid = args.id and args.id:sub(3,3) .. args.id:sub(5,7) or ''
args.ftype, args.link, args.id = 'c'
args.series = args.series or "none"
end
function dataTransforms.weapon(args)
args.ftype, args.link = "w", nil
args.series = args.series or "none"
end
function dataTransforms.summon(args)
args.shortid = args.id and args.id:sub(3,3) .. args.id:sub(5,7) or ''
args.ftype, args.link, args.id = 's'
args.series = args.series or "none"
end
function M.transformFilterData(filterObjectType, row, modifyInPlace)
local ret, tf = row, dataTransforms[filterObjectType]
if not modifyInPlace then
ret = {}
for k, e in queryFields[filterObjectType]:gmatch('([^,=]+)(=?)') do
if e == '' then
ret[k] = row[k]
end
end
end
if tf then
tf(ret)
end
return ret
end
local dataNames = {
shortid = "short-id",
ftype = "type",
evo_max = "filter-evo-max",
}
function M.renderFilterAttributes(args)
local ret = {}
for k, v in pairs(args) do
if v ~= "" then
ret[#ret+1] = (' data-%s=%q'):format(dataNames[k] or ("filter-" .. k), v:lower():gsub("\n",""))
end
end
return table.concat(ret, "")
end
function M.renderFilterAttributesForData(filterObjectType, cargoRow, modifyInPlace)
return cargoRow and M.renderFilterAttributes(M.transformFilterData(filterObjectType, cargoRow, modifyInPlace)) or ""
end
local function normalizePageTitle(title)
return (title:match("^%s*(.-)%s*$"):gsub("^.[\128-\191]*", mw.ustring.upper))
end
for filterObjectType in pairs(queryTables) do
local fn = ('render%sFilterData'):format((filterObjectType:gsub('^.', string.upper)))
M[fn] = function(frame, link)
local page = link or frame.args.link or frame.args[1]
if not page then return "" end
local queryTable = queryTables[filterObjectType]
local queryColumns = queryFields[filterObjectType]
local queryArgs = {limit = 1, where = ('_pageName = %q'):format(normalizePageTitle(page))}
local cargoRow = mw.ext.cargo.query(queryTable, queryColumns, queryArgs)[1]
return M.renderFilterAttributesForData(filterObjectType, cargoRow, true)
end
end
-- older method name compatibility
M.renderFilterData = M.renderCharacterFilterData
function M.renderTemplateWithCharacterData(frame, template, link)
local template = template or frame.args.template or frame.args[1]
local page = link or frame.args.link or frame.args[2]
local filterObjectType = 'character'
local queryTable = queryTables[filterObjectType]
local queryColumns = queryFields[filterObjectType]
local queryArgs = {limit = 1, where = ('_pageName = %q'):format(normalizePageTitle(page))}
local cargoRow = mw.ext.cargo.query(queryTable, queryColumns, queryArgs)[1]
cargoRow.filter = M.renderFilterAttributesForData(filterObjectType, cargoRow)
if frame then
for k,v in pairs(frame.args) do
cargoRow[k] = v
end
end
return frame:expandTemplate{title = template, args = cargoRow}
end
function M.renderTemplateWithWeaponData(frame, template, link)
local template = template or frame.args.template or frame.args[1]
local page = link or frame.args.link or frame.args[2]
local filterObjectType = 'weapon'
local queryTable = queryTables[filterObjectType]
local queryColumns = queryFields[filterObjectType]
local queryArgs = {limit = 1, where = ('_pageName = %q'):format(normalizePageTitle(page))}
local cargoRow = mw.ext.cargo.query(queryTable, queryColumns, queryArgs)[1]
cargoRow.filter = M.renderFilterAttributesForData(filterObjectType, cargoRow)
if frame then
for k,v in pairs(frame.args) do
cargoRow[k] = v
end
end
return frame:expandTemplate{title = template, args = cargoRow}
end
local htmlEntities = {['>']='>', ['<']='<', ['"']='"'}
local function trimNonEmpty(s)
return s and s:match('^%s*(%S.-)%s*$')
end
local function trimAndEscape(s)
s = s and s:match('^%s*(%S.-)%s*$')
return s and s:gsub('[<">]', htmlEntities)
end
local function addCustomFilter(out, args, i, wrapInElement)
local kp = 'f' .. i
local ret = {
trimNonEmpty(args[kp .. "_label"]),
trimNonEmpty(args[kp .. "_datakey"]),
}
if not (ret[1] and ret[2]) then return end
local v = 1
while 1 do
local kvp = kp .. 'v' .. v
local label, value = trimNonEmpty(args[kvp .. '_label']), trimNonEmpty(args[kvp .. '_value'])
if not (label and value) then
break
end
ret[#ret+1], ret[#ret+2], v = label, value, v + 1
end
if v > 1 then
if wrapInElement then
out[#out+1] = '<' .. wrapInElement
end
out[#out+1] = (' data-extra-filter="%s"'):format(table.concat(ret,':'):gsub('[<">]', htmlEntities))
if wrapInElement then
out[#out+1] = '></' .. wrapInElement .. '>'
end
end
return true
end
function M.renderFilterBox(frame, args)
args = args or (frame.args.noparent and frame or frame:getParent()).args
local out = {'<div class="page-filter-container'}
if args.class and args.class:match("%S") then
out[#out+1] = " " .. args.class:gsub('[<">]', htmlEntities)
end
out[#out+1] = '"'
local skipFilters = trimAndEscape(args.skipFilters)
local whitelistFilters = trimAndEscape(args.onlyFilters)
out[#out+1] = skipFilters and (' data-skip-filters="%s"'):format(skipFilters)
out[#out+1] = whitelistFilters and (' data-only-filter="%s"'):format(whitelistFilters)
addCustomFilter(out, args, 1)
out[#out+1] = '>'
local f = 2
while addCustomFilter(out, args, f, 'span') do
f = f + 1
end
out[#out+1] = args.inner
out[#out+1] = '</div>'
out[#out+1] = args.post
out[#out+1] = '<div style="clear:both"></div>'
return table.concat(out, '')
end
function M.renderFilterContainerAttributes(frame, args)
args = args or frame.args
local groupID = trimNonEmpty(args.id or args[1])
groupID = groupID and groupID:gsub("[^a-z0-9%-_]+", '-'):match('^.*[^%-].*$')
groupID = groupID or ("gr-%04x%04x"):format(math.random(2^16)-1, math.random(2^16)-1)
return (' data-page-filter-group-id="%s"'):format(groupID:gsub('[<">]', htmlEntities))
end
return M