Open main menu

Changes

Module:WikidataIB

9,945 bytes added, 18:09, 10 July 2023
Per edit request
-- Version: 2023-07-10
-- Module to implement use of a blacklist and whitelist for infobox fields
-- Can take a named parameter |qid which is the Wikidata ID for the article
-- whitelist is passed in named parameter |fetchwikidata (or |fwd)
require("strict")
local p = {}
local cdate -- initialise as nil and only load _complex_date function if needed
-- [[Module:Complex date]] is loaded lazily and has the following dependencies:-- Module:I18n/complex date, Calendar-- Module:ISOdate, -- Module:DateI18n (alternative for -- Module:Date),I18n/complex date-- Module:Formatnum, Ordinal-- Module:I18n/date, ordinal-- Module:Yesno, -- Module:Linguistic, Formatnum-- Module:CalendarLinguistic--
-- The following, taken from https://www.mediawiki.org/wiki/Wikibase/DataModel#Dates_and_times,
-- is needed to use Module:Complex date which seemingly requires date precision as a string.
-------------------------------------------------------------------------------
-- makeOrdinal needs to be internationalised along with the above:
-- takes cardinal numer number as a numeric and returns the ordinal as a string
-- we need three exceptions in English for 1st, 2nd, 3rd, 21st, .. 31st, etc.
-------------------------------------------------------------------------------
langobj = mw.language.new( langcode )
else
langcode = mw.getCurrentFrame():preprocesscallParserFunction( 'int', {{int:'lang'}}' )
if mw.language.isKnownLanguageTag(langcode) then
langobj = mw.language.new( langcode )
-- dateFormat is the handler for properties that are of type "time"
-- It takes timestamp, precision (6 to 11 per mediawiki), dateformat (y/dmy/mdy), BC format (BC/BCE),
-- a plaindate switch (yes/no/adj) to en/disable "sourcing cirumstancescircumstances"/use adjectival form,
-- any qualifiers for the property, the language, and any adjective to use like 'before'.
-- It passes the date through the "complex date" function
-- output formatting according to preferences (y/dmy/mdy/ymd)
df = (df or ""):lower()
-- if ymd is required, just return the part of the timestamp in YYYY-MM-DD form -- but apply Year zero#Astronomers fix: 1 BC = 0000; 2 BC = -0001; etc. if df == "ymd" then if timestamp:sub(1,1) == "+" then return timestamp:sub(2,11) else local yr = tonumber(timestamp:sub(2,5)) - 1 yr = ("000" .. yr):sub(-4) if yr ~= "0000" then yr = "-" .. yr end return yr .. timestamp:sub(6,11) end end
-- A year can be stored like this: "+1872-00-00T00:00:00Z",
-- which is processed here as if it were the day before "+1872-01-01T00:00:00Z",
-- no point in saying that dates before 1582 are Julian - they are by default
-- doesn't make sense for dates less precise than year
-- we can supress suppress it by setting |plaindate, e.g. for use in constructing categories.
local calendarmodel = ""
if tonumber(year) > 1582
local sitelink
if wiki == "" then
sitelink = mw.wikibase.sitelinkgetSitelink(qid)
else
sitelink = mw.wikibase.sitelinkgetSitelink(qid, wiki)
end
return sitelink
label = mw.wikibase.getLabelByLang(id, lang)
else
label = mw.wikibase.labelgetLabel(id)
end
if label then
-- shortname is boolean switch to use P1813 (short name) instead of label if true.
-- lang is the current language code.
-- uselbl is boolean switch to force display of the label instead of the sitelink (default: false)
-- linkredir is boolean switch to allow linking to a redirect (default: false)
-- formatvalue is boolean switch to allow formatting as italics or quoted (default: false)
-------------------------------------------------------------------------------
-- Dependencies: labelOrId(); donotlink[]
-------------------------------------------------------------------------------
local linkedItem = function(id, lprefix, lpostfix, prefix, postfix, dtxt, shortname, langargs) local lprefix = (args.lp or args.lprefix or args.linkprefix or ""):gsub('" ', '') -- toughen against nil values passed local lpostfix = (args.lpostfix or ""):gsub('"', '') local prefix = (args.prefix or ""):gsub('"', '') local postfix = (args.postfix or ""):gsub('"', '') local dtxt = args.dtxt local shortname = args.shortname or args.sn local lang = args.lang or "en" -- fallback to default if missing local uselbl = args.uselabel or args.uselbl uselbl = parseParam(uselbl, false) local linkredir = args.linkredir linkredir = parseParam(linkredir, false) local formatvalue = args.formatvalue or args.fv formatvalue = parseParam(formatvalue, false)
-- see if item might need italics or quotes
local fmt = ""
if next(formats) and formatvalue then for k, v in ipairs( mw.wikibase.getBestStatements(id, "P31") ) do if v.mainsnak.datavalue and formats[v.mainsnak.datavalue.value.id] then fmt = formats[v.mainsnak.datavalue.value.id] break -- pick the first match end
end
end
local disp
local sitelink = mw.wikibase.sitelinkgetSitelink(id)
local label, islabel
if dtxt then
if sitelink then
if not (dtxt or shortname) then
-- if sitelink and label are the same except for case, no need to process further if sitelink:lower() ~= label:lower() then -- strip any namespace or dab from the sitelink local pos = sitelink:find(":") or 0 local slink = sitelink if pos > 0 then local prefix pfx = sitelink:sub(1,pos-1) if mw.site.namespaces[prefixpfx] then -- that prefix is a valid namespace, so remove it slink = sitelink:sub(pos+1) end end -- remove stuff after commas or inside parentheses - ie. dabs slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "") -- if uselbl is false, use sitelink instead of label if not uselbl then -- use slink as display, preserving label case - find("^%u") is true for 1st char uppercase if label:find("^%u") then label = slink:gsub("^(%l)", string.upper) else label = slink:gsub("^(%u)", string.lower) end
end
end
-- remove stuff after commas or inside parentheses - ie. dabs
slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "")
-- use that as label, preserving label case - find("^%u") is true for 1st char uppercase
if label:find("^%u") then
label = slink:gsub("^(%l)", string.upper)
else
label = slink:gsub("^(%u)", string.lower)
end
end
end
elseif islabel then
-- no sitelink, label exists, so check if a redirect with that title exists, if linkredir is true -- display plain label by default disp = prefix .. fmt .. label .. fmt .. postfix if linkredir then local artitle = mw.title.new(label, 0)-- only nil if label has invalid chars if not donotlink[label] and artitle and artitle.redirectTarget and not donotlink[label] then -- there's a redirect with the same title as the label, so let's link to that disp = "[[".. lprefix .. label .. lpostfix .. "|" .. prefix .. fmt .. label .. fmt .. postfix .. "]]" else -- no sitelink, label exists, not redirect (or donotlink) so output plain label disp = prefix .. fmt .. label .. fmt .. postfixend
end -- test if article title exists as redirect on current Wiki
else
-- no sitelink and no label, so return whatever was returned from labelOrId for now
-- add tracking category [[Category:Articles with missing Wikidata information]]
-- for enwiki, just return the tracking category if mw.wikibase.getGlobalSiteId() == "enwiki" then disp = i18n.missinginfocat else disp = prefix .. label .. postfix .. i18n.missinginfocat end
end
else
-------------------------------------------------------------------------------
-- sourced takes a table representing a statement that may or may not have references
-- it counts how many references are looks for a reference sourced to something not containing the word "wikipedia"-- it returns a boolean = true if there are any it finds a sourced referencesreference.
-------------------------------------------------------------------------------
-- Dependencies: none
for kr, vr in pairs(claim.references) do
local ref = mw.wikibase.renderSnaks(vr.snaks)
if not ref:find("WikipediaWiki") then
return true
end
input_parm = mw.text.trim(input_parm or "")
if input_parm == "" then input_parm = nil end
 
-- return nil if Wikidata is not available
if not mw.wikibase then return false, input_parm end
local args = frame.args
-- The blacklist is passed in named parameter |suppressfields
local blacklist = args.suppressfields or args.spfor ""
-- The whitelist is passed in named parameter |fetchwikidata
local whitelist = args.fetchwikidata or args.fwdor "" if not whitelist or whitelist == "" then whitelist = "NONE" end
-- The name of the field that this function is called from is passed in named parameter |name
local fieldname = args.name or ""
if blacklist ~= "" then
-- The name is compulsory when blacklist is used, so return nil if it is not supplied
if not fieldname or fieldname == "" then return false, nil end
-- If this field is on the blacklist, then return nil
if blacklist:find(fieldname) then return false, nil end
-- createicon assembles the "Edit at Wikidata" pen icon.
-- It returns a wikitext string inside a span class="penicon"
-- if entityID is nil or empty, the ID associated with current page is used
-- langcode and propertyID may be nil or empty
-------------------------------------------------------------------------------
-- Dependencies: i18n[];
-------------------------------------------------------------------------------
local createicon = function(langcode, entityID, propertyID)
langcode = langcode or "" if not entityID or entityID == "" then entityID= mw.wikibase.getEntityIdForCurrentPage() end propertyID = propertyID or "" local icon = "&nbsp;<span class='peniconautoconfirmed-show'>[["
-- "&nbsp;<span data-bridge-edit-flow='overwrite' class='penicon'>[[" -> enable Wikidata Bridge
.. i18n["filespace"]
.. i18n["editonwikidata"]
.. "|link=https://www.wikidata.org/wiki/" .. entityID
if langcode ~= "" then icon = icon .. "?uselang=" .. langcodeend if propertyID ~= "" then icon = icon .. "#" .. propertyID end
icon = icon .. "|" .. i18n["editonwikidata"] .. "]]</span>"
return icon
-- assembleoutput takes the sequence table containing the property values
-- and formats it according to switches given. It returns a string or nil.
-- It needs uses the entityID (and optionally propertyID ) to create a link in the pen icon.
-------------------------------------------------------------------------------
-- Dependencies: parseParam();
-- Zero or not a number result in no collapsing (default becomes 0).
local collapse = tonumber(args.collapse) or 0
 
