Module:Wikibase
Appearance
Documentation for this module may be created at Module:Wikibase/doc
-- Module:Wikibase - fetches data from Wikibase SPARQL endpoint
-- Usage: {{#invoke:Wikibase|countries}} or {{#invoke:Wikibase|cities}}
local p = {}
local ed = mw.ext.externalData
local SPARQL_URL = "https://wd.hxmn.dev/query/sparql?format=json"
-- Helper: run a SPARQL query and return rows
local function sparql(query, fields)
local params = {
url = SPARQL_URL,
format = "json with jsonpath",
["post data"] = "query=" .. query,
data = fields
}
local values, errors = ed.getWebData(params)
if errors and #errors > 0 then
return nil, errors[1]
end
return values
end
-- Helper: format a number with comma separators
local function formatNumber(s)
if not s or s == "" then return "" end
local n = tonumber(s)
if not n then return s end
local formatted = tostring(math.floor(n))
local k
while true do
formatted, k = formatted:gsub("^(-?%d+)(%d%d%d)", "%1,%2")
if k == 0 then break end
end
return formatted
end
-- Helper: extract QID from full URI
local function qid(uri)
if not uri or uri == "" then return "" end
return uri:match("([PQ]%d+)$") or uri
end
function p.countries(frame)
local query = [==[SELECT ?item ?itemLabel ?capitalLabel ?population ?founded ?continentLabel WHERE { ?item <https://wd.hxmn.dev/prop/direct/P1> <https://wd.hxmn.dev/entity/Q1> . ?item <http://www.w3.org/2000/01/rdf-schema#label> ?itemLabel . FILTER(LANG(?itemLabel) = 'en') OPTIONAL { ?item <https://wd.hxmn.dev/prop/direct/P5> ?capital . ?capital <http://www.w3.org/2000/01/rdf-schema#label> ?capitalLabel . FILTER(LANG(?capitalLabel) = 'en') } OPTIONAL { ?item <https://wd.hxmn.dev/prop/direct/P3> ?population . } OPTIONAL { ?item <https://wd.hxmn.dev/prop/direct/P4> ?founded . } OPTIONAL { ?item <https://wd.hxmn.dev/prop/direct/P6> ?continent . ?continent <http://www.w3.org/2000/01/rdf-schema#label> ?continentLabel . FILTER(LANG(?continentLabel) = 'en') } } ORDER BY ?itemLabel]==]
local fields = "item=$.results.bindings[*].item.value,name=$.results.bindings[*].itemLabel.value,capital=$.results.bindings[*].capitalLabel.value,population=$.results.bindings[*].population.value,founded=$.results.bindings[*].founded.value,continent=$.results.bindings[*].continentLabel.value"
local rows, err = sparql(query, fields)
if err then return '<span class="error">SPARQL error: ' .. tostring(err) .. '</span>' end
if not rows then return "No data" end
local out = {}
table.insert(out, '{| class="wikitable sortable"')
table.insert(out, "! Country !! Capital !! Population !! Founded !! Continent !! Wikibase")
for _, row in ipairs(rows) do
if type(row) == "table" and row.name then
local id = qid(row.item or "")
local link = id ~= "" and "[https://wd.hxmn.dev/wiki/Item:" .. id .. " " .. id .. "]" or ""
table.insert(out, "|-")
table.insert(out, "| .. (row.name or ) .. "
.. " || " .. (row.capital or "")
.. " || " .. formatNumber(row.population)
.. " || " .. (row.founded or "")
.. " || " .. (row.continent or "")
.. " || " .. link)
end
end
table.insert(out, "|}}")
return table.concat(out, "\n")
end
function p.cities(frame)
local query = [==[{cities_sparql}]==]
local fields = "item={bp}.item.value,name={bp}.itemLabel.value,country={bp}.countryLabel.value,population={bp}.population.value,founded={bp}.founded.value"
local rows, err = sparql(query, fields)
if err then return '<span class="error">SPARQL error: ' .. tostring(err) .. '</span>' end
if not rows then return "No data" end
local out = {{}}
table.insert(out, '{{| class="wikitable sortable"')
table.insert(out, "! City !! Country !! Population !! Founded !! Wikibase")
for _, row in ipairs(rows) do
if type(row) == "table" and row.name then
local id = qid(row.item or "")
local link = id ~= "" and "[{wb_url}/wiki/Item:" .. id .. " " .. id .. "]" or ""
table.insert(out, "|-")
table.insert(out, "| .. (row.name or ) .. "
.. " || " .. (row.country or "")
.. " || " .. formatNumber(row.population)
.. " || " .. (row.founded or "")
.. " || " .. link)
end
end
table.insert(out, "|}}")
return table.concat(out, "\n")
end
return p