Module:JSONPageList

-- Demo for T332484 require( 'strict' ) local r={} --local lang="en" local site="enwiki" local siteprefix="en:"

local function get_link(qid, label) local sitelink=mw.wikibase.getSitelink(qid,site) label=label or mw.wikibase.getLabel(qid) if sitelink then return ..label.. else return ..label.. end end

local function get_heading(field) if field:match(":(.*)$") then return field:match(":(.*)$") elseif field=='@link' then return 'item' elseif field:sub(1,1)=='$' then local entity_id=field:sub(2):match("([PQpq]%d+)$") return mw.wikibase.getLabel(entity_id) else return field end end

local function get_cell(field, item, data_fields_map, raw) if field:match("(.*):.*$") then field=field:match("(.*):.*$") end local qid=item._qid if field=='@qid' then return qid or '' elseif field=='@link' then if qid and not item._page then return get_link(qid, item._name) else return ..item._name.. end elseif field=='@description' then return mw.wikibase.getDescription(qid) elseif field:sub(1,1)=='$' then local entity_path=field:sub(2) if entity_path:match("^([Pp]%d+)$") then return mw.getCurrentFrame:callParserFunction("#statements",{entity_path, from=qid}) elseif entity_path:match("^([Pp]%d+)/([Qq]%d+)/([Pp%d+)$") then local pid, qid2, pid2=entity_path:match("^([PQpq]%d+)/([PQpq]%d+)/([PQpq]%d+)$") local vals=mw.wikibase.getBestStatements(qid, pid) for _, v in ipairs(vals) do               if v.mainsnak.datavalue.value and v.mainsnak.datavalue.value.id==qid2 and v.qualifiers and v.qualifiers[pid2] then return mw.wikibase.formatValues(v.qualifiers[pid2]) end end end else if item[field] then return tostring(item[field]) elseif qid and data_fields_map[field] and data_fields_map[field].property then local vals=mw.wikibase.getBestStatements(qid, data_fields_map[field].property) if data_fields_map[field].enum_map and vals and vals[1] and vals[1].mainsnak.datavalue.value and data_fields_map[field].enum_map[vals[1].mainsnak.datavalue.value.id] then return tostring(data_fields_map[field].enum_map[vals[1].mainsnak.datavalue.value.id]) end end if data_fields_map[field] and data_fields_map[field].default then return tostring(data_fields_map[field].default) end end return '...' end

local function parse_params(pagename, result_fields, params) if type(pagename) == "table" then pagename, result_fields, params = pagename.args[1], pagename.args[2], pagename end if params:getParent and params:getParent.args[1] then pagename, result_fields, params = params:getParent.args[1], params:getParent.args[2], params:getParent end params=params.args return pagename, result_fields, params end

local function get_content(pagename) local content if mw.title.new( pagename ).namespace==828 then content=require(pagename) else content=mw.title.new(pagename):getContent content=mw.text.jsonDecode(content) end return content end

local function set_site(content) site=content.site or site siteprefix=content.siteprefix or siteprefix end

local function get_fields_and_items(content) local data_fields=content.fields or {} local data_fields_map={} for _, v in ipairs( data_fields ) do       if type(v)=="table" then data_fields_map[v[1]]=v end if v.enum then v.enum_map={} for _, p in ipairs( v.enum ) do               if type(p)=='table' then v.enum_map[p[2]]=p[1] end end end end local items=content.items for i, v in ipairs( items ) do       if type(v) == "string" then items[i]={_qid=v} end end return data_fields, data_fields_map, items end

local function clear_csv(param_str) if not param_str then return {} end local param_val=mw.text.split(param_str,',') local result={} for _,v in ipairs(param_val) do       if mw.text.trim(v)~='' then table.insert(result,mw.text.trim(v)) end end return result end

local function populate_result_fields(result_fields, data_fields) result_fields=clear_csv(result_fields) if #result_fields==0 then result_fields={'@link'} for _, v in ipairs( data_fields ) do           table.insert(result_fields,v[1] .. (v.display_name and (":"..v.display_name) or '')) end end return result_fields end

local function parse_data(pagename, result_fields, params) pagename, result_fields, params = parse_params(pagename, result_fields, params) local content=get_content(pagename) set_site(content) local data_fields, data_fields_map, items=get_fields_and_items(content) result_fields=populate_result_fields(result_fields, data_fields)

