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"
local WB_URL = "https://wd.hxmn.dev"
-- Run a SPARQL query via External Data 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
-- Format 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
-- Extract QID from full entity URI
local function qid(uri)
if not uri or uri == "" then return "" end
return uri:match("([PQ]%d+)$") or uri
end
-- Build a wikitext link to a Wikibase item
local function wblink(uri)
local id = qid(uri)
if id == "" then return "" end
return "[" .. WB_URL .. "/wiki/Item:" .. id .. " " .. id .. "]"
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 returned from Wikibase." 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
table.insert(out, "|-")
table.insert(out,
"| '''" .. (row.name or "") .. "'''"
.. " || " .. (row.capital or "")
.. " || " .. formatNumber(row.population)
.. " || " .. (row.founded or "")
.. " || " .. (row.continent or "")
.. " || " .. wblink(row.item))
end
end
table.insert(out, "|}")
return table.concat(out, "\n")
end
function p.cities(frame)
local query = [==[SELECT ?item ?itemLabel ?countryLabel ?population ?founded WHERE { ?item <https://wd.hxmn.dev/prop/direct/P1> <https://wd.hxmn.dev/entity/Q2> . ?item <http://www.w3.org/2000/01/rdf-schema#label> ?itemLabel . FILTER(LANG(?itemLabel) = 'en') OPTIONAL { ?item <https://wd.hxmn.dev/prop/direct/P2> ?country . ?country <http://www.w3.org/2000/01/rdf-schema#label> ?countryLabel . FILTER(LANG(?countryLabel) = 'en') } OPTIONAL { ?item <https://wd.hxmn.dev/prop/direct/P3> ?population . } OPTIONAL { ?item <https://wd.hxmn.dev/prop/direct/P4> ?founded . } } ORDER BY ?itemLabel]==]
local fields = "item=$.results.bindings[*].item.value,name=$.results.bindings[*].itemLabel.value,country=$.results.bindings[*].countryLabel.value,population=$.results.bindings[*].population.value,founded=$.results.bindings[*].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 returned from Wikibase." 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
table.insert(out, "|-")
table.insert(out,
"| '''" .. (row.name or "") .. "'''"
.. " || " .. (row.country or "")
.. " || " .. formatNumber(row.population)
.. " || " .. (row.founded or "")
.. " || " .. wblink(row.item))
end
end
table.insert(out, "|}")
return table.concat(out, "\n")
end
return p