Line 1: |
Line 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 |
Line 13: |
Line 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:Complex date is loaded lazily and has the following dependencies: |
− | -- Module:I18n/complex date, Module:ISOdate, Module:DateI18n (alternative for Module:Date), | + | -- Module:Calendar |
− | -- Module:Formatnum, Module:I18n/date, Module:Yesno, Module:Linguistic, Module:Calendar | + | -- 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. |
Line 564: |
Line 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, lprefix, lpostfix, prefix, postfix, dtxt, shortname, lang) | + | 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 |
− | if v.mainsnak.datavalue and formats[v.mainsnak.datavalue.value.id] then
| + | for k, v in ipairs( mw.wikibase.getBestStatements(id, "P31") ) do |
− | fmt = formats[v.mainsnak.datavalue.value.id]
| + | if v.mainsnak.datavalue and formats[v.mainsnak.datavalue.value.id] then |
− | break -- pick the first match
| + | fmt = formats[v.mainsnak.datavalue.value.id] |
| + | break -- pick the first match |
| + | end |
| end | | end |
| end | | end |
Line 605: |
Line 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 |
− | local pos = sitelink:find(":") or 0
| + | if sitelink:lower() ~= label:lower() then |
− | local slink = sitelink
| + | -- strip any namespace or dab from the sitelink |
− | if pos > 0 then
| + | local pos = sitelink:find(":") or 0 |
− | local prefix = sitelink:sub(1,pos-1)
| + | local slink = sitelink |
− | if mw.site.namespaces[prefix] then -- that prefix is a valid namespace, so remove it
| + | if pos > 0 then |
− | slink = sitelink:sub(pos+1)
| + | 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
| |
− | -- 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 | | end |
Line 629: |
Line 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 |
− | if not donotlink[label] and artitle and artitle.redirectTarget then
| + | disp = prefix .. fmt .. label .. fmt .. postfix |
− | -- there's a redirect with the same title as the label, so let's link to that
| + | if linkredir then |
− | disp = "[[".. lprefix .. label .. lpostfix .. "|" .. prefix .. fmt .. label .. fmt .. postfix .. "]]"
| + | local artitle = mw.title.new(label, 0) -- only nil if label has invalid chars |
− | else
| + | if not donotlink[label] and artitle and artitle.redirectTarget then |
− | -- either (donotlink is true) or (no sitelink, label exists, not redirect) | + | -- there's a redirect with the same title as the label, so let's link to that |
− | -- so output unlinked label with italics or quotes as needed
| + | disp = "[[".. lprefix .. label .. lpostfix .. "|" .. prefix .. fmt .. label .. fmt .. postfix .. "]]" |
− | disp = 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 |
Line 794: |
Line 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"] |
Line 804: |
Line 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 |
Line 814: |
Line 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 needs the entityID and propertyID to create a link in the pen icon. | + | -- It uses the entityID (and optionally propertyID) to create a link in the pen icon. |
| ------------------------------------------------------------------------------- | | ------------------------------------------------------------------------------- |
| -- Dependencies: parseParam(); | | -- Dependencies: parseParam(); |
Line 938: |
Line 972: |
| local qnumber = dv.id | | local qnumber = dv.id |
| if linked then | | if linked then |
− | val = linkedItem(qnumber, lpre, lpost, pre, post, dtxt, shortname, args.lang) | + | 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 |
Line 1,246: |
Line 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 | + | local lang = args.lang or findLang().code |
| | | |
| -- qualID is a string list of wanted qualifiers or "ALL" | | -- qualID is a string list of wanted qualifiers or "ALL" |
Line 1,374: |
Line 1,408: |
| elseif t ~= "" then | | elseif t ~= "" then |
| if qualsonly then | | if qualsonly then |
− | out[#out+1] = timestart .. dsep .. timeend | + | if timestart == "" then |
| + | out[#out+1] = timeend |
| + | elseif timeend == "" then |
| + | out[#out+1] = timestart |
| + | else |
| + | out[#out+1] = timestart .. dsep .. timeend |
| + | end |
| else | | else |
| out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" | | out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" |
Line 1,454: |
Line 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 |
| | | |
Line 1,485: |
Line 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) |
Line 1,527: |
Line 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) |
Line 1,554: |
Line 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 |
Line 1,570: |
Line 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, ":", "", "", "") -- get a linked value if we can | + | 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 |
Line 1,802: |
Line 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(); |
Line 1,810: |
Line 1,854: |
| | | |
| -- if there is a 'display' parameter supplied, use it | | -- if there is a 'display' parameter supplied, use it |
− | -- otherwise default to "inline, title" | + | -- 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 |
| | | |
Line 1,871: |
Line 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 |
Line 1,896: |
Line 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 |
− | -- 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 |
− | if quals then
| + | local quals = v1.qualifiers[qualifierID] |
− | -- can't reference qualifer, so set onlysourced = "no" (not boolean)
| + | if quals then |
− | local qargs = frame.args
| + | -- can't reference qualifer, so set onlysourced = "no" (args are strings, not boolean) |
− | qargs.onlysourced = "no"
| + | local qargs = frame.args |
− | local vals = propertyvalueandquals(quals, qargs, qid)
| + | qargs.onlysourced = "no" |
− | for k, v in ipairs(vals) do
| + | local vals = propertyvalueandquals(quals, qargs, qid) |
− | out[#out + 1] = v
| + | for k, v in ipairs(vals) do |
| + | out[#out + 1] = v |
| + | end |
| end | | end |
| end | | end |
Line 2,092: |
Line 2,146: |
| -- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput; | | -- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput; |
| ------------------------------------------------------------------------------- | | ------------------------------------------------------------------------------- |
− | p.getPropertyIDs = function(frame) | + | p._getPropertyIDs = function(args) |
− | local args = frame.args
| |
| args.reqranks = setRanks(args.rank) | | args.reqranks = setRanks(args.rank) |
| args.langobj = findLang(args.lang) | | args.langobj = findLang(args.lang) |
Line 2,110: |
Line 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 |
Line 2,124: |
Line 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 |
| | | |
Line 2,159: |
Line 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 |
Line 2,193: |
Line 2,251: |
| -- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput; | | -- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput; |
| ------------------------------------------------------------------------------- | | ------------------------------------------------------------------------------- |
− | p.getPropOfProp = function(frame) | + | p._getPropOfProp = function(args) |
− | frame.args.reqranks = setRanks(frame.args.rank) | + | -- parameter sets for commonly used groups of parameters |
− | frame.args.langobj = findLang(frame.args.lang) | + | local paraset = tonumber(args.ps or args.parameterset or 0) |
− | frame.args.lang = frame.args.langobj.code | + | if paraset == 1 then |
− | local args = frame.args
| + | -- a common setting |
− | local pid1 = args.prop1 or args.pid1 or "" | + | 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 pid2 = args.prop2 or args.pid2 or "" | | local pid2 = args.prop2 or args.pid2 or "" |
− | local localval = mw.text.trim(args[1] or "")
| |
| if pid1 == "" or pid2 == "" then return nil end | | if pid1 == "" or pid2 == "" then return nil end |
− | local qid1, statements1 = parseInput(frame, localval, pid1) | + | |
− | if not qid1 then return localval end | + | 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 |
Line 2,229: |
Line 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 |
| | | |
Line 2,409: |
Line 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 |
Line 2,493: |
Line 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 |
− | local display = mw.ustring.match( mw.uri.decode(qv, "WIKI"), "([%w ]+)$" )
| + | qv = mw.wikibase.renderSnak(vqualifiers[v1][1]) |
− | if display then
| + | local display = mw.ustring.match( mw.uri.decode(qv, "WIKI"), "([%w ]+)$" ) |
− | qv = "[" .. qv .. " " .. display .. "]"
| + | if display then |
| + | qv = "[" .. qv .. " " .. display .. "]" |
| + | end |
| end | | end |
| else | | else |
Line 2,691: |
Line 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 = mw.text.trim(args.qid or "") | + | 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 entity = mw.wikibase.getEntity(qid) | + | local aliases = mw.wikibase.getEntity(qid).aliases |
− | if not entity then return nil end
| |
− | local aliases = entity.aliases
| |
| if not aliases then return nil end | | if not aliases then return nil end |
− | if not qid then qid= mw.wikibase.getEntityIdForCurrentPage() end
| |
| | | |
| args.langobj = findLang(args.lang) | | args.langobj = findLang(args.lang) |
Line 2,901: |
Line 2,992: |
| | | |
| ------------------------------------------------------------------------------- | | ------------------------------------------------------------------------------- |
− | -- followQid takes three optional parameters: qid, props, and all. | + | -- 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. |
Line 2,907: |
Line 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, sparated by spaces. | + | -- 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.followQid = function(frame) | + | p._followQid = function(args) |
− | local qid = (frame.args.qid or ""):upper() | + | local qid = (args.qid or ""):upper() |
− | local all = parseParam(frame.args.all, false) | + | 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() |
Line 2,920: |
Line 3,014: |
| if not qid then return nil end | | if not qid then return nil end |
| local out = {} | | local out = {} |
− | local props = (frame.args.props or ""):upper() | + | 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 |
Line 2,937: |
Line 3,031: |
| end | | end |
| if #out > 0 then | | if #out > 0 then |
− | return table.concat(out, " ") | + | 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 |
| | | |
Line 3,056: |
Line 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. |
Line 3,079: |
Line 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.mainsnak.snaktype == "value" and v.mainsnak.datavalue.value.id == val then | + | 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 |
Line 3,098: |
Line 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 |
Line 3,105: |
Line 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, addr = url:match("(http[s]*://)(.+)") | + | -- extract any protocol like https:// |
− | prot = prot or url | + | local prot = url:match("(https*://).+[ \"\']") |
− | addr = addr or ""
| + | -- 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 |
Line 3,189: |
Line 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 = nil end | + | 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 entity = mw.wikibase.getEntity(qid) | |
− | if not entity then return i18n["entity-not-found"] end
| |
| | | |
− | local labels = entity.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 |
| | | |
Line 3,216: |
Line 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 = nil end | + | 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 entity = mw.wikibase.getEntity(qid) | |
− | if not entity then return i18n["entity-not-found"] end
| |
| | | |
− | local descriptions = entity.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 |
| | | |
Line 3,243: |
Line 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 = nil end | + | 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 entity = mw.wikibase.getEntity(qid) | + | local aliases = mw.wikibase.getEntity(qid).aliases |
− | if not entity then return i18n["entity-not-found"] end
| |
− | | |
− | local aliases = entity.aliases
| |
| if not aliases then return i18n["aliases-not-found"] end | | if not aliases then return i18n["aliases-not-found"] end |
| | | |
Line 3,316: |
Line 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] |
Line 3,326: |
Line 3,442: |
| end | | end |
| end | | end |
| + | |
| | | |
| ------------------------------------------------------------------------------- | | ------------------------------------------------------------------------------- |
Line 3,333: |
Line 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 nil if it does not exist. | + | -- 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 nil end | + | 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) |
Line 3,353: |
Line 3,472: |
| if prec then return prec end | | if prec then return prec end |
| end | | end |
| + | return default |
| end | | end |
| | | |