Dokumentatsioon saksa vikis: de:Wikipedia:Lua/Modul/Wikidata.
Mooduli funktsioonide test: Vikipeedia:Mooduli Wikidata test.
-- mostly has the functionality of German Wikipedia module + some additions -- module local variables local wiki = { langcode = mw.language.getContentLanguage().code } -- internationalisation local i18n = { ["errors"] = { ["property-not-found"] = "Omadust ei leitud.", ["entity-not-found"] = "Wikidata andmeüksust ei leitud.", ["unknown-claim-type"] = "Unknown claim type.", ["unknown-entity-type"] = "Unknown entity type.", ["qualifier-not-found"] = "Qualifier not found.", ["site-not-found"] = "Wiki site not found.", }, ["maintenance-pages"] = { ["entity-not-found"] = "entity-not-found", ["entity-not-valid"] = "entity-not-valid", ["property-not-existing"] = "property-not-existing" }, ["datetime"] = { -- $1 is a placeholder for the actual number [0] = "$1 mld aastat",-- precision: billion years [1] = "$100 mln aastat",-- precision: hundred million years [2] = "$10 mln aastat",-- precision: ten million years [3] = "$1 mln aastat",-- precision: million years [4] = "$100.000 aastat",-- precision: hundred thousand years [5] = "$10.000 aastat",-- precision: ten thousand years [6] = "$1. aastatuhat", -- precision: millenium [7] = "$1. sajand",-- precision: century [8] = "$1ndad",-- precision: decade -- the following use the format of #time parser function [9] = "Y",-- precision: year, [10] = "F Y",-- precision: month [11] = "j.m.Y",-- precision: day [12] = 'j.m.Y, "kell" G',-- precision: hour [13] = "j.m.Y G:i",-- precision: minute [14] = "j.m.Y G:i:s",-- precision: second ["beforenow"] = "vor $1",-- how to format negative numbers for precisions 0 to 5 ["afternow"] = "in $1",-- how to format positive numbers for precisions 0 to 5 ["bc"] = '$1 "eKr."',-- how print negative years ["ad"] = "$1"-- how print positive years }, ["monolingualtext"] = '%text', ["wikidataRefCat"] = "[[Category:Viited Wikidatast]]", ["FETCH_WIKIDATA"] = "FETCH_WIKIDATA" } --important properties local propertyId = { ["starttime"] = "P580", ["endtime"] = "P582" } local formatchar = { [10] = {"n","m","M","F","xg"}, --precision: month [11] = {"W","j","d","z","D","l","N","w"}, --precision: day [12] = {"a","A","g","h","G","H"}, --precision: hour [13] = {"i"}, --precision: minute [14] = {"s","U"} --precision: second } local function printError(code) return ' .. (i18n.errors[code] or code) .. '' end -- the "qualifiers" and "snaks" field have a respective "qualifiers-order" and "snaks-order" field -- use these as the second parameter and this function instead of the built-in "pairs" function -- to iterate over all qualifiers and snaks in the intended order. local function orderedpairs(array, order) if not order then return pairs(array) end -- return iterator function local i = 0 return function() i = i + 1 if order[i] then return order[i], array[order[i]] end end end local function printDatavalueCoordinate(data, parameter) -- data fields: latitude [double], longitude [double], altitude [double], precision [double], globe [wikidata URI, usually http://www.wikidata.org/entity/Q2 [earth]] if parameter then if parameter == "globe" then data.globe = mw.ustring.match(data.globe, "Q%d+") end -- extract entity id from the globe URI return data[parameter] else return data.latitude .. "/" .. data.longitude -- combine latitude and longitude, which can be decomposed using the #titleparts wiki function end end local function printDatavalueQuantity(data, parameter) -- data fields: amount [number], unit [string], upperBound [number], lowerBound [number] if not parameter or parameter == "amount" then return tonumber(data.amount) elseif parameter == "unit" then return mw.ustring.match(data.unit, "Q%d+") else return data[parameter] end end local function normalizeDate(date) date = mw.text.trim(date, "+") -- extract year local yearstr = mw.ustring.match(date, "^-?%d+") local year = tonumber(yearstr) -- remove leading zeros of year return year .. mw.ustring.sub(date, #yearstr + 1), year end -- precision: 0 - billion years, 1 - hundred million years, ..., 6 - millenia, 7 - century, 8 - decade, 9 - year, 10 - month, 11 - day, 12 - hour, 13 - minute, 14 - second function formatDate(date, precision, timezone, formatstr) precision = precision or 11 date, year = normalizeDate(date) date = string.gsub(date, "-00%f[%D]", "-01") if year == 0 and precision <= 9 then return "" end -- precision is 10000 years or more if precision <= 5 then local factor = 10 ^ ((5 - precision) + 4) local y2 = math.ceil(math.abs(year) / factor) local relative = mw.ustring.gsub(i18n.datetime[precision], "$1", tostring(y2)) if year < 0 then relative = mw.ustring.gsub(i18n.datetime.beforenow, "$1", relative) else relative = mw.ustring.gsub(i18n.datetime.afternow, "$1", relative) end return relative end -- precision is decades, centuries and millenia local era if precision == 6 then era = mw.ustring.gsub(i18n.datetime[6], "$1", tostring(math.floor((math.abs(year) - 1) / 1000) + 1)) end if precision == 7 then era = mw.ustring.gsub(i18n.datetime[7], "$1", tostring(math.floor((math.abs(year) - 1) / 100) + 1)) end if precision == 8 then era = mw.ustring.gsub(i18n.datetime[8], "$1", tostring(math.floor(math.abs(year) / 10) * 10)) end if era then if year < 0 then era = mw.ustring.gsub(mw.ustring.gsub(i18n.datetime.bc, '"', ""), "$1", era) elseif year > 0 then era = mw.ustring.gsub(mw.ustring.gsub(i18n.datetime.ad, '"', ""), "$1", era) end return era end -- precision is years or less if precision >= 9 then --[[ the following code replaces the UTC suffix with the given negated timezone to convert the global time to the given local time timezone = tonumber(timezone) if timezone and timezone ~= 0 then timezone = -timezone timezone = string.format("%.2d%.2d", timezone / 60, timezone % 60) if timezone[1] ~= '-' then timezone = "+" .. timezone end date = mw.text.trim(date, "Z") .. " " .. timezone end ]]-- if formatstr then for i=(precision+1), 14 do for _, ch in pairs(formatchar[i]) do if formatstr:find(ch) then formatstr = i18n.datetime[precision] end end end else formatstr = i18n.datetime[precision] end if year == 0 then formatstr = mw.ustring.gsub(formatstr, i18n.datetime[9], "") elseif year < 0 then -- Mediawiki formatDate doesn't support negative years date = mw.ustring.sub(date, 2) formatstr = mw.ustring.gsub(formatstr, i18n.datetime[9], mw.ustring.gsub(i18n.datetime.bc, "$1", i18n.datetime[9])) elseif year > 0 and i18n.datetime.ad ~= "$1" then formatstr = mw.ustring.gsub(formatstr, i18n.datetime[9], mw.ustring.gsub(i18n.datetime.ad, "$1", i18n.datetime[9])) end return mw.language.new(wiki.langcode):formatDate(formatstr, date) end end local function printDatavalueTime(data, parameter) -- data fields: time [ISO 8601 time], timezone [int in minutes], before [int], after [int], precision [int], calendarmodel [wikidata URI] -- precision: 0 - billion years, 1 - hundred million years, ..., 6 - millenia, 7 - century, 8 - decade, 9 - year, 10 - month, 11 - day, 12 - hour, 13 - minute, 14 - second -- calendarmodel: e.g. http://www.wikidata.org/entity/Q1985727 for the proleptic Gregorian calendar or http://www.wikidata.org/wiki/Q11184 for the Julian calendar] if parameter then para, formatstr = parameter:match("([^:]+):([^:]+)") if parameter == "calendarmodel" then data.calendarmodel = string.match(data.calendarmodel, "Q%d+") -- extract entity id from the calendar model URI elseif para and para == "time" then return formatDate(data.time, data.precision, data.timezone,formatstr) elseif parameter == "time" then data.time = normalizeDate(data.time) end return data[parameter] else return formatDate(data.time, data.precision, data.timezone) end end local function printDatavalueEntity(data, parameter) -- data fields: entity-type [string], numeric-id [int, Wikidata id] local id if data["entity-type"] == "item" then id = "Q" .. data["numeric-id"] elseif data["entity-type"] == "property" then id = "P" .. data["numeric-id"] else return printError("unknown-entity-type") end if parameter then if parameter == "link" then local linkTarget = mw.wikibase.sitelink(id) local linkName = mw.wikibase.label(id) if linkTarget then local link = linkTarget -- if there is a local Wikipedia article linking to it, use the label or the article title if linkName and (linkName ~= linkTarget) then link = link .. "|" .. linkName end return "[[" .. link .. "]]" else -- if there is no local Wikipedia article output the label or link to the Wikidata object to input a proper label if linkName then return linkName else return "[[:d:" .. id .. "|" .. id .. "]]" end end else return data[parameter] end else return mw.wikibase.label(id) or id end end local function printDatavalueMonolingualText(data, parameter) -- data fields: language [string], text [string] if parameter then return data[parameter] else local result = mw.ustring.gsub(mw.ustring.gsub(i18n.monolingualtext, "%%language", data["language"]), "%%text", data["text"]) return result end end function getSnakValue(snak, parameter) -- snaks have three types: "novalue" for null/nil, "somevalue" for not null/not nil, or "value" for actual data if snak.snaktype == "value" then -- call the respective snak parser if snak.datavalue.type == "string" then return snak.datavalue.value elseif snak.datavalue.type == "globecoordinate" then return printDatavalueCoordinate(snak.datavalue.value, parameter) elseif snak.datavalue.type == "quantity" then return printDatavalueQuantity(snak.datavalue.value, parameter) elseif snak.datavalue.type == "time" then return printDatavalueTime(snak.datavalue.value, parameter) elseif snak.datavalue.type == "wikibase-entityid" then return printDatavalueEntity(snak.datavalue.value, parameter) elseif snak.datavalue.type == "monolingualtext" then return printDatavalueMonolingualText(snak.datavalue.value, parameter) end end return mw.wikibase.renderSnak(snak) end function getQualifierSnak(claim, qualifierId) -- a "snak" is Wikidata terminology for a typed key/value pair -- a claim consists of a main snak holding the main information of this claim, -- as well as a list of attribute snaks and a list of references snaks if qualifierId then -- search the attribute snak with the given qualifier as key if claim.qualifiers then local qualifier = claim.qualifiers[qualifierId] if qualifier then return qualifier[1] end end return nil, printError("qualifier-not-found") else -- otherwise return the main snak return claim.mainsnak end end local function datavalueTimeToDateObject(data) local sign, year, month, day, hour, minute, second = string.match(data.time, "(.)(%d+)%-(%d+)%-(%d+)T(%d+):(%d+):(%d+)Z") local result = { year = tonumber(year), month = tonumber(month), day = tonumber(day), hour = tonumber(hour), min = tonumber(minute), sec = tonumber(second), timezone = data.timezone, julian = data.calendarmodel and string.match(data.calendarmodel, "Q11184$") } if sign == "-" then result.year = -result.year end return result end function julianDay(dateObject) local year = dateObject.year local month = dateObject.month or 0 local day = dateObject.day or 0 if month == 0 then month = 1 end if day == 0 then day = 1 end if month <= 2 then year = year - 1 month = month + 12 end local time = ((((dateObject.sec or 0) / 60 + (dateObject.min or 0) + (dateObject.timezone or 0)) / 60) + (dateObject.hour or 0)) / 24 local b if dateObject.julian then b = 0 else local century = math.floor(year / 100) b = 2 - century + math.floor(century / 4) end return math.floor(365.25 * (year + 4716)) + math.floor(30.6001 * (month + 1)) + day + time + b - 1524.5 end function getQualifierSortValue(claim, qualifierId) local snak = getQualifierSnak(claim, qualifierId) if snak and snak.snaktype == "value" then if snak.datavalue.type == "time" then return julianDay(datavalueTimeToDateObject(snak.datavalue.value)) else return getSnakValue(snak) end end end function getValueOfClaim(claim, qualifierId, parameter) local error local snak snak, error = getQualifierSnak(claim, qualifierId) if snak then return getSnakValue(snak, parameter) else return nil, error end end function getReferences(frame, claim) local result = "" -- traverse through all references for ref in pairs(claim.references or {}) do local refparts = "" local outtext = "" local desc = "" local accessed = "" local url = "" -- traverse through all parts of the current reference for snakkey, snakval in orderedpairs(claim.references[ref].snaks or {}, claim.references[ref]["snaks-order"]) do local currentref = "" local currentrefid = "" if #refparts > 0 then refparts = refparts .. ", " end -- output all values of this reference part, e.g. "German Wiki wikidata" and "English Wiki wikidata" if the referenced claim was imported from both sites for snakidx = 1, #snakval do if snakkey ~= 'P143' and snakkey ~= 'P4656' then if snakidx > 1 then currentref = currentref .. ", " end if getSnakValue(snakval[snakidx]) then currentref = currentref .. getSnakValue(snakval[snakidx]) end if getSnakValue(snakval[snakidx], "numeric-id") then currentrefid = getSnakValue(snakval[snakidx], "numeric-id") end end end if snakkey == 'P248' then if string.len(url) == 0 then url = 'https://www.wikidata.org/wiki/Q' .. currentrefid end currentref = mw.getContentLanguage():ucfirst(currentref) desc = currentref elseif snakkey == 'P1476' then if #desc == 0 then desc = currentref end elseif snakkey == 'P813' then accessed = currentref elseif snakkey == 'P854' then url = currentref end refparts = refparts .. currentref end if #url > 0 then if #desc > 0 then outtext = "[" .. url .. " " .. desc .. "]" else outtext = url end if #accessed > 0 then outtext = outtext .. ", vaadatud " .. accessed .. "." end if outtext then result = result .. mw.getCurrentFrame():extensionTag("ref", outtext) end elseif refparts ~= "" then result = result .. mw.getCurrentFrame():extensionTag("ref", refparts .. '.') end end if result ~= "" then result = result .. i18n.wikidataRefCat end return result end local function hasqualifier(claim, qualifierproperty) local negotiate if string.sub(qualifierproperty, 1, 1) == "!" then negotiate = true else negotiate = false end if not claim.qualifiers and not negotiate then return false end if not claim.qualifiers and negotiate then return true end if qualifierproperty == '' then return true end if not negotiate and not claim.qualifiers[qualifierproperty] then return false end if negotiate and claim.qualifiers[string.sub(qualifierproperty, 2)] then return false end return true end local function qualifierhasvalue(claim, property, value) if not claim.qualifiers then return false end if not claim.qualifiers[property] then return false end for key, snak in pairs(claim.qualifiers[property]) do if snak.snaktype == "value" then if snak.datavalue.type == "wikibase-entityid" then if snak.datavalue.value.id == value then return true end --TODO: elseif other types end end end return false end local function hassource(claim, sourceproperty) if not claim.references then return false end if sourceproperty == '' then return true end if string.sub(sourceproperty,1,1) ~= "!" then for _, source in pairs(claim.references) do if source.snaks[sourceproperty] then return true end end return false else for _, source in pairs(claim.references) do for key in pairs(source.snaks) do if key ~= string.sub(sourceproperty,2) then return true end end end return false end end function atdate(claim, mydate) local refdate if not mydate or mydate == "" then refdate = os.date("!*t") else if string.match(mydate, "^%d+$") then refdate = { year = tonumber(mydate) } else refdate = datavalueTimeToDateObject({ time = mw.language.getContentLanguage():formatDate("+Y-m-d\\TH:i:s\\Z", mydate) }) end end local refjd = julianDay(refdate) local mindate = getQualifierSortValue(claim, propertyId["starttime"]) local maxdate = getQualifierSortValue(claim, propertyId["endtime"]) if mindate and mindate > refjd then return false end if maxdate and maxdate < refjd then return false end return true end local function notdeprecated(claim) return claim.rank ~= "deprecated" end --returns a table of claims excluding claims not passed the filters function filterClaims(frame, claims) local function filter(condition, filterfunction) if not frame.args[condition] then return end local newclaims = {} for i, claim in pairs(claims) do if filterfunction(claim, frame.args[condition]) then table.insert(newclaims, claim) end end claims = newclaims end filter('hasqualifier', hasqualifier) filter('hassource', hassource) filter('atdate', atdate) if not frame.args.includedeprecated then frame.args.notdeprecated = true filter('notdeprecated', notdeprecated) end -- use additional unnamed parameters as qualifier conditions (in pairs) for key in pairs(frame.args) do if type(key) == "number" and key > 2 and key % 2 == 1 then -- key = 3, 5, 7 and so on local newclaims = {} local values = frame.args[key] local negated = string.sub(values, 1, 1) == "!" if negated then values = string.sub(values, 2) end for i, claim in pairs(claims) do local hasvalue = false for val in mw.text.gsplit(values, ",") do if qualifierhasvalue(claim, frame.args[key - 1], val) then hasvalue = true break end end if hasvalue ~= negated then table.insert(newclaims, claim) end end claims = newclaims end end return claims end local p = { } function p.descriptionIn(frame) local langcode = frame.args[1] local id = frame.args[2] -- return description of a Wikidata entity in the given language or the default language of this Wikipedia site local entity = mw.wikibase.getEntity(id) if entity and entity.descriptions then local desc = entity.descriptions[langcode or wiki.langcode] if desc then return desc.value end end end function p.labelIn(frame) local langcode = frame.args[1] or wiki.langcode local id = frame.args[2] or mw.wikibase.getEntityIdForCurrentPage() -- return label of a Wikidata entity in the given language or the default language of this Wikipedia site (no language fallbacks) if id ~= nil then return mw.wikibase.getLabelByLang(id, langcode) end end function p.claim(frame) local property = frame.args[1] or "" local id = frame.args["id"] local qualifierId = frame.args["qualifier"] local parameter = frame.args["parameter"] local language = frame.args["language"] local countValues = frame.args["countValues"] local list = frame.args["list"] local includeempty = frame.args["includeempty"] local listMaxItems = tonumber(frame.args["listMaxItems"]) or 0 local references = frame.args["references"] local sort = frame.args["sort"] local sortEmptiesFirst = frame.args["sortEmptiesFirst"] local sortInItem = frame.args["sortInItem"] local inverse = frame.args["inverse"] local showerrors = frame.args["showerrors"] local default = frame.args["default"] if default then showerrors = nil end -- get wikidata entity if id then if not mw.wikibase.isValidEntityId(id) then if showerrors then return printError("entity-not-valid") else local temp = mw.title.new(i18n["maintenance-pages"]["entity-not-valid"], "Moodul").exists return default end elseif not mw.wikibase.entityExists(id) then if showerrors then return printError("entity-not-found") else local temp = mw.title.new(i18n["maintenance-pages"]["entity-not-found"], "Moodul").exists return default end end end local entity = mw.wikibase.getEntity(id) if not entity then if showerrors then return printError("entity-not-found") else return default end end -- check if property exists local realProp = mw.wikibase.resolvePropertyId(property) if not realProp then local temp = mw.title.new(i18n["maintenance-pages"]["property-not-existing"], "Moodul").exists end -- fetch the first claim of satisfying the given property local claims if entity.claims then claims = entity.claims[realProp] end if not claims or not claims[1] then if countValues then return 0 elseif showerrors then return printError("property-not-found") else return default end end --filter claims claims = filterClaims(frame, claims) if not claims[1] then if countValues then return 0 else return default end end -- get initial sort indices local sortindices = {} for idx in pairs(claims) do sortindices[#sortindices + 1] = idx end local comparator if sort then comparator = function(a, b) --comparator function for sorting statements based on qualifier value -- load qualifier values local QualifierSortValueA = getQualifierSortValue(claims[a], sort) local QualifierSortValueB = getQualifierSortValue(claims[b], sort) -- if either of the two statements does not have this qualifer: ---- if sortEmptiesFirst=true: sort it to the beginning ---- else: always sort it to the end if not QualifierSortValueB then if not QualifierSortValueA then -- if neither of the two statements has this qualifier, arbitrarily but consistently return a < b return a < b elseif sortEmptiesFirst then return false else return true end elseif not QualifierSortValueA then if sortEmptiesFirst then return true else return false end end if type(QualifierSortValueA) ~= type(QualifierSortValueB) and not (tonumber(QualifierSortValueA) and tonumber(QualifierSortValueB)) then if tonumber(QualifierSortValueA) then return true elseif tonumber(QualifierSortValueB) then return false elseif tostring(QualifierSortValueA) and tostring(QualifierSortValueB) then if inverse then return tostring(QualifierSortValueA) > tostring(QualifierSortValueB) else return tostring(QualifierSortValueA) < tostring(QualifierSortValueB) end else return false end -- different types, neither numbers nor strings, no chance to compare => random result to avoid script error elseif tonumber(QualifierSortValueA) and tonumber(QualifierSortValueB) then QualifierSortValueA = tonumber(QualifierSortValueA) QualifierSortValueB = tonumber(QualifierSortValueB) end if inverse then return QualifierSortValueA > QualifierSortValueB else return QualifierSortValueA < QualifierSortValueB end end elseif sortInItem then -- fill table sortkeys local sortkeys = {} local snakSingle local sortkeyValueId local claimContainingValue for idx, claim in pairs(claims) do snakSingle = getQualifierSnak(claim) sortkeyValueId = "Q" .. getSnakValue(snakSingle, "numeric-id") claimContainingValue = mw.wikibase.getEntity(sortkeyValueId).claims[mw.wikibase.resolvePropertyId(sortInItem)] if claimContainingValue then sortkeys[#sortkeys + 1] = getValueOfClaim(claimContainingValue[1]) else sortkeys[#sortkeys + 1] = "" end end comparator = function(a, b) if inverse then return sortkeys[a] > sortkeys [b] else return sortkeys[a] < sortkeys [b] end end else -- sort by claim rank comparator = function(a, b) local rankmap = { deprecated = 2, normal = 1, preferred = 0 } local ranka = rankmap[claims[a].rank or "normal"] .. string.format("%08d", a) local rankb = rankmap[claims[b].rank or "normal"] .. string.format("%08d", b) return ranka < rankb end end table.sort(sortindices, comparator) local result local error if countValues then local count = 0 for _ in pairs(claims) do count = count + 1 end result = count elseif list then list = string.gsub(list, "\\n", "\n") -- if a newline is provided (whose backslash will be escaped) unescape it local value -- iterate over all elements and return their value (if existing) result = {} for idx in pairs(claims) do local claim = claims[sortindices[idx]] value, error = getValueOfClaim(claim, qualifierId, parameter) if not value and value ~= 0 and showerrors then value = error end if not value and value ~= 0 and includeempty then value = "" end if value and references then value = value .. getReferences(frame, claim) end result[#result + 1] = value end if listMaxItems and listMaxItems > 0 then result = table.concat(result, list, 1, math.min(#result, listMaxItems)) else result = table.concat(result, list) end else -- return first element local claim = claims[sortindices[1]] if language == "Q" then result, error = "Q" .. getSnakValue(getQualifierSnak(claim), "numeric-id") elseif language and claim.mainsnak.datatype == "monolingualtext" then -- iterate over claims to find adequate language for idx, claim in pairs(claims) do if claim.mainsnak.datavalue.value.language == language then result, error = getValueOfClaim(claim, qualifierId, parameter) break end end else result, error = getValueOfClaim(claim, qualifierId, parameter) end if references == "only" then result = getReferences(frame, claim) elseif result and references then result = result .. getReferences(frame, claim) end end if result then return result else if showerrors then return error else return default end end end function p.getValue(frame) local param = frame.args[2] if param == "FETCH_WIKIDATA" or param == i18n["FETCH_WIKIDATA"] then return p.claim(frame) else return param end end function p.pageId(frame) local id = frame.args[1] local entity = mw.wikibase.getEntity(id) if not entity then return nil else return entity.id end end function p.labelOf(frame) local id = frame.args[1] -- returns the label of the given entity/property id -- if no id is given, the one from the entity associated with the calling Wikipedia article is used if not id then local entity = mw.wikibase.getEntity() if not entity then return printError("entity-not-found") end id = entity.id end return mw.wikibase.label(id) end function p.sitelinkOf(frame) local id = frame.args[1] -- returns the Wikipedia article name of the given entity -- if no id is given, the one from the entity associated with the calling Wikipedia article is used if not id then local entity = mw.wikibase.getEntity() if not entity then return printError("entity-not-found") end id = entity.id end return mw.wikibase.sitelink(id) end function p.badges(frame) local site = frame.args[1] local id = frame.args[2] if not site then return printError("site-not-found") end local entity = mw.wikibase.getEntity(id) if not entity then return printError("entity-not-found") end local badges = entity.sitelinks[site].badges if badges then local result for idx = 1, #badges do if result then result = result .. "/" .. badges[idx] else result = badges[idx] end end return result end end function p.sitelinkCount(frame) local filter = "^.*" .. (frame.args[1] or "") .. "$" local id = frame.args[2] local entity = mw.wikibase.getEntity(id) local count = 0 if entity and entity.sitelinks then for project, _ in pairs(entity.sitelinks) do if string.find(project, filter) then count = count + 1 end end end return count end -- call this in cases of script errors within a function instead of {{#invoke:Wikidata||...}} call {{#invoke:Wikidata|debug||...}} function p.debug(frame) local func = frame.args[1] if func then -- create new parameter set, where the first parameter with the function name is removed local newargs = {} for key, val in pairs(frame.args) do if type(key) == "number" then if key > 1 then newargs[key - 1] = val end else newargs[key] = val end end frame.args = newargs local status, result = pcall(p[func], frame) if status then return result else return ' .. result .. '' end else return '' end end function p.printEntity(frame) local id = frame.args[1] local entity = mw.wikibase.getEntity(id) if entity then return ""
.. mw.text.jsonEncode(entity, mw.text.JSON_PRETTY) .. "
" end end --[[ This is used to return an image legend from Wikidata image is property P18 image legend is property P2096 Call as {{#invoke:Wikidata |getImageLegend |