Jump to content

Module:Wikibase

From HxmnWiki
Revision as of 22:22, 4 April 2026 by Admin (talk | contribs) (Wikibase sample data (auto-generated))
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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