-- replacetext (rt) is a string that is returned instead of any non-empty Wikidata value
-- this is useful for tracking and debugging
local replacetext = mw.text.trim(args.rt or args.replacetext or "")
-- if there's anything to return, then return a list
if #out > 0 then
if sorted then table.sort(out) end
-- if there's something to display and a pen icon is wanted , add it the end of the last value local hasdisplay = false for i, v in ipairs(out) do if v ~= i18n.missinginfocat then hasdisplay = true break end end if not noic and hasdisplay then
out[#out] = out[#out] .. createicon(args.langobj.code, entityID, propertyID)
end
strout = nil -- no items had valid reference
end
if replacetext ~= "" and strout then strout = replacetext end
return strout
end
local qnumber = dv.id
if linked then
val = linkedItem(qnumber, lpre, lpost, pre, post, dtxt, shortname, args.lang)
else -- no link wanted so check for display-text, otherwise test for lang code
local label, islabel
if uabbr then
-- see if there's a unit symbol (P5061)
local unitsymbols = mw.wikibase.getAllStatementsgetBestStatements(unitqid, "P5061") -- construct fallback table, add local lang and multiple languages
local fbtbl = mw.language.getFallbacksFor( args.lang )
table.insert( fbtbl, 1, args.lang )
table.insert( fbtbl, 1, "mul" )
local found = false
for idx1, us in ipairs(unitsymbols) do
args.pd = pd
-- allow qualifiers to have a different date format; default to yearunless qualsonly is set args.qdf = args.qdf or args.qualifierdateformat or args.df or (not qualsonly and "y")  local lang = args.lang or findLang().code  -- qualID is a string list of wanted qualifiers or "ALL" qualID = qualID or "" -- capitalise list of wanted qualifiers and substitute "DATES" qualID = qualID:upper():gsub("DATES", "P580, P582") local allflag = (qualID == "ALL") -- create table of wanted qualifiers as key local qwanted = {} -- create sequence of wanted qualifiers local qorder = {} for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate local qtrim = mw.text.trim(q) if qtrim ~= "" then qwanted[mw.text.trim(q)] = true qorder[#qorder+1] = qtrim end end -- qsep is the output separator for rendering qualifier list local qsep = (args.qsep or ""):gsub('"', '') -- qargs are the arguments to supply to assembleoutput() local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix or args.qlp, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args.qlist, ["sep"] = qsep, ["langobj"] = args.langobj, ["lang"] = args.langobj.code, ["df"] = args.qdf, ["sn"] = parseParam(args.qsn or args.qshortname, false), }
local lang = args.lang or findlang().code
-- all proper values of a Wikidata property will be the same type as the first
-- qualifiers don't have a mainsnak, properties do
local datatype = objproperty[1].datatype or objproperty[1].mainsnak.datatype
local datatype = objproperty[1].datatype or objproperty[1].mainsnak.datatype -- out[] holds the a list of returned values for this property
-- mlt[] holds the language code if the datatype is monolingual text
local out = {}
local mlt = {}
 
for k, v in ipairs(objproperty) do
local hasvalue = true
-- See if qualifiers are to be returned:
local snak = v.mainsnak or v
if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then local qsep = (args.qsep or ""):gsub('"', '') local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix or args.qlp, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args. -- collect all wanted qualifier values returned in qlist, ["sep"] = qsep, ["langobj"] = args.langobj, ["lang"] = args.langobj.code, ["df"] = args.qdf }indexed by propertyID
local qlist = {}
local t1timestart, t2 timeend = "", "" -- see if we want all qualifiers if qualID == "ALL" then if v["loop through qualifiers-order"] then -- the values in the order table are the keys for the qualifiers table: for k1, v1 in ipairspairs(v[".qualifiers-order"]) do if v1 allflag or qwanted[k1] then if k1 == "P1326" then local ts = v.qualifiers[v1][1].datavalue.value.time local dp = v.qualifiers[v1][1].datavalue.value.precision qlist[#qlist + 1k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") elseif v1 k1 == "P1319" then local ts = v.qualifiers[v1][1].datavalue.value.time local dp = v.qualifiers[v1][1].datavalue.value.precision qlist[#qlist + 1k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") else elseif k1 == "P580" then local q timestart = assembleoutput(propertyvalueandquals(v.qualifiers[v1], qargs), qargs) [1] or "" -- we already deal with circa via 'sourcing circumstances'treat only one start time as valid -- either linked or unlinked *** internationalise later *** if q ~ elseif k1 == "circaP582" and not (type(q) then timeend == "string" and q:findpropertyvalueandquals("circa]]"v1, qargs)) then qlist[#qlist + 1] = q or "" -- treat only one endtime as valid end end else -- are there cases where qualifiers-order doesn't exist? local ql q = assembleoutput(propertyvalueandquals(v.qualifiersv1, qargs) for k1, v1 in ipairs(qlqargs) do -- we already deal with circa via 'sourcing circumstances'if the datatype was time -- circa may be either linked or unlinked *** internationalise later *** if v1 datatype ~= "time" or q ~= "circa" and not (type(v1q) == "string" and v1q:find("circa]]")) then qlist[#qlist + 1k1] = v1q end end end -- see if we want date/range elseif qualID == "DATES" then qargs.maxvals = 1 for k1, v1 in pairs(v.qualifiers) do if k1 == "P580" then -- P580 is "start time" t1 = propertyvalueandquals(v1, qargs)[1] or "" elseif k1 == "P582" then -- P582 is "end time" t2 = propertyvalueandquals(v1, qargs)[1] or "" end end -- otherwise process qualID as a list of qualifiers else for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate q = mw.text.trim(q):upper() -- remove whitespace and capitalise if q == "P1326" then -- latest date, so supply 'before' as well. Assume one date value. for k1, v1 in pairs(v.qualifiers) do if k1 == "P1326" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[#qlist + 1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") end end else for k1, v1 in pairs(v.qualifiers) do if k1 == q then local ql = propertyvalueandquals(v1, qargs) test for k2, v2 in ipairs(ql) dowanted qlist[#qlist + 1] = v2 end end end end end -- of loop through list of qualifiers in qualID end -- of testing for what qualID isset date separator local t = t1 timestart .. t2timeend -- *** internationalise date separators later *** local dsep = "&ndash;"
if t:find("%s") or t:find("&nbsp;") then dsep = " &ndash; " end
-- set the order for the list of qualifiers returned; start time and end time go last if next(qlist) then local qlistout = {} if allflag then for k2, v2 in pairs(qlist) do qlistout[#qlistout+1] = v2 end else for i2, v2 in ipairs(qorder) do qlistout[#qlistout+1] = qlist > 0 [v2] end end if t ~= "" then qlistout[#qlistout+1] = timestart .. dsep .. timeend end local qstr = assembleoutput(qlistqlistout, qargs)
if qualsonly then
out[#out+1] = qstr
out[#out] = out[#out] .. " (" .. qstr .. ")"
end
elseif t > ~= "" then
if qualsonly then
if timestart == "" then out[#out+1] = timeend elseif timeend == "" then out[#out+1] = timestart else out[#out+1] = t1 timestart .. dsep .. t2timeend end
else
out[#out] = out[#out] .. " (" .. t1 timestart .. dsep .. t2 timeend .. ")"
end
end
local uabbr = parseParam(args.unitabbr or args.uabbr, false)
local filter = (args.unit or ""):upper()
local maxvals = tonumber(args.maxvals) or 0
if filter == "" then filter = nil end
return nil
end -- of check for string
if maxvals > 0 and #out >= maxvals then break end
end -- of loop through values of propertyID
return assembleoutput(out, frame.args, qid, propertyID)
end
for i2, v2 in ipairs(proptbl) do
local parttbl = v2.qualifiers and v2.qualifiers.P518
if parttbl then
-- this higher location has qualifier 'applies to part' (P518)
end
-- check if it's an instance of (P31) a country (Q6256) or sovereign state (Q3624078) -- and terminate the chain if it is
local inst = mw.wikibase.getAllStatements(qid, "P31")
if #inst > 0 then
for k, v in ipairs(inst) do
local instid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id
-- stop if it's a country (or a country within the United Kingdom if skip is true)
if instid == "Q6256" or instid == "Q3624078" or (skip and instid == "Q3336843") then
prop = nil -- this will ensure this is treated as top-level location
break
if prop and prop.mainsnak.datavalue then
if not skip or count == 0 then
local args = { lprefix = ":" } out[#out+1] = linkedItem(qid, ":", "", "", ""args) -- get a linked value if we can
end
qid, prevqid = prop.mainsnak.datavalue.value.id, qid
until finished or count >= 10 -- limit to 10 levels to avoid infinite loops
-- remove the first location if not quiredrequired
if not first then table.remove(out, 1) end
args.reqranks = setRanks(args.rank)
 
-- replacetext (rt) is a string that is returned instead of any non-empty Wikidata value
-- this is useful for tracking and debugging, so we set fetchwikidata=ALL to fill the whitelist
local replacetext = mw.text.trim(args.rt or args.replacetext or "")
if replacetext ~= "" then
args.fetchwikidata = "ALL"
end
local f = {}
-- getCoords is used to get coordinates for display in an infobox
-- whitelist and blacklist are implemented
-- optional 'display' parameter is allowed, defaults to nil - was "inline, title"
-------------------------------------------------------------------------------
-- Dependencies: setRanks(); parseInput(); decimalPrecision();
-- if there is a 'display' parameter supplied, use it
-- otherwise default to "inline, title"nothing
local disp = frame.args.display or ""
if disp == "" then
disp = nil -- default to not supplying display parameter, was "inline, title"
end
-- whose value is to be returned is passed in named parameter |qual=
local qualifierID = frame.args.qual
 
-- A filter can be set like this: filter=P642==Q22674854
local filter, fprop, fval
local ftable = mw.text.split(frame.args.filter or "", "==")
if ftable[2] then
fprop = mw.text.trim(ftable[1])
fval = mw.text.trim(ftable[2])
filter = true
end
-- onlysourced is a boolean passed to return qualifiers
for k1, v1 in pairs(props) do
if v1.mainsnak.snaktype == "value" and v1.mainsnak.datavalue.type == "wikibase-entityid" then
-- It's a wiki-linked value, so check if it's the target (in propvalue) -- and if it has qualifiers
if v1.mainsnak.datavalue.value.id == propvalue and v1.qualifiers then
if onlysrc == false or sourced(v1) then
-- if we've got this far, we have a (sourced) claim with qualifiers
-- which matches the target, so apply the filter and find the value(s) of the qualifier we want if not filter or (v1.qualifiers[fprop] and v1.qualifiers[fprop][1].datavalue.value.id == fval) then local quals = v1.qualifiers[qualifierID] if quals then -- can't reference qualifer, so set onlysourced = "no" (args are strings, not boolean) local qargs = frame.args qargs.onlysourced = "no" local vals = propertyvalueandquals(quals, qargs, qid) for k, v in ipairs(vals) do out[#out + 1] = v end
end
end
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput;
-------------------------------------------------------------------------------
p.getPropertyIDs _getPropertyIDs = function(frameargs) local args = frame.args
args.reqranks = setRanks(args.rank)
args.langobj = findLang(args.lang)
local f = {}
f.args = args
local pid = mw.text.trim(args[1] or ""):upper()
-- get the qid and table of claims for the property, or nothing and the local value passed
local maxvals = tonumber(args.maxvals) or 0
local out = {}
for i, v in ipairs(props) do
local snak = v.mainsnak
return assembleoutput(out, args, qid, pid)
end
 
p.getPropertyIDs = function(frame)
local args = frame.args
return p._getPropertyIDs(args)
end
-------------------------------------------------------------------------------
-- getPropOfProp getQualifierIDs takes two propertyIDs: prop1 and prop2 (as well as most of the usual parameters).-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented.-- If It takes a property-id as the valuefirst unnamed parameter, and an optional parameter qlist-- which is a list of qualifier property-ids to search for (sdefault is "ALL") of prop1 are of type "wikibase--item" then it It returns the valueEntity-IDs (sQids) of prop2-- the values of each of those wikibasea property if it is a Wikibase-itemsEntity.-- The usual whitelisting, blacklisting, onlysourced, etcOtherwise it returns nothing. are implemented
-------------------------------------------------------------------------------
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput;
-------------------------------------------------------------------------------
p.getPropOfProp getQualifierIDs = function(frame) frame.args.reqranks = setRanks(frame.args.rank) frame.args.langobj = findLang(frame.args.lang) frame.args.lang = frame.args.langobj.code
local args = frame.args
local pid1 args.reqranks = setRanks(args.rank) args.prop1 or langobj = findLang(args.pid1 or ""lang) local pid2 args.lang = args.prop2 or langobj.code -- change default for noicon to true args.noicon = tostring(parseParam(args.pid2 noicon or "", true)) local localval f = {} f.args = args local pid = mw.text.trim(args[1] or ""):upper(if pid1 == "" -- get the qid and table of claims for the property, or pid2 == "" then return nil endnothing and the local value passed local qid1qid, statements1 props = parseInput(framef, localvalargs[2], pid1pid) if not qid1 qid then return localval props end if not props[1] then return nil end -- get the other parameters
local onlysrc = parseParam(args.onlysourced or args.osd, true)
local maxvals = tonumber(args.maxvals) or 0
local qualID qlist = mw.text.trim(args.qual qlist or ""):upper() if qualID qlist == "" then qualID qlist = nil "ALL" end qlist = qlist:gsub("[%p%s]+", " ") .. " " 
local out = {}
for ki, v in ipairs(statements1props) do if not onlysrc or sourced(v) then local snak = v.mainsnak if snak( v.rank and args.reqranks[v.datatype == "wikibase-item" rank:sub(1, 1)] ) and ( snak.snaktype == "value" then) local qid2 = snak.datavalue.value.id and ( sourced(v) or not onlysrc ) local statements2 = {} then if args.reqranksv.b qualifiers then statements2 = mw.wikibase for k1, v1 in pairs(v.getBestStatements(qid2, pid2qualifiers) elsedo statements2 if qlist == mw"ALL " or qlist:match(k1 .wikibase.getAllStatements" ") then for i2, v2 in ipairs(qid2, pid2v1)do end if statements2[1] v2.datatype == "wikibase-item" and v2.snaktype == "value" then local out2 = propertyvalueandquals(statements2, args, qualID) out[#out+1] = assembleoutput(out2, args, qid2, pid2)v2.datavalue.value.id end -- of test that id exists end -- of loop through qualifier values end -- of test for kq in qlist end-- of loop through qualifiers end -- of test for valid property1 valuequalifiers end -- of test for rank value, sourced, and value exists
if maxvals > 0 and #out >= maxvals then break end
end -- of loop through property values of property1  return assembleoutput(out, args, qid1qid, pid1pid)
end
-------------------------------------------------------------------------------
-- getAwardCat getPropOfProp takes most of two propertyIDs: prop1 and prop2 (as well as the usual parameters. )-- If the item has values of P166 value(award receiveds),-- then it examines each of those awards for P2517 (category for recipients prop1 are of this award).type "wikibase-- If it exists, item" then it returns the corresponding category,-- with the item'value(s P734 (family name) as sort key, or no sort key if there is no family name.of prop2-- The sort key may be overridden by the parameter |sortkey (alias |sk)of each of those wikibase-items.
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented
-------------------------------------------------------------------------------
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput;
-------------------------------------------------------------------------------
p.getAwardCat _getPropOfProp = function(frameargs) frame.args.reqranks -- parameter sets for commonly used groups of parameters local paraset = setRankstonumber(frameargs.ps or args.rankparameterset or 0) frameif paraset == 1 then -- a common setting args.rank = "best" args.langobj fetchwikidata = findLang(frame"ALL" args.onlysourced = "no" args.lang)noicon = "true" frameelseif paraset == 2 then -- equivalent to raw args.rank = "best" args.lang fetchwikidata = frame"ALL" args.onlysourced = "no" args.langobjnoicon = "true" args.linked = "no" args.codepd = "true" elseif paraset == 3 then -- third set goes here end  local args .reqranks = framesetRanks(args.rank) args.langobj = findLang(args.lang) args.sep lang = " "args.langobj.code local pid1 = args.prop1 or args.pid1 or "P166" local pid2 = args.prop2 or args.pid2 or "P2517"
if pid1 == "" or pid2 == "" then return nil end
-- locally supplied value: local localval f = mw{} f.text.trim(args[1] or "")= args local qid1, statements1 = parseInput(framef, localvalargs[1], pid1) if not qid1 then return localval end -- linkprefix (strip quotes) local lp = (parseInput nulls empty args.linkprefix or args.lp or ""):gsub('"', '') -- sort key (strip quotes, hyphens [1] and periods): local sk = (args.sortkey or returns args.sk or ""):gsub('["-.1]', '') -- family name: local famname = ""if nothing on Wikidata if sk == "" not qid1 thenreturn statements1 end local p734 = mw.wikibase.getBestStatements(qid1, "P734")[1] local p734id = p734 and p734.mainsnak.snaktype == "value" and p734.mainsnak.datavalue.value.id or "" famname = mw.wikibase.sitelink(p734id) or "" -- strip namespace and disambigation local pos = famname:find(":") or 0 famname = famname:sub(pos+1):gsub("%s%(.+%)$", "") if famname == "" then local lbl = mw.wikibase.label(p734id) famname = lbl otherwise it returns the qid and mw.text.nowiki(lbl) or "" end enda table for the statement local onlysrc = parseParam(args.onlysourced or args.osd, true) local maxvals = tonumber(args.maxvals) or 0 local qualID = mw.text.trim(args.qual or ""):upper()
if qualID == "" then qualID = nil end
local out = {}
statements2 = mw.wikibase.getAllStatements(qid2, pid2)
end
if statements2[1] and statements2[1].mainsnak.snaktype == "value" then local qid3 out2 = propertyvalueandquals(statements2[1].mainsnak.datavalue.value.id local sitelink = mw.wikibase.sitelink(qid3) -- if there's no local sitelink, create the sitelink from English label if not sitelink then local lbl = mw.wikibase.getLabelByLang(qid3, "en") if lbl then if lbl:sub(1args,9qualID) == "Category:" then sitelink = mw.text.nowiki(lbl) else sitelink = "Category:" .. mw.text.nowiki(lbl) end end end if sitelink then if sk ~= "" then out[#out+1] = "[[" .. lp .. sitelink .. "|" .. sk .. "]]" elseif famname ~= "" then out[#out+1] = "[[" .. lp .. sitelink .. "|" .. famname .. "]]" else out[#out+1] = "[[" .. lp .. sitelink .. "]]" end -- of check for sort keys end -- of test for sitelinkassembleoutput(out2, args, qid2, pid2) end -- of test for category end -- of test for wikibase item has a valid property1 value end -- of test for sourced if maxvals > 0 and #out >= maxvals then break end end -- of loop through values of property1 return assembleoutput(out, args, qid1, pid1)end p.getPropOfProp = function(frame) local args= frame.args if not args.prop1 and not args.pid1 then args = frame:getParent().args if not args.prop1 and not args.pid1 then return i18n.errors["No property supplied"] end end  return p._getPropOfProp(args)
end
-------------------------------------------------------------------------------
-- getIntersectCat getAwardCat takes most of the usual parameters. If the item has values of P166 (award received),-- then it examines each of those awards for P2517 (category for recipients of this award).-- If it exists, it returns the corresponding category,-- with the item's P734 (family name) as sort key, or no sort key if there is no family name.-- The sort key may be overridden by the parameter |sortkey (alias |sk).
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented
-- It takes two properties, |prop1 and |prop2 (e.g. occupation and country of citizenship)
-- Each property's value is a wiki-base entity
-- For each value of the first parameter (ranks implemented) it fetches the value's main category
-- and then each value of the second parameter (possibly substituting a simpler description)
-- then it returns all of the categories representing the intersection of those properties,
-- (e.g. Category:Actors from Canada). A joining term may be supplied (e.g. |join=from).
-- The item's P734 (family name) is the sort key, or no sort key if there is no family name.
-- The sort key may be overridden by the parameter |sortkey (alias |sk).
-------------------------------------------------------------------------------
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput;
-------------------------------------------------------------------------------
p.getIntersectCat getAwardCat = function(frame)
frame.args.reqranks = setRanks(frame.args.rank)
frame.args.langobj = findLang(frame.args.lang)
local args = frame.args
args.sep = " "
args.linked = "no" local pid1 = args.prop1 or "P106P166" local pid2 = args.prop2 or "P27P2517"
if pid1 == "" or pid2 == "" then return nil end
-- locally supplied value: local qid, statements1 localval = parseInputmw.text.trim(frame, args[1] or "", pid1) if not qid then return nil end local qidqid1, statements2 statements1 = parseInput(frame, ""localval, pid2pid1) if not qid qid1 then return nil localval end -- topics like countries may have different names in categories from their label in Wikidata local subs_exists, subs = pcall(mw.loadData, "Module:WikidataIB/subs") local join = args.join or "" local onlysrc = parseParam(args.onlysourced or args.osd, true) local maxvals = tonumber(args.maxvals) or 0
-- linkprefix (strip quotes)
local lp = (args.linkprefix or args.lp or ""):gsub('"', '')
local famname = ""
if sk == "" then
local p734 = mw.wikibase.getBestStatements(qidqid1, "P734")[1]
local p734id = p734 and p734.mainsnak.snaktype == "value" and p734.mainsnak.datavalue.value.id or ""
famname = mw.wikibase.sitelinkgetSitelink(p734id) or ""
-- strip namespace and disambigation
local pos = famname:find(":") or 0
famname = famname:sub(pos+1):gsub("%s%(.+%)$", "")
if famname == "" then
local lbl = mw.wikibase.labelgetLabel(p734id)
famname = lbl and mw.text.nowiki(lbl) or ""
end
end
local cat1 onlysrc = parseParam(args.onlysourced or args.osd, true) local maxvals = tonumber(args.maxvals) or 0 local qualID = mw.text.trim(args.qual or ""):upper() if qualID == "" then qualID = nil end local out = {}
for k, v in ipairs(statements1) do
if not onlysrc or sourced(v) then
-- get the ID representing the value of the property local pvalID snak = (v.mainsnak if snak.datatype == "wikibase-item" and snak.snaktype == "value") and v.mainsnakthen local qid2 = snak.datavalue.value.id local statements2 = {} if pvalID args.reqranks.b then -- get the topic's main category statements2 = mw.wikibase.getBestStatements(P910qid2, pid2) for that entity local p910 else statements2 = mw.wikibase.getBestStatementsgetAllStatements(pvalIDqid2, "P910"pid2) end if statements2[1] if p910 and p910statements2[1].mainsnak.snaktype == "value" then local tmcID qid3 = p910statements2[1].mainsnak.datavalue.value.id -- use local sitelink or the English label for the cat local cat = mw.wikibase.sitelinkgetSitelink(tmcIDqid3) -- if there's no local sitelink, create the sitelink from English label if not cat sitelink then local lbl = mw.wikibase.getLabelByLang(tmcIDqid3, "en")
if lbl then
if lbl:sub(1,9) == "Category:" then
cat sitelink = mw.text.nowiki(lbl)
else
cat sitelink = "Category:" .. mw.text.nowiki(lbl)
end
end
end
cat1if sitelink then if sk ~= "" then out[#cat1out+1] = cat"[[" .. lp .. sitelink .. "|" .. sk .. "]]" elseif famname ~= "" then out[#out+1] = "[[" .. lp .. sitelink .. "|" .. famname .. "]]" else out[#out+1] = "[[" .. lp .. sitelink .. "]]" end -- of check for sort keys end -- of test for sitelink end -- of test for topic's main category exists end -- of test for property wikibase item has vaild a value
end -- of test for sourced
if maxvals > 0 and #cat1 out >= maxvals then break end end local cat2 = {} for k, v in ipairs(statements2) do if not onlysrc or sourced(v) then local cat = rendersnak(v, args) if subs[cat] then cat = subs[cat] end cat2[#cat2+1] = cat end if maxvals > 0 and #cat2 >= maxvals then break end end out = {} for k1, v1 in ipairs(cat1) do for k2, v2 in ipairs(cat2) do if sk ~= "" then out[#out+1] = "[[" .. lp .. v1 .. " " .. join .. " " .. v2 .. "|" .. sk .. "]]" elseif famname ~= "" then out[#out+1] = "[[" .. lp .. v1 .. " " .. join .. " " .. v2 .. "|" .. famname .. "]]" else out[#out+1] = "[[" .. lp .. v1 .. " " .. join .. " " .. v2 .. "]]" end -- of check for sort keys end end args.noicon = "true"loop through values of property1 return assembleoutput(out, args, qidqid1, pid1)
end
-------------------------------------------------------------------------------
-- qualsToTable getIntersectCat takes most of the usual parameters.-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented.-- A qid may be givenIt takes two properties, |prop1 and the first unnamed parameter is the property ID, which is |prop2 (e.g. occupation and country of type wikibase item.citizenship)-- It takes Each property's value is a list of qualifier property IDs as |quals=wiki-base entity-- For a given qid and property, each value of the first parameter (ranks implemented) it creates fetches the rows of an html table,value's main category-- and then each row being a value of the property second parameter (optionally only if possibly substituting a simpler description)-- then it returns all of the property matches categories representing the value in intersection of those properties,-- (e.g. Category:Actors from Canada). A joining term may be supplied (e.g. |pvaljoin= from).-- each cell being The item's P734 (family name) is the first value of sort key, or no sort key if there is no family name.-- The sort key may be overridden by the qualifier corresponding to the list in parameter |sortkey (alias |qualssk).
-------------------------------------------------------------------------------
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput;
-------------------------------------------------------------------------------
p.qualsToTable getIntersectCat = function(frame) frame.args.reqranks = setRanks(frame.args.rank) frame.args.langobj = findLang(frame.args.lang) frame.args.lang = frame.args.langobj.code
local args = frame.args
args.sep = " " args.linked = "no" local quals pid1 = args.quals prop1 or "P106" local pid2 = args.prop2 or "P27" if quals pid1 == "" or pid2 == "" then return "" nil end  args.reqranks local qid, statements1 = setRanksparseInput(args.rankframe, "", pid1) if not qid then return nil end local propertyID qid, statements2 = mw.text.trimparseInput(args[1] or frame, "", pid2) local f = {}if not qid then return nil end f.args = args-- topics like countries may have different names in categories from their label in Wikidata local entityidsubs_exists, props subs = parseInputpcall(fmw.loadData, "Module:WikidataIB/subs", propertyID) if not entityid then return local join = args.join or "" end  local onlysrc = parseParam(args.onlysourced or args.langobj osd, true) local maxvals = findLangtonumber(args.langmaxvals) or 0 -- linkprefix (strip quotes) local lp = (args.lang = linkprefix or args.langobj.codelp or ""):gsub('"', '') -- sort key (strip quotes, hyphens and periods): local pval sk = (args.pval sortkey or args.sk or ""):gsub('["-.]', '') -- family name: local famname = "" if sk == "" then local qplist p734 = mw.textwikibase.splitgetBestStatements(qualsqid, "%pP734")[1] local p734id = p734 and p734.mainsnak.snaktype == "value" and p734.mainsnak.datavalue.value.id or "" famname = mw.wikibase.getSitelink(p734id) or "" -- split at punctuation strip namespace and make a sequential tabledisambigation for i local pos = famname:find(":") or 0 famname = famname:sub(pos+1):gsub("%s%(.+%)$", v in ipairs(qplist"") do qplist[i] if famname == "" then local lbl = mw.textwikibase.trimgetLabel(vp734id):upper famname = lbl and mw.text.nowiki(lbl) -- remove whitespace and capitaliseor "" end
end
local cat1 = {} for k, v in ipairs(statements1) do if not onlysrc or sourced(v) then -- get the ID representing the value of the property local pvalID = (v.mainsnak.snaktype == "value") and v.mainsnak.datavalue.value.id if pvalID then -- get the topic's main category (P910) for that entity local col1 p910 = argsmw.wikibase.firstcol or getBestStatements(pvalID, "P910")[1] if col1 ~p910 and p910.mainsnak.snaktype == "value" then col1 local tmcID = p910.mainsnak.datavalue.value.id -- use sitelink or the English label for the cat local cat = mw.wikibase.getSitelink(tmcID) if not cat then local lbl = col1 mw.wikibase. getLabelByLang(tmcID, "</td><td>en") end if lbl then if lbl:sub(1,9) == "Category:" then local emptycell cat = argsmw.text.emptycell or nowiki(lbl) else cat = "&nbsp;Category:".. mw.text.nowiki(lbl) end end end cat1[#cat1+1] = cat end -- of test for topic's main category exists end --of test for property has vaild value end - construct a 2-D array of qualifier values in qvalstest for sourced if maxvals > 0 and #cat1 >= maxvals then break end end local qvals cat2 = {} for ik, v in ipairs(propsstatements2) do local skip = false if pval ~= "" not onlysrc or sourced(v) then local pid cat = rendersnak(v.mainsnak.datavalue and v.mainsnak.datavalue.value.id, args) if pid ~= pval subs[cat] then skip cat = true subs[cat] end cat2[#cat2+1] = cat
end
if not skip then local qval = {} local vqualifiers = v.qualifiers or {} -- go through list of wanted qualifier properties for i1, v1 in ipairs(qplist) do -- check for that property ID in the statement's qualifiers local qv, qtype if vqualifiers[v1] then qtype = vqualifiers[v1][1].datatype if qtype == "time" then if vqualifiers[v1][1].snaktype =maxvals > 0 and #cat2 >= "value" maxvals then qv = mw.wikibase.renderSnak(vqualifiers[v1][1]) qv = frame:expandTemplate{title="dts", args={qv}} else qv = "?" end elseif qtype == "url" then qv = mw.wikibase.renderSnak(vqualifiers[v1][1]) local display = mw.ustring.match( mw.uri.decode(qv, "WIKI"), "([%w ]+)$" ) if display then qv = "[" .. qv .. " " .. display .. "]" end else qv = mw.wikibase.formatValue(vqualifiers[v1][1]) end end -- record either the value or a placeholder qval[i1] = qv or emptycell end -- of loop through list of qualifiers -- add the list of qualifier values as a "row" in the main list qvals[#qvals+1] = qval break end end -- of for each value loop 
local out = {}
for ik1, v v1 in ipairs(qvalscat1) do for k2, v2 in ipairs(cat2) do if sk ~= "" then out[#out+1] = "[[" .. lp .. v1 .. " " .. join .. " " .. v2 .. "|" .. sk .. "]]" elseif famname ~= "" then out[i#out+1] = "<tr><td>[[" .. col1 lp ..v1 . table.concat(qvals" " .. join .. " " .. v2 .. "|" .. famname .. "]]" else out[i#out+1], = "[[" .. lp .. v1 .. " " .. join .. "</td><td>") .. v2 .. "</td></tr>]]" end -- of check for sort keys end end args.noicon = "true" return table.concatassembleoutput(out, "\n"args, qid, pid1)
end
-------------------------------------------------------------------------------
-- getGlobe qualsToTable takes an optional most of the usual parameters.-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented.-- A qid may be given, and the first unnamed parameter is the property ID, which is of type wikibase item.-- It takes a Wikidata entity passed list of qualifier property IDs as |qidquals=-- otherwise For a given qid and property, it uses creates the linked item for the current page.rows of an html table,-- If returns each row being a value of the Qid of property (optionally only if the property matches the globe used value in P625 (coordinate location|pval= ),-- or nil if there isn't one.each cell being the first value of the qualifier corresponding to the list in |quals
-------------------------------------------------------------------------------
-- Dependencies: noneparseParam; setRanks; parseInput; sourced;
-------------------------------------------------------------------------------
p.getGlobe qualsToTable = function(frame) local qid args = frame.args.qid or frame.args[1] or "" if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage() end local coords = mw.wikibase.getBestStatements(qid, "P625")[1] local globeid if coords and coords.mainsnak.snaktype == "value" then globeid = coords.mainsnak.datavalue.value.globe:match("(Q%d+)") end return globeidend
local quals = args.quals or ""
if quals == "" then return "" end
--------------------------------------------------------------------------------- getCommonsLink takes an optional qid of a Wikidata entity passed as |qid=-- It returns one of the following in order of preference:-- the Commons sitelink of the linked Wikidata item;-- the Commons sitelink of the topic's main category of the linked Wikidata item;--------------------------------------------------------------------------------- Dependencies: _getCommonslink(); _getSitelink(); parseParam()-------------------------------------------------------------------------------p.getCommonsLink = function(frame) local oc = frame.args.onlycat or frame.args.onlycategories local fb reqranks = parseParamsetRanks(frame.args.fallback or frame.args.fb, true) return _getCommonslink(frame.args.qid, oc, fbrank)end
local propertyID = mw.text.trim(args[1] or "")
local f = {}
f.args = args
local entityid, props = parseInput(f, "", propertyID)
if not entityid then return "" end
--------------------------------------------------------------------------------- getSitelink takes the qid of a Wikidata entity passed as |qid=-- It takes an optional parameter |wiki= to determine which wiki is to be checked for a sitelink-- If the parameter is blank, then it uses the local wiki.-- If there is a sitelink to an article available, it returns the plain text link to the article-- If there is no sitelink, it returns nil.--------------------------------------------------------------------------------- Dependencies: none-------------------------------------------------------------------------------p args.getSiteLink langobj = functionfindLang(frameargs.lang) return _getSitelink(frame.args.qid, frame.lang = args.wiki or mw.text.trim(framelangobj.args[1] or ""))endcode
local pval = args.pval or ""
--------------------------------------------------------------------------------- getLink has the qid of a Wikidata entity passed as the first unnamed parameter or as |qid=-- If there is a sitelink to an article on the local Wiki, it returns a link to the article-- with the Wikidata label as the displayed text.-- If there is no sitelink, it returns the label as plain text.-- If there is no label in the local language, it displays the qid instead.--------------------------------------------------------------------------------- Dependencies: none-------------------------------------------------------------------------------p.getLink = function(frame) local itemID qplist = mw.text.trimsplit(frame.args[1] or frame.args.qid or quals, "%p")-- split at punctuation and make a sequential table if itemID == "" then return endfor i, v in ipairs(qplist) do local sitelink qplist[i] = mw.wikibasetext.sitelinktrim(itemIDv) local label = labelOrId:upper(itemID) if sitelink then return "[[:" .. sitelink .. "|" .. label .. "]]" else return label-- remove whitespace and capitalise
end
end
local col1 = args.firstcol or ""
if col1 ~= "" then
col1 = col1 .. "</td><td>"
end
--------------------------------------------------------------------------------- getLabel has the qid of a Wikidata entity passed as the first unnamed parameter or as |qid=-- It returns the Wikidata label for the local language as plain text.-- If there is no label in the local language, it displays the qid instead.--------------------------------------------------------------------------------- Dependencies: none-------------------------------------------------------------------------------p.getLabel = function(frame) local itemID = mw.text.trim(frame.args[1] or frame.args.qid or "") if itemID == "" then return end local lang emptycell = frame.args.lang emptycell or "&nbsp;" if lang == "" then lang = nil end local label = labelOrId(itemID, lang) return labelend
 ---------------------------------------------------------------------------- --construct a 2-D array of qualifier values in qvals local qvals = {}-- getAT for i, v in ipairs(Article Titleprops)do local skip = false if pval ~= "" then local pid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if pid ~= pval then skip = true end end if not skip then local qval = {} local vqualifiers = v.qualifiers or {} -- has the qid go through list of a Wikidata entity passed as the first unnamed parameter or as |qid=wanted qualifier properties for i1, v1 in ipairs(qplist) do -- If there is a sitelink to an article on check for that property ID in the statement's qualifiers local Wikiqv, it returns the sitelink as plain textqtype if vqualifiers[v1] then qtype = vqualifiers[v1][1].datatype if qtype == "time" then-- If there is no sitelink, it returns nothing if vqualifiers[v1][1].snaktype == "value" then------------------------------------------------------------------------------- qv = mw.wikibase.renderSnak(vqualifiers[v1][1])-- Dependencies qv = frame: noneexpandTemplate{title="dts", args={qv}}------------------------------------------------------------------------------- else qv = "?" end elseif qtype == "url" thenp if vqualifiers[v1][1].getAT snaktype = function= "value" then qv = mw.wikibase.renderSnak(framevqualifiers[v1][1]) local itemID display = mw.textustring.trimmatch( mw.uri.decode(qv, "WIKI"), "(frame[%w ]+)$" ) if display then qv = "[" .. qv .. " " .. display .. "]" end end else qv = mw.wikibase.argsformatValue(vqualifiers[v1][1] ) end end -- record either the value or frame.args.qid a placeholder qval[i1] = qv or emptycell end -- of loop through list of qualifiers -- add the list of qualifier values as a "row")in the main list qvals[#qvals+1] = qval end end -- of for each value loop  if itemID local out ={} for i, v in ipairs(qvals) do out[i] = "<tr><td>" .. col1 .. table.concat(qvals[i], "</td><td>") .. "</td></tr>" then return end return mwtable.wikibase.sitelinkconcat(itemIDout, "\n")end  --------------------------------------------------------------------------------- getDescription has the getGlobe takes an optional qid of a Wikidata entity passed as |qid=-- (otherwise it defaults to uses the associated qid of linked item for the current article if omitted)-- and a local parameter passed as the first unnamed parameterpage.-- Any local parameter passed (other than "Wikidata" or "none") becomes the return value.-- It If returns the article description for Qid of the Wikidata entity if the local parameter is "Wikidata".globe used in P625 (coordinate location),-- Nothing is returned or nil if the description doesnthere isn't exist or "none" is passed as the local parameterone.
-------------------------------------------------------------------------------
-- Dependencies: none
-------------------------------------------------------------------------------
p.getDescription getGlobe = function(frame) local desc qid = mwframe.textargs.trim(qid or frame.args[1] or "" if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage()end local itemID coords = mw.textwikibase.trimgetBestStatements(frame.args.qid or , "P625")[1] local globeid if itemID coords and coords.mainsnak.snaktype == "value" then itemID = nil end if desc:lower() globeid == 'wikidata' then return mwcoords.mainsnak.datavalue.wikibasevalue.descriptionglobe:match(itemID"(Q%d+) elseif desc:lower(") == 'none' then return nil else return desc
end
return globeid
end
-------------------------------------------------------------------------------
-- getAliases has the getCommonsLink takes an optional qid of a Wikidata entity passed as |qid=-- (it defaults to It returns one of the associated qid following in order of the current article if omitted)preference:-- and a local parameter passed as the first unnamed parameter.-- It implements blacklisting and whitelisting with a field name Commons sitelink of "alias" by default.the linked Wikidata item;-- Any local parameter passed becomes the return value.-- Otherwise it returns Commons sitelink of the aliases for topic's main category of the linked Wikidata entity with the usual list options.-- Nothing is returned if the aliases do not exist.item;
-------------------------------------------------------------------------------
-- Dependencies: findLang_getCommonslink(); assembleoutput_getSitelink(); parseParam()
-------------------------------------------------------------------------------
p.getAliases getCommonsLink = function(frame) local oc = frame.args.onlycat or frame.args .onlycategories local fb = parseParam(frame.args.fallback or frame.args.fb, true) return _getCommonslink(frame.args.qid, oc, fb)end
local fieldname = args.name or ""
if fieldname == "" then fieldname = "alias" end
--------------------------------------------------------------------------------- getSitelink takes the qid of a Wikidata entity passed as |qid=-- It takes an optional parameter |wiki= to determine which wiki is to be checked for a sitelink-- If the parameter is blank, then it uses the local blacklist wiki.-- If there is a sitelink to an article available, it returns the plain text link to the article-- If there is no sitelink, it returns nil.--------------------------------------------------------------------------------- Dependencies: none-------------------------------------------------------------------------------p.getSiteLink = function(frame) return _getSitelink(frame.args.suppressfields qid, frame.args.wiki or mw.text.trim(frame.args.spf [1] or "")) if blacklist:find(fieldname) then return nil end
local localval = mw.text.trim(args[1] or "")
if localval ~= "" then return localval end
--------------------------------------------------------------------------------- getLink has the qid of a Wikidata entity passed as the first unnamed parameter or as |qid=-- If there is a sitelink to an article on the local whitelist = argsWiki, it returns a link to the article-- with the Wikidata label as the displayed text.-- If there is no sitelink, it returns the label as plain text.fetchwikidata or args-- If there is no label in the local language, it displays the qid instead.fwd or "" if whitelist == "" then whitelist = "NONE" end--------------------------------------------------------------------------------- Dependencies: none------------------------------------------------------------------------------- if not (whitelist p.getLink == 'ALL' or whitelist:findfunction(fieldname)frame) then return nil end  local qid itemID = mw.text.trim(frame.args[1] or frame.args.qid or "") if qid itemID == "" then qid = nil return end  local entity sitelink = mw.wikibase.getEntitygetSitelink(qiditemID) if not entity then return nil end local aliases label = entity.aliaseslabelOrId(itemID) if not aliases sitelink then return nil end if not qid then qid= mw"[[:" ..wikibasesitelink .getEntityIdForCurrentPage() end  args.langobj = findLang(args"|" .lang) local langcode = args.langobjlabel .code args.lang = langcode  local out = {} for k1, v1 in pairs(aliases) do if v1[1"].language == langcode then for k1, v2 in ipairs(v1) do out[#out+1] = v2.value" end break else endreturn label
end
 
return assembleoutput(out, args, qid)
end
-------------------------------------------------------------------------------
-- pageId returns getLabel has the page id (qid of a Wikidata entity ID, Qnnn) of passed as the current pagefirst unnamed parameter or as |qid=-- It returns nothing if the page Wikidata label for the local language as plain text.-- If there is not connected to Wikidatano label in the local language, it displays the qid instead.
-------------------------------------------------------------------------------
-- Dependencies: none
-------------------------------------------------------------------------------
p.pageId getLabel = function(frame) local itemID = mw.text.trim(frame.args[1] or frame.args.qid or "") if itemID == "" then return mwend local lang = frame.wikibaseargs.getEntityIdForCurrentPagelang or "" if lang == "" then lang = nil end local label = labelOrId(itemID, lang) return label
end
-------------------------------------------------------------------------------
-- formatDate label has the qid of a Wikidata entity passed as the first unnamed parameter or as |qid=-- if no qid is a wrapper to export supplied, it uses the qid associated with the current page.-- It returns the Wikidata label for the local language as plain text.-- If there is no label in the private function format_Datelocal language, it returns nil.
-------------------------------------------------------------------------------
-- Dependencies: format_Date();none
-------------------------------------------------------------------------------
p.formatDate label = function(frame) return format_Datelocal qid = mw.text.trim(frame.args[1], or frame.args.df, qid or "") if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage() end if not qid then return end local lang = frame.args.bclang or "" if lang == "" then lang = nil end local label, success = labelOrId(qid, lang) if success then return label end
end
-------------------------------------------------------------------------------
-- location is a wrapper to export the private function _locationgetAT (Article Title)-- it takes has the qid of a Wikidata entity-id passed as qid or the first unnamed parameteror as |qid=-- optional boolean parameter first toggles If there is a sitelink to an article on the display of local Wiki, it returns the first itemsitelink as plain text.-- optional boolean parameter skip toggles the display to skip to the last item-- parameter debug=<y/n> (default 'n') adds error msg if not a locationIf there is no sitelink or qid supplied, it returns nothing.
-------------------------------------------------------------------------------
-- Dependencies: _location();none
-------------------------------------------------------------------------------
p.location getAT = function(frame) local debug = (frame.args.debug or ""):sub(1, 1):lower() if debug == "" then debug = "n" end local qid itemID = mw.text.trim(frame.args.qid [1] or frame.args[1] .qid or ""):upper() if qid itemID == "" then qid=mw.wikibase.getEntityIdForCurrentPage() return end if not qid then if debug ~= "n" then return i18n.errors["entity-not-found"] else return nil end end local first = mw.text.trim(frame.args.first or "") local skip = mw.text.trim(frame.argswikibase.skip or "") return table.concat( _locationgetSitelink(qid, first, skip), ", " itemID)
end
-------------------------------------------------------------------------------
-- checkBlacklist implements getDescription has the qid of a test to check whether a named field is allowedWikidata entity passed as |qid=-- returns true (it defaults to the associated qid of the current article if the field is not blacklisted (i.e. allowedomitted)-- returns false if and a local parameter passed as the field is blacklisted (i.efirst unnamed parameter. disallowed)-- {{#if:{{#invoke:WikidataIB |checkBlacklist |name=Joe |suppressfields=Dave; Joe; Fred}} | not blacklisted | blacklisted}}Any local parameter passed (other than "Wikidata" or "none") becomes the return value.-- displays It returns the article description for the Wikidata entity if the local parameter is "blacklistedWikidata".-- {{#Nothing is returned if:{{#invoke:WikidataIB |checkBlacklist |name=Jim |suppressfields=Dave; Joe; Fred}} | not blacklisted | blacklisted}}-- displays the description doesn't exist or "not blacklistednone"is passed as the local parameter.
-------------------------------------------------------------------------------
-- Dependencies: none
-------------------------------------------------------------------------------
p.checkBlacklist getDescription = function(frame) local blacklist desc = framemw.argstext.suppressfields or trim(frame.args.spf [1] or "") local fieldname itemID = mw.text.trim(frame.args.name qid or "") if blacklist ~itemID = "" and fieldname ~= "" thenitemID = nil end if blacklistdesc:findlower(fieldname) == 'wikidata' then return falsemw.wikibase.getDescription(itemID) elseif desc:lower() == 'none' then else return true endnil
else
-- one of the fields is missing: let's call that "not on the list" return truedesc
end
end
-------------------------------------------------------------------------------
-- emptyor returns nil if its first unnamed argument is just punctuation, whitespace or html tagsgetAliases has the qid of a Wikidata entity passed as |qid=-- otherwise (it returns defaults to the associated qid of the argument unchanged (including leading/trailing spacecurrent article if omitted).-- If and a local parameter passed as the argument may contain "=", then it must be called explicitly:first unnamed parameter.-- |1=argIt implements blacklisting and whitelisting with a field name of "alias" by default.-- (In that case, leading and trailing spaces are trimmed)Any local parameter passed becomes the return value.-- It finds use in infoboxes where Otherwise it can replace tests like:returns the aliases for the Wikidata entity with the usual list options.-- {{#Nothing is returned if: {{#invoke:WikidatIB |getvalue |P99 |fwd=ALL}} | <span class="xxx">{{#invoke:WikidatIB |getvalue |P99 |fwd=ALL}}</span> | }}-- with a form that uses just a single call to Wikidata:-- {{#invoke |WikidataIB |emptyor |1= <span class="xxx">{{#invoke:WikidataIB |getvalue |P99 |fwd=ALL}}</span> }}the aliases do not exist.
-------------------------------------------------------------------------------
-- Dependencies: nonefindLang(); assembleoutput()
-------------------------------------------------------------------------------
p.emptyor getAliases = function(frame) local s args = frame.args[1] or "" if s == "" then return nil end local sx = s:gsub("%s", ""):gsub("<[^>]*>", ""):gsub("%p", "") if sx == "" then return nil else return s endend
local fieldname = args.name or ""
if fieldname == "" then fieldname = "alias" end
--------------------------------------------------------------------------------- labelorid is a public function to expose the output of labelOrId()-- Pass the Q-number as |qid local blacklist = args.suppressfields or as an unnamed parameterargs.spf or ""-- It returns the Wikidata label for that entity or the qid if no label exists.--------------------------------------------------------------------------------- Dependenciesblacklist: labelOrId-------------------------------------------------------------------------------p.labelorid = functionfind(framefieldname) then return labelOrId( frame.args.qid or frame.args[1] )nil end
local localval = mw.text.trim(args[1] or "")
if localval ~= "" then return localval end
--------------------------------------------------------------------------------- getLang returns the MediaWiki language code of the current content local whitelist = args.fetchwikidata or args.fwd or ""-- If optional parameter |style if whitelist == "" then whitelist =full, it returns the language name."NONE" end--------------------------------------------------------------------------------- Dependencies if not (whitelist == 'ALL' or whitelist: none-------------------------------------------------------------------------------p.getLang = functionfind(framefieldname))then return nil end  local style qid = (frame.args.style qid or "" if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage():lowerend if not qid or not mw.wikibase.entityExists(qid)then return nil end  local langcode aliases = mw.languagewikibase.getEntity(qid).aliases if not aliases then return nil end  args.getContentLanguagelangobj = findLang(args.lang) local langcode = args.langobj.code if style args.lang =langcode  local out = "full" then{} for k1, v1 in pairs(aliases) do return mwif v1[1].language.fetchLanguageName== langcode then for k1, v2 in ipairs( langcode v1)do out[#out+1] = v2.value end break end
end
  return langcodeassembleoutput(out, args, qid)
end
-------------------------------------------------------------------------------
-- getItemLangCode takes a qid parameter (using pageId returns the current page's qid if blank)-- If the item for that qid has property country id (P17) it looks at the first preferred value-- If the country has an official language (P37)entity ID, it looks at the first preferred value-- If that official language has a language code (P424Qnnn), it returns of the first preferred valuecurrent page-- Otherwise it returns nothing.if the page is not connected to Wikidata
-------------------------------------------------------------------------------
-- Dependencies: _getItemLangCode()none
-------------------------------------------------------------------------------
p.getItemLangCode pageId = function(frame) return _getItemLangCode(framemw.argswikibase.qid or frame.args[1]getEntityIdForCurrentPage()
end
-------------------------------------------------------------------------------
-- findLanguage exports formatDate is a wrapper to export the local findLang() private function-- It takes an optional language code and returns, in order of preference:-- the code if a known language;-- the user's language, if set;-- the server's content language.format_Date
-------------------------------------------------------------------------------
-- Dependencies: findLangformat_Date();
-------------------------------------------------------------------------------
p.findLanguage formatDate = function(frame) return findLangformat_Date(frame.args[1], frame.lang or args.df, frame.args[1].bc).code
end
-------------------------------------------------------------------------------
-- getQid returns location is a wrapper to export the private function _location-- it takes the entity-id as qid, if suppliedor the first unnamed parameter-- failing that, optional boolean parameter first toggles the Wikidata entity ID display of the "category's main topic (P301)", if it existsfirst item-- failing that, optional boolean parameter skip toggles the Wikidata entity ID associated with display to skip to the current page, if it existslast item-- otherwise, nothingparameter debug=<y/n> (default 'n') adds error msg if not a location
-------------------------------------------------------------------------------
-- Dependencies: none_location();
-------------------------------------------------------------------------------
p.getQid location = function(frame) local qid debug = (frame.args.qid debug or ""):uppersub(1, 1) -- check if a qid was passed; if so, return it:lower() if qid ~debug == "" then return qid debug = "n" end -- check if there's a local qid = mw.text.trim(frame.args.qid or frame.args[1] or ""category's main topic ):upper(P301)": if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage()end if not qid then local prop301 if debug ~= mw.wikibase.getBestStatements(qid, "P301n") if prop301[1] then local mctid = prop301return i18n.errors[1"entity-not-found"].mainsnak.datavalue.value.id else if mctid then return mctid endnil
end
end
-- otherwise return the page qid local first = mw.text.trim(frame.args.first or "") local skip = mw.text.trim(if anyframe.args.skip or "") return table.concat( _location(qid, first, skip), ", " )
end
-------------------------------------------------------------------------------
-- followQid takes three optional parameters: qid, props, and all.checkBlacklist implements a test to check whether a named field is allowed-- If qid returns true if the field is not given, it uses the qid for the connected pageblacklisted (i.e. allowed)-- or returns nil false if there isn't onethe field is blacklisted (i.-- props is a list of properties, separated by punctuatione.disallowed)-- If props is given, the Wikidata item for the qid is examined for each property in turn.{{#if:{{#invoke:WikidataIB |checkBlacklist |name=Joe |suppressfields=Dave; Joe; Fred}} | not blacklisted | blacklisted}}-- If that property contains a value that is another Wikibase-item, that item's qid is returned,displays "blacklisted"-- and the search terminates, unless {{#if:{{#invoke:WikidataIB |checkBlacklist |name=Jim |allsuppressfields=y when all of the qids are returned, sparated by spaces.Dave; Joe; Fred}} | not blacklisted | blacklisted}}-- If props is displays "not given, the qid is returned.blacklisted"
-------------------------------------------------------------------------------
-- Dependencies: parseParam()none
-------------------------------------------------------------------------------
p.followQid checkBlacklist = function(frame) local qid blacklist = (frame.args.qid suppressfields or ""):upper() local all = parseParam(frame.args.all, false) if qid == spf or "" then qid = mw.wikibase.getEntityIdForCurrentPage() end if not qid then return nil end local out fieldname = {} local props = (frame.args.props name or ""):upper() if props blacklist ~= "" and fieldname ~= "" then for p in mw.text.gsplitif blacklist:find(props, "%p"fieldname) do -- split at punctuation and iteratethen p = mw.text.trim(p)return false for i, v in ipairs( mw.wikibase.getBestStatements(qid, p) ) do local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] = linkedid else return linkedid end -- test for all or just the first one found end -- test for value exists for that property end -- loop through values of property to followtrue end -- loop through list of properties to follow end if #out > 0 then return table.concat(out, " ")
else
-- one of the fields is missing: let's call that "not on the list" return qidtrue
end
end
-------------------------------------------------------------------------------
-- globalSiteID emptyor returns nil if its first unnamed argument is just punctuation, whitespace or html tags-- otherwise it returns the globalSiteID for argument unchanged (including leading/trailing space).-- If the current wikiargument may contain "=", then it must be called explicitly:-- e.g. returns |1=arg-- (In that case, leading and trailing spaces are trimmed)-- It finds use in infoboxes where it can replace tests like:-- {{#if: {{#invoke:WikidatIB |getvalue |P99 |fwd=ALL}} | <span class="enwikixxx" for the English Wikipedia, >{{#invoke:WikidatIB |getvalue |P99 |fwd=ALL}}</span> | }}-- with a form that uses just a single call to Wikidata:-- {{#invoke |WikidataIB |emptyor |1= <span class="enwikisourcexxx" for English Wikisource, etc.>{{#invoke:WikidataIB |getvalue |P99 |fwd=ALL}}</span> }}
-------------------------------------------------------------------------------
-- Dependencies: none
-------------------------------------------------------------------------------
p.globalSiteID emptyor = function(frame) local s = frame.args[1] or "" if s == "" then return nil end local sx = s:gsub("%s", ""):gsub("<[^>]*>", ""):gsub("%p", "") if sx == "" then return mwnil else return s endend  --------------------------------------------------------------------------------- labelorid is a public function to expose the output of labelOrId()-- Pass the Q-number as |qid= or as an unnamed parameter.wikibase-- It returns the Wikidata label for that entity or the qid if no label exists.getGlobalSiteId--------------------------------------------------------------------------------- Dependencies: labelOrId-------------------------------------------------------------------------------p.labelorid = function(frame) return (labelOrId(frame.args.qid or frame.args[1]))
end
-------------------------------------------------------------------------------
-- siteID getLang returns the root MediaWiki language code of the globalSiteID-- e.g. "en" for "enwiki", "enwikisource", etccurrent content.-- treats "en-gb" as "en"If optional parameter |style=full, etcit returns the language name.
-------------------------------------------------------------------------------
-- Dependencies: none
-------------------------------------------------------------------------------
p.siteID getLang = function(frame) local txtlang style = (frame.args.style or ""):preprocesslower( "{{int:lang}}" ) or "" -- This deals with specific exceptions: be-tarask -> be-x-oldlocal langcode = mw.language.getContentLanguage().code if txtlang style == "be-taraskfull" then return "be_x_old"mw.language.fetchLanguageName( langcode )
end
local pos = txtlang:find("-") local ret = "" if pos then ret = txtlang:sub(1, pos-1) else ret = txtlang end return retlangcode
end
-------------------------------------------------------------------------------
-- projID returns the code used to link to getItemLangCode takes a qid parameter (using the reader's languagecurrent page's projectqid if blank)-- e.g "en" If the item for [[:en:WikidataIB]]that qid has property country (P17) it looks at the first preferred value-- treats "enIf the country has an official language (P37), it looks at the first preferred value-gb" as "en"- If that official language has a language code (P424), etcit returns the first preferred value-- Otherwise it returns nothing.
-------------------------------------------------------------------------------
-- Dependencies: none_getItemLangCode()
-------------------------------------------------------------------------------
p.projID getItemLangCode = function(frame) local txtlang = return _getItemLangCode(frame:preprocess( "{{int:lang}}" ) .args.qid or "" -- This deals with specific exceptions: be-tarask -> be-x-old if txtlang == "be-tarask" then return "be-x-old" end local pos = txtlang:find("-") local ret = "" if pos then ret = txtlang:sub(1, pos-frame.args[1]) else ret = txtlang end return retend  
-------------------------------------------------------------------------------
-- formatNumber formats a number according to findLanguage exports the local findLang() function-- It takes an optional language code and returns, in order of preference:-- the supplied code if a known language code ("|lang=");-- or the default user's language , if not supplied.set;-- The number is the first unnamed parameter or "|num="server's content language.
-------------------------------------------------------------------------------
-- Dependencies: findLang()
-------------------------------------------------------------------------------
p.formatNumber findLanguage = function(frame) local lang local num = tonumberreturn findLang(frame.args[1] .lang or frame.args.num[1]) or 0 lang = findLang(frame.args.lang) return lang:formatNum( num )code
end
-------------------------------------------------------------------------------
-- examine dumps getQid returns the property (the unnamed parameter or pid)qid, if supplied-- from failing that, the item given by Wikidata entity ID of the parameter 'qid"category' s main topic (or the other unnamed parameterP301)", if it exists-- or from failing that, the item corresponding to Wikidata entity ID associated with the current page , if qid is not supplied.-- e.g. {{#invoke:WikidataIB |examine |pid=P26 |qid=Q42}}-- or {{#invoke:WikidataIB |examine |P26 |Q42}} or any combination of theseit exists-- or {{#invoke:WikidataIB |examine |P26}} for the current page.otherwise, nothing
-------------------------------------------------------------------------------
-- Dependencies: none
-------------------------------------------------------------------------------
p.examine getQid = function( frame ) local args if qid = (frame.args[1] or frame.args.pid qid or frame.args.""):upper() -- check if a qid was passed; if so, return it: if qid ~= "" thenreturn qid end -- check if there's a "category's main topic (P301)": args qid = framemw.wikibase.argsgetEntityIdForCurrentPage() elseif qid then args local prop301 = frame:getParentmw.wikibase.getBestStatements(qid, "P301") if prop301[1] then local mctid = prop301[1].argsmainsnak.datavalue.value.id if mctid then return mctid end end
end
local par = {} local pid = (args.pid or ""):upper() local qid = (args.qid or ""):upper() par[1] = mw.text.trim( args[1] or "" ):upper() par[2] = mw.text.trim( args[2] or "" ):upper() table.sort(par) if par[2]:sub(1,1) == "P" then par[1], par[2] = par[2], par[1] end if pid == "" then pid = par[1] end if qid == "" then -- otherwise return the page qid = par[2] end if pid:sub(1,1) ~= "P" then return "No property supplied" end if qid:sub(1,1) ~= "Q" then qid = mw.wikibase.getEntityIdForCurrentPage(any) end if not qid then return "No item for this page" end return "<pre>" .. mw.dumpObject( mw.wikibase.getAllStatements( qid, pid ) ) .. "</pre>"
end
-------------------------------------------------------------------------------
-- checkvalue looks for 'val' as a wikibase-item value of a property (the unnamed parameter or pid)followQid takes four optional parameters: qid, props, list and all.-- from the item If qid is not given by , it uses the parameter 'qid'for the connected page-- or from the Wikidata item associated with the current page returns nil if qid there isn't one.-- props is not supplieda list of properties, separated by punctuation.-- If property props is not suppliedgiven, then P31 (instance of) the Wikidata item for the qid is assumedexamined for each property in turn.-- It returns val if found or nothing if not found.If that property contains a value that is another Wikibase-- e.g. {{#invoke:WikidataIB |checkvalue |val=Q5 |pid=P31 |item, that item's qid=Q42}}is returned,-- or {{#invoke:WikidataIB |checkvalue and the search terminates, unless |valall=Q5 |P31 |qid=Q42}}y when all of the qids are returned, separated by spaces.-- or {{#invoke:WikidataIB |checkvalue If |vallist=Q5 |qid=Q42}}is set to a template, the qids are passed as arguments to the template.-- or {{#invoke:WikidataIB |checkvalue |val=Q5 |P31}} for If props is not given, the current pageqid is returned.
-------------------------------------------------------------------------------
-- Dependencies: noneparseParam()
-------------------------------------------------------------------------------
p.checkvalue _followQid = function( frame args) local qid = (args.qid or ""):upper() if framelocal all = parseParam(args.all, false) local list = args.val list or "" if list == "" then args list = frame.argsnil end elseif qid == "" then args qid = frame:getParentmw.wikibase.getEntityIdForCurrentPage().args
end
local val = args.val
if not val then return nil end
local pid = mw.text.trim(args.pid or args[1] or "P31"):upper()
local qid = (args.qid or ""):upper()
if pid:sub(1,1) ~= "P" then return nil end
if qid:sub(1,1) ~= "Q" then qid = mw.wikibase.getEntityIdForCurrentPage() end
if not qid then return nil end
local stats out = mw{} local props = (args.wikibase.getAllStatementsprops or ""):upper( qid, pid ) if not stats[1] props ~= "" then return nil end if stats[1] for p in mw.mainsnaktext.datatype == gsplit(props, "%p"wikibase) do --item" thensplit at punctuation and iterate p = mw.text.trim(p) for ki, v in pairsipairs( stats mw.wikibase.getBestStatements(qid, p) ) do if local linkedid = v.mainsnak.snaktype == "value" datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] =linkedid else return linkedid end -- test for all or just the first one found end -- test for value exists for that property end -- loop through values of property to follow end -- loop through list of properties to follow end if #out > 0 then local ret = val "" if list then return val ret = mw.getCurrentFrame():expandTemplate{title = list, args = out} else endret = table.concat(out, " ")
end
return ret
else
return qid
end
end p.followQid = function(frame) return nilp._followQid(frame.args)
end
-------------------------------------------------------------------------------
-- url2 takes a parameter url= that is a proper url and formats it for use in an infobox.-- If no parameter is supplied, it globalSiteID returns nothing.-- This is the equivalent of Template:URL-- but it keeps the "edit at Wikidata" pen icon out of globalSiteID for the microformat.-- Usually it will take its url parameter directly from a Wikidata call:current wiki-- e.g. {{#invoke:WikidataIB |url2 |url={{wdib |P856 |qid=Q23317 |fwd=ALL |osd=no}}returns "enwiki" for the English Wikipedia, "enwikisource" for English Wikisource, etc.
-------------------------------------------------------------------------------
-- Dependencies: none
-------------------------------------------------------------------------------
p.url2 globalSiteID = function(frame) local txt = framereturn mw.wikibase.getGlobalSiteId()end  --------------------------------------------------------------------------------- siteID returns the root of the globalSiteID-- e.argsg.url or "en" for "enwiki", "enwikisource", etc. if txt == -- treats "en-gb" as "en" then return nil end, etc.--------------------------------------------------------------------------------- Dependencies: none-------------------------------------------------------------------------------p.siteID = function(frame) local url, icon txtlang = txtframe:matchcallParserFunction('int', {'lang'}) or "(.+)&nbsp;(.+)") url = url or txt-- This deals with specific exceptions: be-tarask -> be-x-old icon if txtlang = icon or = "be-tarask" then return "be_x_old" end local prot, addr pos = urltxtlang:matchfind("(http[s]*://)(.+)-") prot = prot or url addr local ret = addr or "" local disp, n if pos then ret = addrtxtlang:gsubsub("%."1, "<wbr/>%."pos-1) else ret = txtlang end return '<span class="url">[' .. prot .. addr .. " " .. disp .. "]</span>&nbsp;" .. iconret
end
-------------------------------------------------------------------------------
-- getWebsite fetches projID returns the Official website (P856) and formats it for use in an infobox.code used to link to the reader's language's project-- This is similar to Templatee.g "en" for [[:en:Official website but with a url displayed,WikidataIB]]-- and it adds the treats "edit at Wikidataen-gb" pen icon beyond the microformat if enabled.-- A local value will override the Wikidata value. as "NONEen" returns nothing, etc.-- e.g. {{#invoke:WikidataIB |getWebsite |qid= |noicon= |lang= |url= }}
-------------------------------------------------------------------------------
-- Dependencies: findLang(); parseParam();none
-------------------------------------------------------------------------------
p.getWebsite projID = function(frame) local url txtlang = frame.args.url or "" if url:uppercallParserFunction('int', {'lang'}) == or "NONE" then return nil end  local qid = frame.args.qid or ""-- This deals with specific exceptions: be-tarask -> be-x-old if qid txtlang == "be-tarask" then qid = mw.wikibase.getEntityIdForCurrentPage() end if not qid then return nil end"be-x-old" local urls = {}end local quals = {} if url =pos = txtlang:find("-" then) local prop856 ret = mw.wikibase.getBestStatements(qid, "P856") for k, v in pairs(prop856) do if v.mainsnak.snaktype == "value" pos then urls[#urls+1] ret = v.mainsnak.datavalue.value if v.qualifiers and v.qualifiers["P1065"] then -- just take the first archive url txtlang:sub(P1065) local au = v.qualifiers["P1065"][1] if au.snaktype == "value" then quals[#urls] = au.datavalue.value end , pos-- test for archive url having a value end -- test for qualifers end -- test for website having a value end -- loop through website(s1)
else
urls[1] ret = urltxtlang
end
if #urls == 0 then return nil retend 
local out = {}------------------------------------------------------------------------------- for i, u in ipairs-- formatNumber formats a number according to the the supplied language code (urls"|lang=") do local link = quals[i] -- or uthe default language if not supplied. local prot, addr -- The number is the first unnamed parameter or "|num= u:match("(http[s]*--------------------------------------------------------------------------------- Dependencies://)findLang(.+)") addr = addr or u------------------------------------------------------------------------------- local disp, n p.formatNumber = addr:gsubfunction("%.", "<wbr/>%."frame) out[#out+1] = '<span class="url">[' .. link .. " " .. disp .. "]</span>" endlocal lang local langcode num = findLangtonumber(frame.args[1] or frame.args.langnum).codeor 0 local noicon lang = parseParamfindLang(frame.args.noicon, falselang) if url == "" and not noicon then out[#out] = out[#out] .. createicon(langcode, qid, "P856") end  local ret = "" if #out > 1 then ret = mw.getCurrentFramereturn lang:formatNum(num ):expandTemplate{title = "ubl", args = out} else ret = out[1] end  return ret
end
-------------------------------------------------------------------------------
-- getAllLabels fetches examine dumps the set of labels and formats it for display as wikitext.property (the unnamed parameter or pid)-- It takes a from the item given by the parameter 'qid' (or the other unnamed parameter)-- or from the item corresponding to the current page if qid is not supplied.-- e.g. {{#invoke:WikidataIB |examine |pid=P26 |qid=Q42}}-- or {{#invoke:WikidataIB |examine |P26 |Q42}} or any combination of these-- or {{#invoke:WikidataIB |examine |P26}} for arbitrary access, otherwise it uses the current page.
-------------------------------------------------------------------------------
-- Dependencies: none
-------------------------------------------------------------------------------
p.getAllLabels examine = function(frame) local args = if frame.args [1] or frame:getParent().args .pid or {}  local qid = frame.args.qid if qid == "" then qid = nil end  local entity args = mwframe.wikibase.getEntity(qid)args if not entity then return i18n["entity-not-found"] endelse  local labels args = entity.labels if not labels then return i18n["labels-not-found"] end  local out = {} for k, v in pairsframe:getParent(labels) do out[#out+1] = v.value .. " (" .. v.language .. ")"args
end
local par = {} local pid = (args.pid or ""):upper() local qid = (args.qid or ""):upper() par[1] = mw.text.trim( args[1] or "" ):upper() par[2] = mw.text.trim( args[2] or "" ):upper() return table.concatsort(outpar) if par[2]:sub(1, 1) == "; P"then par[1], par[2] = par[2], par[1] end if pid == "" then pid = par[1] end if qid == "" then qid = par[2] end local q1 = qid:sub(1,1) if pid:sub(1,1) ~= "P" then return "No property supplied" end if q1 ~= "Q" and q1 ~= "M" then qid = mw.wikibase.getEntityIdForCurrentPage() end if not qid then return "No item for this page" end return "<pre>" .. mw.dumpObject( mw.wikibase.getAllStatements( qid, pid ) ) .. "</pre>"
end
-------------------------------------------------------------------------------
-- getAllDescriptions fetches the set of descriptions and formats it checkvalue looks for display 'val' as wikitext.a wikibase-item value of a property (the unnamed parameter or pid)-- It takes a from the item given by the parameter 'qid' -- or from the Wikidata item associated with the current page if qid is not supplied.-- It only checks ranks that are requested (preferred and normal by default)-- If property is not supplied, then P31 (instance of) is assumed.-- It returns val if found or nothing if not found.-- e.g. {{#invoke:WikidataIB |checkvalue |val=Q5 |pid=P31 |qid=Q42}}-- or {{#invoke:WikidataIB |checkvalue |val=Q5 |P31 |qid=Q42}}-- or {{#invoke:WikidataIB |checkvalue |val=Q5 |qid=Q42}}-- or {{#invoke:WikidataIB |checkvalue |val=Q5 |P31}} for arbitrary access, otherwise it uses the current page.
-------------------------------------------------------------------------------
-- Dependencies: none
-------------------------------------------------------------------------------
p.getAllDescriptions checkvalue = function(frame) local args if frame.args.val then args = frame.args or else args = frame:getParent().args end local val = args.val if not val then return nil end local pid = mw.text.trim(args.pid or args[1] or "P31"):upper() local qid = (args.qid or ""):upper() if pid:sub(1,1) ~= "P" then return nil end if qid:sub(1,1) ~= "Q" then qid = mw.wikibase.getEntityIdForCurrentPage() end if not qid then return nil end local ranks = setRanks(args.rank) local stats = {} if ranks.b then stats = mw.wikibase.getBestStatements(qid, pid) else stats = mw.wikibase.getAllStatements( qid, pid ) end if not stats[1] then return nil end if stats[1].mainsnak.datatype == "wikibase-item" then for k, v in pairs( stats ) do local ms = v.mainsnak if ranks[v.rank:sub(1,1)] and ms.snaktype == "value" and ms.datavalue.value.id == val then return val end end end return nilend
local qid = args.qid
if qid == "" then qid = nil end
--------------------------------------------------------------------------------- url2 takes a parameter url= that is a proper url and formats it for use in an infobox.-- If no parameter is supplied, it returns nothing.-- This is the equivalent of Template:URL-- but it keeps the "edit at Wikidata" pen icon out of the microformat.-- Usually it will take its url parameter directly from a Wikidata call:-- e.g. {{#invoke:WikidataIB |url2 |url={{wdib |P856 |qid=Q23317 |fwd=ALL |osd=no}} }}--------------------------------------------------------------------------------- Dependencies: none-------------------------------------------------------------------------------p.url2 = function(frame) local entity txt = mwframe.wikibaseargs.getEntity(qid)url or "" if not entity txt == "" then return i18n[nil end -- extract any icon local url, icon = txt:match("(.+)&nbsp;(.+)"entity) -not-found"] make sure there's at least a space at the end  local descriptions url = entity(url or txt) ..descriptions" " if not descriptions then return i18n[icon = icon or ""descriptions -not-foundextract any protocol like https:// local prot = url:match("(https*://).+[ \"\'] end") -- extract address local out addr = {}"" for k, v in pairsif prot then addr = url:match("https*://(descriptions.+) do[ \"\']") or " " else out[#out+1] prot = v.value .. " //" addr = url:match(" [^%p%s]+%.(. v.language .. +)[ \"\']")or " "
end
-- strip trailing / from end of domain-only url and add <wbr/> before . and / local disp, n = addr:gsub( "^([^/]+)/$", "%1" ):gsub("%/", "<wbr/>/"):gsub("%.", "<wbr/>.") return table'<span class="url">[' .. prot .. addr .. " " .. disp ..concat(out, "]</span>&nbsp; ").. icon
end
-------------------------------------------------------------------------------
-- getAllAliases getWebsite fetches the set of aliases Official website (P856) and formats it for display as wikitextuse in an infobox.-- It takes This is similar to Template:Official website but with a parameter 'qid' for arbitrary accessurl displayed, otherwise -- and it uses adds the current page"edit at Wikidata" pen icon beyond the microformat if enabled.-- A local value will override the Wikidata value. "NONE" returns nothing.-- e.g. {{#invoke:WikidataIB |getWebsite |qid= |noicon= |lang= |url= }}
-------------------------------------------------------------------------------
-- Dependencies: nonefindLang(); parseParam();
-------------------------------------------------------------------------------
p.getAllAliases getWebsite = function(frame) local args url = frame.args .url or frame"" if url:getParentupper().args or == "NONE" then return nil end local urls = {} local quals = {} local qid = frame.args.qidor "" if url and url ~= "" then urls[1] = url else if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage() end if not qid then return nil end
local entity prop856 = mw.wikibase.getEntitygetBestStatements(qid, "P856") for k, v in pairs(prop856) do if not entity v.mainsnak.snaktype == "value" then return i18n urls[#urls+1] = v.mainsnak.datavalue.value if v.qualifiers and v.qualifiers["entityP1065"] then -not-foundjust take the first archive url (P1065) local au = v.qualifiers["P1065"] [1] if au.snaktype == "value" then quals[#urls] = au.datavalue.value end -- test for archive url having a value end -- test for qualifers end-- test for website having a value end -- loop through website(s) local aliases = entity.aliasesend if not aliases #urls == 0 then return i18n["aliases-not-found"] nil end
local out = {}
for k1i, v1 u in pairsipairs(aliasesurls) do local lang link = v1quals[1i].languageor u local val prot, addr = {} for k1, v2 in ipairsu:match("(http[s]*://)(v1.+)") do val[#val+1] addr = v2.valueaddr or u endlocal disp, n = addr:gsub("%.", "<wbr/>%.") out[#out+1] = table.concat(val, '<span class=", url") >[' .. link .. " (" .. lang disp .. ")]</span>"
end
return tablelocal langcode = findLang(frame.args.lang).concatcode local noicon = parseParam(frame.args.noicon, false) if url == "" and not noicon then out[#out] = out[#out] .. createicon(langcode, qid, "; P856") end  local ret = "" if #out > 1 then ret = mw.getCurrentFrame():expandTemplate{title = "ubl", args = out} else ret = out[1] end  return ret
end
-------------------------------------------------------------------------------
-- showNoLinks displays getAllLabels fetches the article titles that should not be linkedset of labels and formats it for display as wikitext.-- It takes a parameter 'qid' for arbitrary access, otherwise it uses the current page.
-------------------------------------------------------------------------------
-- Dependencies: none
-------------------------------------------------------------------------------
p.showNoLinks getAllLabels = function(frame) local args = frame.args or frame:getParent().args or {}  local qid = args.qid or "" if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage() end if not qid or not mw.wikibase.entityExists(qid) then return i18n["entity-not-found"] end  local labels = mw.wikibase.getEntity(qid).labels if not labels then return i18n["labels-not-found"] end 
local out = {}
for k, v in pairs(donotlinklabels) do out[#out+1] = kv.value .. " (" .. v.language .. ")"
end
table.sort( out )
return table.concat(out, "; ")
end
-------------------------------------------------------------------------------
-- checkValidity checks whether getAllDescriptions fetches the first unnamed parameter represents a valid entity-id,-- that is, something like Q1235 or P123set of descriptions and formats it for display as wikitext.-- It returns takes a parameter 'qid' for arbitrary access, otherwise it uses the strings "true" or "false".-- Change false to nil to return "true" or "" (easier to test with #if:)current page.
-------------------------------------------------------------------------------
-- Dependencies: none
-------------------------------------------------------------------------------
function p.checkValiditygetAllDescriptions = function(frame) local id args = mwframe.text.trimargs or frame:getParent(frame).args[1] or {}  local qid = args.qid or "" if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage()end if not qid or not mw.wikibase.isValidEntityIdentityExists(idqid) thenreturn i18n["entity-not-found"] end local descriptions = mw.wikibase.getEntity(qid).descriptions if not descriptions then return truei18n["descriptions-not-found"] end  local out = {} elsefor k, v in pairs(descriptions) do return falseout[#out+1] = v.value .. " (" .. v.language .. ")"
end
 
return table.concat(out, "; ")
end
-------------------------------------------------------------------------------
-- getAllAliases fetches the set of aliases and formats it for display as wikitext.-- It takes a parameter 'qid' for arbitrary access, otherwise it uses the current page.--------------------------------------------------------------------------------- Dependencies: none-------------------------------------------------------------------------------p.getAllAliases = function(frame) local args = frame.args or frame:getParent().args or {}  local qid = args.qid or "" if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage() end if not qid or not mw.wikibase.entityExists(qid) then return i18n["entity-not-found"] end  local aliases = mw.wikibase.getEntity(qid).aliases if not aliases then return i18n["aliases-not-found"] end  local out = {} for k1, v1 in pairs(aliases) do local lang = v1[1].language local val = {} for k1, v2 in ipairs(v1) do val[#val+1] = v2.value end out[#out+1] = table.concat(val, ", ") .. " (" .. lang .. ")" end  return table.concat(out, "; ")end  --------------------------------------------------------------------------------- showNoLinks displays the article titles that should not be linked.--------------------------------------------------------------------------------- Dependencies: none-------------------------------------------------------------------------------p.showNoLinks = function(frame) local out = {} for k, v in pairs(donotlink) do out[#out+1] = k end table.sort( out ) return table.concat(out, "; ")end  --------------------------------------------------------------------------------- checkValidity checks whether the first unnamed parameter represents a valid entity-id,-- that is, something like Q1235 or P123.-- It returns the strings "true" or "false".-- Change false to nil to return "true" or "" (easier to test with #if:).--------------------------------------------------------------------------------- Dependencies: none-------------------------------------------------------------------------------function p.checkValidity(frame) local id = mw.text.trim(frame.args[1] or "") if mw.wikibase.isValidEntityId(id) then return true else return false endend  --------------------------------------------------------------------------------- getEntityFromTitle returns the Entity-ID (Q-number) for a given title.-- Modification of Module:ResolveEntityId
-- The title is the first unnamed parameter.
-- The site parameter determines the site/language for the title. Defaults to current wiki.-- The showdab parameter determines whether dab pages should return the Q-number or nil. Defaults to true.-- Returns the Q-number or nil if it does not exist.--------------------------------------------------------------------------------- Dependencies: parseParam-------------------------------------------------------------------------------function p.getEntityFromTitle(frame) local args=frame.args if not args[1] then args=frame:getParent().args end if not args[1] then return nil end local title = mw.text.trim(args[1]) local site = args.site or "" local showdab = parseParam(args.showdab, true) local qid = mw.wikibase.getEntityIdForTitle(title, site) if qid then local prop31 = mw.wikibase.getBestStatements(qid, "P31")[1] if not showdab and prop31 and prop31.mainsnak.datavalue.value.id == "Q4167410" then return nil else return qid end endend  --------------------------------------------------------------------------------- getDatePrecision returns the number representing the precision of the first best date value-- for the given property.-- It takes the qid and property ID-- The meanings are given at https://www.mediawiki.org/wiki/Wikibase/DataModel#Dates_and_times-- 0 = 1 billion years .. 6 = millennium, 7 = century, 8 = decade, 9 = year, 10 = month, 11 = day-- Returns 0 (or the second unnamed parameter) if the Wikidata does not exist.--------------------------------------------------------------------------------- Dependencies: parseParam; sourced;-------------------------------------------------------------------------------function p.getDatePrecision(frame) local args=frame.args if not args[1] then args=frame:getParent().args end local default = tonumber(args[2] or args.default) or 0 local prop = mw.text.trim(args[1] or "") if prop == "" then return default end local qid = args.qid or "" if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage() end if not qid then return default end local onlysrc = parseParam(args.onlysourced or args.osd, true) local stat = mw.wikibase.getBestStatements(qid, prop) for i, v in ipairs(stat) do local prec = (onlysrc == false or sourced(v)) and v.mainsnak.datavalue and v.mainsnak.datavalue.value and v.mainsnak.datavalue.value.precision if prec then return prec end
end
end --------------------------------------------------------------------------------- getDatePrecision returns the number representing the precision of the first best date value-- for the given property.-- It takes the qid and property ID-- The meanings are given at https://www.mediawiki.org/wiki/Wikibase/DataModel#Dates_and_times-- 0 = 1 billion years .. 6 = millennium, 7 = century, 8 = decade, 9 = year, 10 = month, 11 = day-- Returns nil if it does not exist.--------------------------------------------------------------------------------- Dependencies: parseParam-------------------------------------------------------------------------------function p.getDatePrecision(frame) local args=frame.args if not args[1] then args=frame:getParent().args end local prop = mw.text.trim(args[1] or "") if prop == "" then return nil end local qid = args.qid or "" if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage() end local stat = mw.wikibase.getBestStatements(qid, prop)[1] if not stat then return nil end local prec = stat.mainsnak.datavalue and stat.mainsnak.datavalue.value and stat.mainsnak.datavalue.value.precision return precdefault
end
getValueByRefSource
getPropertyIDs
getQualifierIDs
getPropOfProp
getAwardCat
getLink
getLabel
label
getAT
getDescription
Anonymous user