Importer, Bürokraten, Moderatoren (CommentStreams), Strukturierte-Diskussionen-Bots, Oberflächenadministratoren, Push-Abonnementverwalter, Oversighter, Administratoren, Kampagnenbearbeiter (Hochladeassistent)
855
Bearbeitungen
K (2 Versionen von skanwiki:Modul:WikidataIB importiert) |
Keine Bearbeitungszusammenfassung |
||
| Zeile 1: | Zeile 1: | ||
-- Version: 2021-02-06 | |||
-- Module to implement use of a blacklist and whitelist for infobox fields | -- 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 | -- Can take a named parameter |qid which is the Wikidata ID for the article | ||
| Zeile 13: | Zeile 14: | ||
local cdate -- initialise as nil and only load _complex_date function if needed | 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: | -- Module:Calendar | ||
-- Module: | -- Module:ISOdate | ||
-- Module:DateI18n | |||
-- Module:No globals | |||
-- Module:I18n/complex date | |||
-- Module:Ordinal | |||
-- Module:I18n/ordinal | |||
-- Module:Yesno | |||
-- Module:Formatnum | |||
-- Module:Linguistic | |||
-- | |||
-- The following, taken from https://www.mediawiki.org/wiki/Wikibase/DataModel#Dates_and_times, | -- 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. | -- is needed to use Module:Complex date which seemingly requires date precision as a string. | ||
| Zeile 564: | Zeile 574: | ||
-- shortname is boolean switch to use P1813 (short name) instead of label if true. | -- shortname is boolean switch to use P1813 (short name) instead of label if true. | ||
-- lang is the current language code. | -- 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[] | -- Dependencies: labelOrId(); donotlink[] | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
local linkedItem = function(id, | local linkedItem = function(id, args) | ||
lprefix = lprefix or "" -- toughen against nil values passed | local lprefix = (args.lp or args.lprefix or args.linkprefix or ""):gsub('"', '') -- toughen against nil values passed | ||
lpostfix = lpostfix or "" | local lpostfix = (args.lpostfix or ""):gsub('"', '') | ||
prefix = prefix or "" | local prefix = (args.prefix or ""):gsub('"', '') | ||
postfix = postfix or "" | local postfix = (args.postfix or ""):gsub('"', '') | ||
lang = lang or "en" -- fallback to default if missing | local dtxt = args.dtxt | ||
local shortname = args.shortname | |||
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 | -- see if item might need italics or quotes | ||
local fmt = "" | local fmt = "" | ||
for k, v in ipairs( mw.wikibase.getBestStatements(id, "P31") ) do | 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 | ||
end | end | ||
| Zeile 605: | Zeile 628: | ||
if sitelink then | if sitelink then | ||
if not (dtxt or shortname) then | if not (dtxt or shortname) then | ||
-- strip any namespace or dab from the sitelink | -- 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 pfx = sitelink:sub(1,pos-1) | |||
if mw.site.namespaces[pfx] 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 | ||
end | end | ||
end | end | ||
| Zeile 629: | Zeile 658: | ||
end | end | ||
elseif islabel then | elseif islabel then | ||
-- no sitelink, label exists, so check if a redirect with that title exists | -- no sitelink, label exists, so check if a redirect with that title exists, if linkredir is true | ||
local artitle = mw.title.new(label, 0) -- only nil if label has invalid chars | -- 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 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 .. "]]" | |||
end | |||
end -- test if article title exists as redirect on current Wiki | end -- test if article title exists as redirect on current Wiki | ||
else | else | ||
-- no sitelink and no label, so return whatever was returned from labelOrId for now | -- no sitelink and no label, so return whatever was returned from labelOrId for now | ||
-- add tracking category [[Category:Articles with missing Wikidata information]] | -- add tracking category [[Category:Articles with missing Wikidata information]] | ||
disp = prefix .. label .. postfix .. i18n.missinginfocat | -- 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 | end | ||
else | else | ||
| Zeile 789: | Zeile 823: | ||
-- createicon assembles the "Edit at Wikidata" pen icon. | -- createicon assembles the "Edit at Wikidata" pen icon. | ||
-- It returns a wikitext string inside a span class="penicon" | -- 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[]; | -- Dependencies: i18n[]; | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
local createicon = function(langcode, entityID, propertyID) | local createicon = function(langcode, entityID, propertyID) | ||
local icon = " <span class='penicon'>[[" | langcode = langcode or "" | ||
if not entityID or entityID == "" then entityID= mw.wikibase.getEntityIdForCurrentPage() end | |||
propertyID = propertyID or "" | |||
local icon = " <span class='penicon autoconfirmed-show'>[[" | |||
-- " <span data-bridge-edit-flow='overwrite' class='penicon'>[[" -> enable Wikidata Bridge | -- " <span data-bridge-edit-flow='overwrite' class='penicon'>[[" -> enable Wikidata Bridge | ||
.. i18n["filespace"] | .. i18n["filespace"] | ||
| Zeile 799: | Zeile 838: | ||
.. i18n["editonwikidata"] | .. i18n["editonwikidata"] | ||
.. "|link=https://www.wikidata.org/wiki/" .. entityID | .. "|link=https://www.wikidata.org/wiki/" .. entityID | ||
.. "?uselang=" .. langcode | if langcode ~= "" then icon = icon .. "?uselang=" .. langcode end | ||
if propertyID then icon = icon .. "#" .. propertyID end | if propertyID ~= "" then icon = icon .. "#" .. propertyID end | ||
icon = icon .. "|" .. i18n["editonwikidata"] .. "]]</span>" | icon = icon .. "|" .. i18n["editonwikidata"] .. "]]</span>" | ||
return icon | return icon | ||
| Zeile 809: | Zeile 848: | ||
-- assembleoutput takes the sequence table containing the property values | -- assembleoutput takes the sequence table containing the property values | ||
-- and formats it according to switches given. It returns a string or nil. | -- and formats it according to switches given. It returns a string or nil. | ||
-- It | -- It uses the entityID (and optionally propertyID) to create a link in the pen icon. | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
-- Dependencies: parseParam(); | -- Dependencies: parseParam(); | ||
| Zeile 857: | Zeile 896: | ||
if #out > 0 then | if #out > 0 then | ||
if sorted then table.sort(out) end | if sorted then table.sort(out) end | ||
-- if a pen icon is wanted add it the end of the last value | -- if there's something to display and a pen icon is wanted, add it the end of the last value | ||
if not noic then | 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) | out[#out] = out[#out] .. createicon(args.langobj.code, entityID, propertyID) | ||
end | end | ||
| Zeile 926: | Zeile 972: | ||
local qnumber = dv.id | local qnumber = dv.id | ||
if linked then | if linked then | ||
val = linkedItem(qnumber | val = linkedItem(qnumber, args) | ||
else -- no link wanted so check for display-text, otherwise test for lang code | else -- no link wanted so check for display-text, otherwise test for lang code | ||
local label, islabel | local label, islabel | ||
| Zeile 1.234: | Zeile 1.280: | ||
args.pd = pd | args.pd = pd | ||
-- allow qualifiers to have a different date format; default to year | -- allow qualifiers to have a different date format; default to year unless qualsonly is set | ||
args.qdf = args.qdf or args.qualifierdateformat or args.df or "y" | 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), | |||
} | |||
-- all proper values of a Wikidata property will be the same type as the first | -- all proper values of a Wikidata property will be the same type as the first | ||
-- qualifiers don't have a mainsnak, properties do | -- qualifiers don't have a mainsnak, properties do | ||
local datatype = objproperty[1].datatype or objproperty[1].mainsnak.datatype | |||
-- out[] holds the a list of returned values for this property | |||
-- out[] holds the values for this property | |||
-- mlt[] holds the language code if the datatype is monolingual text | -- mlt[] holds the language code if the datatype is monolingual text | ||
local out = {} | local out = {} | ||
local mlt = {} | local mlt = {} | ||
for k, v in ipairs(objproperty) do | for k, v in ipairs(objproperty) do | ||
local hasvalue = true | local hasvalue = true | ||
| Zeile 1.264: | Zeile 1.351: | ||
-- See if qualifiers are to be returned: | -- See if qualifiers are to be returned: | ||
local snak = v.mainsnak or v | local snak = v.mainsnak or v | ||
if hasvalue and v.qualifiers and qualID and snak.snaktype~="novalue" then | if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then | ||
-- collect all wanted qualifier values returned in qlist, indexed by propertyID | |||
local qlist = {} | local qlist = {} | ||
local | local timestart, timeend = "", "" | ||
-- loop through qualifiers | |||
for k1, v1 in pairs(v.qualifiers) do | |||
if allflag or qwanted[k1] then | |||
if k1 == "P1326" then | |||
local ts = v1[1].datavalue.value.time | |||
local dp = v1[1].datavalue.value.precision | |||
qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") | |||
elseif k1 == "P1319" then | |||
local ts = v1[1].datavalue.value.time | |||
local dp = v1[1].datavalue.value.precision | |||
qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") | |||
elseif k1 == "P580" then | |||
timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid | |||
elseif k1 == "P582" then | |||
timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid | |||
else | |||
local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) | |||
-- we already deal with circa via 'sourcing circumstances' if the datatype was time | |||
-- circa may be either linked or unlinked *** internationalise later *** | |||
if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then | |||
qlist[k1] = q | |||
end | |||
end | |||
end -- of test for wanted | |||
end -- of loop through qualifiers | |||
-- set date separator | |||
local t = timestart .. timeend | |||
-- *** internationalise date separators later *** | |||
local dsep = "–" | |||
if t:find("%s") or t:find(" ") then dsep = " – " 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[v2] | |||
end | |||
end | |||
if t ~= "" then | |||
qlistout[#qlistout+1] = timestart .. dsep .. timeend | |||
end | |||
local qstr = assembleoutput(qlistout, qargs) | |||
if qualsonly then | |||
out[#out+1] = qstr | |||
else | else | ||
out[#out] = out[#out] .. " (" .. qstr .. ")" | |||
end | end | ||
elseif t ~= "" then | |||
elseif | if qualsonly then | ||
if timestart == "" then | |||
out[#out+1] = timeend | |||
elseif timeend == "" then | |||
out[#out+1] = timestart | |||
else | else | ||
out[#out+1] = timestart .. dsep .. timeend | |||
end | end | ||
else | else | ||
out[#out] = out[#out] .. " (" .. | out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" | ||
end | end | ||
end | end | ||
| Zeile 1.448: | Zeile 1.494: | ||
local uabbr = parseParam(args.unitabbr or args.uabbr, false) | local uabbr = parseParam(args.unitabbr or args.uabbr, false) | ||
local filter = (args.unit or ""):upper() | local filter = (args.unit or ""):upper() | ||
local maxvals = tonumber(args.maxvals) or 0 | |||
if filter == "" then filter = nil end | if filter == "" then filter = nil end | ||
| Zeile 1.479: | Zeile 1.526: | ||
return nil | return nil | ||
end -- of check for string | end -- of check for string | ||
if maxvals > 0 and #out >= maxvals then break end | |||
end -- of loop through values of propertyID | end -- of loop through values of propertyID | ||
return assembleoutput(out, frame.args, qid, propertyID) | return assembleoutput(out, frame.args, qid, propertyID) | ||
| Zeile 1.521: | Zeile 1.569: | ||
end | end | ||
for i2, v2 in ipairs(proptbl) do | for i2, v2 in ipairs(proptbl) do | ||
parttbl = v2.qualifiers and v2.qualifiers.P518 | local parttbl = v2.qualifiers and v2.qualifiers.P518 | ||
if parttbl then | if parttbl then | ||
-- this higher location has qualifier 'applies to part' (P518) | -- this higher location has qualifier 'applies to part' (P518) | ||
| Zeile 1.548: | Zeile 1.596: | ||
end | end | ||
-- check if it's an instance of (P31) a country (Q6256) and terminate the chain if it is | -- 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") | local inst = mw.wikibase.getAllStatements(qid, "P31") | ||
if #inst > 0 then | if #inst > 0 then | ||
for k, v in ipairs(inst) do | for k, v in ipairs(inst) do | ||
local instid = v.mainsnak.datavalue.value.id | 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) | -- stop if it's a country (or a country within the United Kingdom if skip is true) | ||
if instid == "Q6256" or (skip and instid == "Q3336843") then | if instid == "Q6256" or instid == "Q3624078" or (skip and instid == "Q3336843") then | ||
prop = nil -- this will ensure this is treated as top-level location | prop = nil -- this will ensure this is treated as top-level location | ||
break | break | ||
| Zeile 1.564: | Zeile 1.613: | ||
if prop and prop.mainsnak.datavalue then | if prop and prop.mainsnak.datavalue then | ||
if not skip or count == 0 then | if not skip or count == 0 then | ||
out[#out+1] = linkedItem(qid, | local args = { lprefix = ":" } | ||
out[#out+1] = linkedItem(qid, args) -- get a linked value if we can | |||
end | end | ||
qid, prevqid = prop.mainsnak.datavalue.value.id, qid | qid, prevqid = prop.mainsnak.datavalue.value.id, qid | ||
| Zeile 1.796: | Zeile 1.846: | ||
-- getCoords is used to get coordinates for display in an infobox | -- getCoords is used to get coordinates for display in an infobox | ||
-- whitelist and blacklist are implemented | -- whitelist and blacklist are implemented | ||
-- optional 'display' parameter is allowed, defaults to "inline, title" | -- optional 'display' parameter is allowed, defaults to nil - was "inline, title" | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
-- Dependencies: setRanks(); parseInput(); decimalPrecision(); | -- Dependencies: setRanks(); parseInput(); decimalPrecision(); | ||
| Zeile 1.804: | Zeile 1.854: | ||
-- if there is a 'display' parameter supplied, use it | -- if there is a 'display' parameter supplied, use it | ||
-- otherwise default to | -- otherwise default to nothing | ||
local disp = frame.args.display or "" | local disp = frame.args.display or "" | ||
if disp == "" then | if disp == "" then | ||
disp = "inline, title" | disp = nil -- default to not supplying display parameter, was "inline, title" | ||
end | end | ||
| Zeile 1.865: | Zeile 1.915: | ||
-- whose value is to be returned is passed in named parameter |qual= | -- whose value is to be returned is passed in named parameter |qual= | ||
local qualifierID = frame.args.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 | -- onlysourced is a boolean passed to return qualifiers | ||
| Zeile 1.890: | Zeile 1.949: | ||
for k1, v1 in pairs(props) do | for k1, v1 in pairs(props) do | ||
if v1.mainsnak.snaktype == "value" and v1.mainsnak.datavalue.type == "wikibase-entityid" then | 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) | -- 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 v1.mainsnak.datavalue.value.id == propvalue and v1.qualifiers then | ||
if onlysrc == false or sourced(v1) then | if onlysrc == false or sourced(v1) then | ||
-- if we've got this far, we have a (sourced) claim with qualifiers | -- if we've got this far, we have a (sourced) claim with qualifiers | ||
-- which matches the target, so find the value(s) of the qualifier we want | -- which matches the target, so apply the filter and find the value(s) of the qualifier we want | ||
local quals = v1.qualifiers[qualifierID] | 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 | ||
end | end | ||
| Zeile 2.086: | Zeile 2.146: | ||
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput; | -- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput; | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
p. | p._getPropertyIDs = function(args) | ||
args.reqranks = setRanks(args.rank) | args.reqranks = setRanks(args.rank) | ||
args.langobj = findLang(args.lang) | args.langobj = findLang(args.lang) | ||
| Zeile 2.104: | Zeile 2.163: | ||
local maxvals = tonumber(args.maxvals) or 0 | local maxvals = tonumber(args.maxvals) or 0 | ||
out = {} | local out = {} | ||
for i, v in ipairs(props) do | for i, v in ipairs(props) do | ||
local snak = v.mainsnak | local snak = v.mainsnak | ||
| Zeile 2.118: | Zeile 2.177: | ||
return assembleoutput(out, args, qid, pid) | return assembleoutput(out, args, qid, pid) | ||
end | |||
p.getPropertyIDs = function(frame) | |||
local args = frame.args | |||
return p._getPropertyIDs(args) | |||
end | end | ||
| Zeile 2.153: | Zeile 2.217: | ||
qlist = qlist:gsub("[%p%s]+", " ") .. " " | qlist = qlist:gsub("[%p%s]+", " ") .. " " | ||
out = {} | local out = {} | ||
for i, v in ipairs(props) do | for i, v in ipairs(props) do | ||
local snak = v.mainsnak | local snak = v.mainsnak | ||
| Zeile 2.187: | Zeile 2.251: | ||
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput; | -- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput; | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
p. | p._getPropOfProp = function(args) | ||
-- parameter sets for commonly used groups of parameters | |||
local paraset = tonumber(args.ps or args.parameterset or 0) | |||
if paraset == 1 then | |||
-- a common setting | |||
args.rank = "best" | |||
args.fetchwikidata = "ALL" | |||
args.onlysourced = "no" | |||
args.noicon = "true" | |||
elseif paraset == 2 then | |||
-- equivalent to raw | |||
args.rank = "best" | |||
args.fetchwikidata = "ALL" | |||
args.onlysourced = "no" | |||
args.noicon = "true" | |||
args.linked = "no" | |||
args.pd = "true" | |||
elseif paraset == 3 then | |||
-- third set goes here | |||
end | |||
args.reqranks = setRanks(args.rank) | |||
args.langobj = findLang(args.lang) | |||
args.lang = args.langobj.code | |||
local pid1 = args.prop1 or args.pid1 or "" | local pid1 = args.prop1 or args.pid1 or "" | ||
local pid2 = args.prop2 or args.pid2 or "" | local pid2 = args.prop2 or args.pid2 or "" | ||
if pid1 == "" or pid2 == "" then return nil end | if pid1 == "" or pid2 == "" then return nil end | ||
local qid1, statements1 = parseInput( | |||
if not qid1 then return | local f = {} | ||
f.args = args | |||
local qid1, statements1 = parseInput(f, args[1], pid1) | |||
-- parseInput nulls empty args[1] and returns args[1] if nothing on Wikidata | |||
if not qid1 then return statements1 end | |||
-- otherwise it returns the qid and a table for the statement | |||
local onlysrc = parseParam(args.onlysourced or args.osd, true) | local onlysrc = parseParam(args.onlysourced or args.osd, true) | ||
local maxvals = tonumber(args.maxvals) or 0 | local maxvals = tonumber(args.maxvals) or 0 | ||
| Zeile 2.223: | Zeile 2.310: | ||
end -- of loop through values of property1 | end -- of loop through values of property1 | ||
return assembleoutput(out, args, qid1, pid1) | 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 | end | ||
| Zeile 2.403: | Zeile 2.500: | ||
if maxvals > 0 and #cat2 >= maxvals then break end | if maxvals > 0 and #cat2 >= maxvals then break end | ||
end | end | ||
out = {} | local out = {} | ||
for k1, v1 in ipairs(cat1) do | for k1, v1 in ipairs(cat1) do | ||
for k2, v2 in ipairs(cat2) do | for k2, v2 in ipairs(cat2) do | ||
| Zeile 2.487: | Zeile 2.584: | ||
end | end | ||
elseif qtype == "url" then | elseif qtype == "url" then | ||
qv = mw.wikibase.renderSnak(vqualifiers[v1][1]) | if vqualifiers[v1][1].snaktype == "value" 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 | |||
end | end | ||
else | else | ||
| Zeile 2.685: | Zeile 2.784: | ||
if not (whitelist == 'ALL' or whitelist:find(fieldname)) then return nil end | if not (whitelist == 'ALL' or whitelist:find(fieldname)) then return nil end | ||
local qid = | local qid = args.qid or "" | ||
if qid == "" then qid = nil end | if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage() end | ||
if not qid or not mw.wikibase.entityExists(qid) then return nil end | |||
local | local aliases = mw.wikibase.getEntity(qid).aliases | ||
if not aliases then return nil end | if not aliases then return nil end | ||
args.langobj = findLang(args.lang) | args.langobj = findLang(args.lang) | ||
| Zeile 2.895: | Zeile 2.992: | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
-- followQid takes | -- followQid takes four optional parameters: qid, props, list and all. | ||
-- If qid is not given, it uses the qid for the connected page | -- If qid is not given, it uses the qid for the connected page | ||
-- or returns nil if there isn't one. | -- or returns nil if there isn't one. | ||
| Zeile 2.901: | Zeile 2.998: | ||
-- If props is given, the Wikidata item for the qid is examined for each property in turn. | -- If props is given, the Wikidata item for the qid is examined for each property in turn. | ||
-- If that property contains a value that is another Wikibase-item, that item's qid is returned, | -- If that property contains a value that is another Wikibase-item, that item's qid is returned, | ||
-- and the search terminates, unless |all=y when all of the qids are returned, | -- and the search terminates, unless |all=y when all of the qids are returned, separated by spaces. | ||
-- If |list= is set to a template, the qids are passed as arguments to the template. | |||
-- If props is not given, the qid is returned. | -- If props is not given, the qid is returned. | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
-- Dependencies: parseParam() | -- Dependencies: parseParam() | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
p. | p._followQid = function(args) | ||
local qid = ( | local qid = (args.qid or ""):upper() | ||
local all = parseParam( | local all = parseParam(args.all, false) | ||
local list = args.list or "" | |||
if list == "" then list = nil end | |||
if qid == "" then | if qid == "" then | ||
qid = mw.wikibase.getEntityIdForCurrentPage() | qid = mw.wikibase.getEntityIdForCurrentPage() | ||
| Zeile 2.914: | Zeile 3.014: | ||
if not qid then return nil end | if not qid then return nil end | ||
local out = {} | local out = {} | ||
local props = ( | local props = (args.props or ""):upper() | ||
if props ~= "" then | if props ~= "" then | ||
for p in mw.text.gsplit(props, "%p") do -- split at punctuation and iterate | for p in mw.text.gsplit(props, "%p") do -- split at punctuation and iterate | ||
| Zeile 2.931: | Zeile 3.031: | ||
end | end | ||
if #out > 0 then | if #out > 0 then | ||
local ret = "" | |||
if list then | |||
ret = mw.getCurrentFrame():expandTemplate{title = list, args = out} | |||
else | |||
ret = table.concat(out, " ") | |||
end | |||
return ret | |||
else | else | ||
return qid | return qid | ||
end | end | ||
end | |||
p.followQid = function(frame) | |||
return p._followQid(frame.args) | |||
end | end | ||
| Zeile 3.050: | Zeile 3.160: | ||
-- from the item given by the parameter 'qid' | -- from the item given by the parameter 'qid' | ||
-- or from the Wikidata item associated with the current page if qid is not supplied. | -- 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. | -- If property is not supplied, then P31 (instance of) is assumed. | ||
-- It returns val if found or nothing if not found. | -- It returns val if found or nothing if not found. | ||
| Zeile 3.073: | Zeile 3.184: | ||
if qid:sub(1,1) ~= "Q" then qid = mw.wikibase.getEntityIdForCurrentPage() end | if qid:sub(1,1) ~= "Q" then qid = mw.wikibase.getEntityIdForCurrentPage() end | ||
if not qid then return nil end | if not qid then return nil end | ||
local stats = mw.wikibase.getAllStatements( qid, pid ) | 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 not stats[1] then return nil end | ||
if stats[1].mainsnak.datatype == "wikibase-item" then | if stats[1].mainsnak.datatype == "wikibase-item" then | ||
for k, v in pairs( stats ) do | for k, v in pairs( stats ) do | ||
if v. | local ms = v.mainsnak | ||
if ranks[v.rank:sub(1,1)] and ms.snaktype == "value" and ms.datavalue.value.id == val then | |||
return val | return val | ||
end | end | ||
| Zeile 3.092: | Zeile 3.210: | ||
-- but it keeps the "edit at Wikidata" pen icon out of the microformat. | -- 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: | -- 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}} | -- e.g. {{#invoke:WikidataIB |url2 |url={{wdib |P856 |qid=Q23317 |fwd=ALL |osd=no}} }} | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
-- Dependencies: none | -- Dependencies: none | ||
| Zeile 3.099: | Zeile 3.217: | ||
local txt = frame.args.url or "" | local txt = frame.args.url or "" | ||
if txt == "" then return nil end | if txt == "" then return nil end | ||
-- extract any icon | |||
local url, icon = txt:match("(.+) (.+)") | local url, icon = txt:match("(.+) (.+)") | ||
url = url or txt | -- make sure there's at least a space at the end | ||
url = (url or txt) .. " " | |||
icon = icon or "" | icon = icon or "" | ||
local prot | -- extract any protocol like https:// | ||
prot = | local prot = url:match("(https*://).+[ \"\']") | ||
-- extract address | |||
local disp, n = addr:gsub("%.", "<wbr/> | local addr = "" | ||
if prot then | |||
addr = url:match("https*://(.+)[ \"\']") or " " | |||
else | |||
prot = "//" | |||
addr = url:match("[^%p%s]+%.(.+)[ \"\']") 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 '<span class="url">[' .. prot .. addr .. " " .. disp .. "]</span> " .. icon | return '<span class="url">[' .. prot .. addr .. " " .. disp .. "]</span> " .. icon | ||
end | end | ||
| Zeile 3.183: | Zeile 3.311: | ||
local args = frame.args or frame:getParent().args or {} | local args = frame.args or frame:getParent().args or {} | ||
local qid = args.qid | local qid = args.qid or "" | ||
if qid == "" then qid = | 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 = | local labels = mw.wikibase.getEntity(qid).labels | ||
if not labels then return i18n["labels-not-found"] end | if not labels then return i18n["labels-not-found"] end | ||
| Zeile 3.210: | Zeile 3.336: | ||
local args = frame.args or frame:getParent().args or {} | local args = frame.args or frame:getParent().args or {} | ||
local qid = args.qid | local qid = args.qid or "" | ||
if qid == "" then qid = | 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 descriptions = | local descriptions = mw.wikibase.getEntity(qid).descriptions | ||
if not descriptions then return i18n["descriptions-not-found"] end | if not descriptions then return i18n["descriptions-not-found"] end | ||
| Zeile 3.237: | Zeile 3.361: | ||
local args = frame.args or frame:getParent().args or {} | local args = frame.args or frame:getParent().args or {} | ||
local qid = args.qid | local qid = args.qid or "" | ||
if qid == "" then qid = | 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 = | local aliases = mw.wikibase.getEntity(qid).aliases | ||
if not aliases then return i18n["aliases-not-found"] end | if not aliases then return i18n["aliases-not-found"] end | ||
| Zeile 3.310: | Zeile 3.432: | ||
local site = args.site or "" | local site = args.site or "" | ||
local showdab = parseParam(args.showdab, true) | local showdab = parseParam(args.showdab, true) | ||
qid = mw.wikibase.getEntityIdForTitle(title, site) | local qid = mw.wikibase.getEntityIdForTitle(title, site) | ||
if qid then | if qid then | ||
local prop31 = mw.wikibase.getBestStatements(qid, "P31")[1] | local prop31 = mw.wikibase.getBestStatements(qid, "P31")[1] | ||
| Zeile 3.320: | Zeile 3.442: | ||
end | end | ||
end | end | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
| Zeile 3.327: | Zeile 3.450: | ||
-- The meanings are given at https://www.mediawiki.org/wiki/Wikibase/DataModel#Dates_and_times | -- 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 | -- 0 = 1 billion years .. 6 = millennium, 7 = century, 8 = decade, 9 = year, 10 = month, 11 = day | ||
-- Returns | -- Returns 0 (or the second unnamed parameter) if the Wikidata does not exist. | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
-- Dependencies: parseParam | -- Dependencies: parseParam; sourced; | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
function p.getDatePrecision(frame) | function p.getDatePrecision(frame) | ||
local args=frame.args | local args=frame.args | ||
if not args[1] then args=frame:getParent().args end | 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 "") | local prop = mw.text.trim(args[1] or "") | ||
if prop == "" then return | if prop == "" then return default end | ||
local qid = args.qid or "" | local qid = args.qid or "" | ||
if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage() end | 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 onlysrc = parseParam(args.onlysourced or args.osd, true) | ||
local stat = mw.wikibase.getBestStatements(qid, prop) | local stat = mw.wikibase.getBestStatements(qid, prop) | ||
| Zeile 3.347: | Zeile 3.472: | ||
if prec then return prec end | if prec then return prec end | ||
end | end | ||
return default | |||
end | end | ||