-- filter local filter=clear_csv(params.filter) if #filter>0 then local filtered_items={} for _, v in ipairs(items) do           local selected=true for _, v2 in ipairs(filter) do               if v2:match("(.-)==(.*)") then local l, r=v2:match("(.-)==(.*)") if get_cell(l,v,data_fields_map)~=r then selected=false break end elseif v2:match("(.-)!=(.*)") then local l, r=v2:match("(.-)!=(.*)") if get_cell(l,v,data_fields_map)==r then selected=false break end elseif v2:match("(.-)>=(.*)") then local l, r=v2:match("(.-)>=(.*)") if get_cell(l,v,data_fields_map)r then selected=false break end elseif v2:match("(.-)>(.*)") then local l, r=v2:match("(.-)>(.*)") if get_cell(l,v,data_fields_map)<=r then selected=false break end elseif v2:match("(.-)<(.*)") then local l, r=v2:match("(.-)<(.*)") if get_cell(l,v,data_fields_map)>=r then selected=false break end end end if selected then table.insert(filtered_items,v) end end items=filtered_items end

-- orderby

local orderby=clear_csv(params.orderby) local function _o(i1, i2) for _, v in ipairs(orderby) do           local v1=get_cell(v,i1,data_fields_map) local v2=get_cell(v,i2,data_fields_map) if v1v2 then return false end end return false end if #orderby>0 then table.sort(items, _o) end

-- groupby

local groupby=clear_csv(params.groupby) local item_groups={} for _, v in ipairs( items ) do       local cur_node=item_groups for _, v2 in ipairs(groupby) do           local subnode_name=get_cell(v2,v,data_fields_map) if cur_node[subnode_name]==nil then if cur_node._subnodes==nil then cur_node._subnodes={} end table.insert(cur_node._subnodes,subnode_name) cur_node[subnode_name]={} end cur_node=cur_node[subnode_name] end table.insert(cur_node,v) end return pagename, result_fields, params, content, data_fields, data_fields_map, item_groups end

function r.table(pagename, result_fields, params) local content, data_fields, data_fields_map, item_groups pagename, result_fields, params, content, data_fields, data_fields_map, item_groups=parse_data(pagename, result_fields, params) local result=mw.html.create("table"):attr( 'class', 'wikitable' ) local heading=result:tag("tr") for i, field in ipairs( result_fields ) do       heading:tag("th"):wikitext(get_heading(field)) end local function populate_table(node, level) for _, item in ipairs(node) do           local row=result:tag("tr") for _, field in ipairs( result_fields ) do               row:tag("td"):wikitext(get_cell(field,item,data_fields_map)) end end if node._subnodes then for _, v in ipairs(node._subnodes) do               result:tag("tr"):tag("td"):attr("colspan",#result_fields):wikitext('\n' .. ('='):rep(level) .. v .. ('='):rep(level) .. '\n') populate_table(node[v], level+1) end end end populate_table(item_groups, tonumber(params.level) or 2) return tostring( result ) end

function r.plainlist(pagename, result_fields, params) local content, data_fields, data_fields_map, item_groups pagename, result_fields, params, content, data_fields, data_fields_map, item_groups=parse_data(pagename, result_fields, params) local all_results={} local function populate_plainlist(node, level) local clear_node={} if node[1] then for _, v in ipairs(node) do               table.insert(clear_node,get_cell("@link",v,data_fields_map)) end end table.insert(all_results,table.concat(clear_node,', ')) if node._subnodes then for _, v in ipairs(node._subnodes) do               table.insert(all_results,('='):rep(level) .. v .. ('='):rep(level)) populate_plainlist(node[v], level+1) end end end populate_plainlist(item_groups, tonumber(params.level) or 2) return table.concat(all_results,'\n') end

function r.navbox(pagename, result_fields, params) local content, data_fields, data_fields_map, item_groups pagename, result_fields, params, content, data_fields, data_fields_map, item_groups=parse_data(pagename, result_fields, params) local navbox_mod=require('Module:Navbox') local function populate_navbox(node, primary) local clear_node={} local result if node[1] then for _, v in ipairs(node) do               table.insert(clear_node,'* '..get_cell("@link",v,data_fields_map)..'\n') end result=table.concat(clear_node) end if node._subnodes then result={list1=result} local n=result.list1 and 1 or 0 for _, v in ipairs(node._subnodes) do               n=n+1 result['group'..n]=v local sub_result=populate_navbox(node[v]) if type(sub_result)=='table' then sub_result[1]='child' result['list'..n]=navbox_mod._navbox(sub_result) else result['list'..n]=sub_result end end return result else return result or '' end end local result=populate_navbox(item_groups) result.title='Navbox' result.listclass='hlist' return navbox_mod._navbox(result) end return r