| Line 113: |
Line 113: |
| | ------------------------------------------------------------------------------- | | ------------------------------------------------------------------------------- |
| | -- makeOrdinal needs to be internationalised along with the above: | | -- makeOrdinal needs to be internationalised along with the above: |
| − | -- takes cardinal numer as a numeric and returns the ordinal as a string | + | -- takes cardinal number as a numeric and returns the ordinal as a string |
| | -- we need three exceptions in English for 1st, 2nd, 3rd, 21st, .. 31st, etc. | | -- we need three exceptions in English for 1st, 2nd, 3rd, 21st, .. 31st, etc. |
| | ------------------------------------------------------------------------------- | | ------------------------------------------------------------------------------- |
| Line 328: |
Line 328: |
| | -- dateFormat is the handler for properties that are of type "time" | | -- 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), | | -- 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 cirumstances"/use adjectival form, | + | -- a plaindate switch (yes/no/adj) to en/disable "sourcing circumstances"/use adjectival form, |
| | -- any qualifiers for the property, the language, and any adjective to use like 'before'. | | -- any qualifiers for the property, the language, and any adjective to use like 'before'. |
| | -- It passes the date through the "complex date" function | | -- It passes the date through the "complex date" function |
| Line 338: |
Line 338: |
| | -- output formatting according to preferences (y/dmy/mdy/ymd) | | -- output formatting according to preferences (y/dmy/mdy/ymd) |
| | df = (df or ""):lower() | | df = (df or ""):lower() |
| − | -- if ymd is required, just return the part of the timestamp in YYYY-MM-DD form | + | -- if ymd is required, return the part of the timestamp in YYYY-MM-DD form |
| − | if df == "ymd" then return timestamp:sub(2,11) end | + | -- 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", | | -- 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", | | -- which is processed here as if it were the day before "+1872-01-01T00:00:00Z", |
| Line 385: |
Line 395: |
| | -- no point in saying that dates before 1582 are Julian - they are by default | | -- no point in saying that dates before 1582 are Julian - they are by default |
| | -- doesn't make sense for dates less precise than year | | -- doesn't make sense for dates less precise than year |
| − | -- we can supress it by setting |plaindate, e.g. for use in constructing categories. | + | -- we can suppress it by setting |plaindate, e.g. for use in constructing categories. |
| | local calendarmodel = "" | | local calendarmodel = "" |
| | if tonumber(year) > 1582 | | if tonumber(year) > 1582 |
| Line 465: |
Line 475: |
| | local sitelink | | local sitelink |
| | if wiki == "" then | | if wiki == "" then |
| − | sitelink = mw.wikibase.sitelink(qid) | + | sitelink = mw.wikibase.getSitelink(qid) |
| | else | | else |
| − | sitelink = mw.wikibase.sitelink(qid, wiki) | + | sitelink = mw.wikibase.getSitelink(qid, wiki) |
| | end | | end |
| | return sitelink | | return sitelink |
| Line 533: |
Line 543: |
| | label = mw.wikibase.getLabelByLang(id, lang) | | label = mw.wikibase.getLabelByLang(id, lang) |
| | else | | else |
| − | label = mw.wikibase.label(id) | + | label = mw.wikibase.getLabel(id) |
| | end | | end |
| | if label then | | if label then |
| Line 572: |
Line 582: |
| | end | | end |
| | local disp | | local disp |
| − | local sitelink = mw.wikibase.sitelink(id) | + | local sitelink = mw.wikibase.getSitelink(id) |
| | local label, islabel | | local label, islabel |
| | if dtxt then | | if dtxt then |
| Line 620: |
Line 630: |
| | 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 |
| − | local artitle = mw.title.new(label, 0) | + | local artitle = mw.title.new(label, 0) -- only nil if label has invalid chars |
| − | if artitle and artitle.redirectTarget and not donotlink[label] then | + | 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 | | -- 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 .. "]]" | | disp = "[[".. lprefix .. label .. lpostfix .. "|" .. prefix .. fmt .. label .. fmt .. postfix .. "]]" |
| | else | | else |
| − | -- no sitelink, label exists, not redirect (or donotlink) so output plain label | + | -- either (donotlink is true) or (no sitelink, label exists, not redirect) |
| | + | -- so output unlinked label with italics or quotes as needed |
| | disp = prefix .. fmt .. label .. fmt .. postfix | | disp = prefix .. fmt .. label .. fmt .. postfix |
| | end -- test if article title exists as redirect on current Wiki | | end -- test if article title exists as redirect on current Wiki |
| Line 631: |
Line 642: |
| | -- 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 |
| Line 652: |
Line 668: |
| | ------------------------------------------------------------------------------- | | ------------------------------------------------------------------------------- |
| | -- sourced takes a table representing a statement that may or may not have references | | -- sourced takes a table representing a statement that may or may not have references |
| − | -- it counts how many references are sourced to something not containing the word "wikipedia" | + | -- it looks for a reference sourced to something not containing the word "wikipedia" |
| − | -- it returns a boolean = true if there are any sourced references. | + | -- it returns a boolean = true if it finds a sourced reference. |
| | ------------------------------------------------------------------------------- | | ------------------------------------------------------------------------------- |
| | -- Dependencies: none | | -- Dependencies: none |
| Line 661: |
Line 677: |
| | for kr, vr in pairs(claim.references) do | | for kr, vr in pairs(claim.references) do |
| | local ref = mw.wikibase.renderSnaks(vr.snaks) | | local ref = mw.wikibase.renderSnaks(vr.snaks) |
| − | if not ref:find("Wikipedia") then | + | if not ref:find("Wiki") then |
| | return true | | return true |
| | end | | end |
| Line 713: |
Line 729: |
| | input_parm = mw.text.trim(input_parm or "") | | input_parm = mw.text.trim(input_parm or "") |
| | if input_parm == "" then input_parm = nil end | | 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 | | local args = frame.args |
| Line 719: |
Line 738: |
| | -- if it's not supplied, use the id for the current page | | -- if it's not supplied, use the id for the current page |
| | 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 there's no Wikidata item for the current page return nil | | -- if there's no Wikidata item for the current page return nil |
| | if not qid then return false, input_parm end | | if not qid then return false, input_parm end |
| | | | |
| | -- The blacklist is passed in named parameter |suppressfields | | -- The blacklist is passed in named parameter |suppressfields |
| − | local blacklist = args.suppressfields or args.spf | + | local blacklist = args.suppressfields or args.spf or "" |
| | | | |
| | -- The whitelist is passed in named parameter |fetchwikidata | | -- The whitelist is passed in named parameter |fetchwikidata |
| − | local whitelist = args.fetchwikidata or args.fwd | + | local whitelist = args.fetchwikidata or args.fwd or "" |
| − | if not whitelist or whitelist == "" then whitelist = "NONE" end | + | if whitelist == "" then whitelist = "NONE" end |
| | | | |
| | -- The name of the field that this function is called from is passed in named parameter |name | | -- The name of the field that this function is called from is passed in named parameter |name |
| | local fieldname = args.name or "" | | local fieldname = args.name or "" |
| | | | |
| − | if blacklist then | + | if blacklist ~= "" then |
| | -- The name is compulsory when blacklist is used, so return nil if it is not supplied | | -- 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 fieldname == "" then return false, nil end |
| | -- If this field is on the blacklist, then return nil | | -- If this field is on the blacklist, then return nil |
| | if blacklist:find(fieldname) then return false, nil end | | if blacklist:find(fieldname) then return false, nil end |
| Line 760: |
Line 779: |
| | local props = {} | | local props = {} |
| | if args.reqranks.b then | | if args.reqranks.b then |
| − | -- props = mw.wikibase.getBestStatements(qid, property_id) | + | props = mw.wikibase.getBestStatements(qid, property_id) |
| | else | | else |
| − | -- props = mw.wikibase.getAllStatements(qid, property_id) | + | props = mw.wikibase.getAllStatements(qid, property_id) |
| | end | | end |
| | if props[1] then | | if props[1] then |
| Line 832: |
Line 851: |
| | -- Zero or not a number result in no collapsing (default becomes 0). | | -- Zero or not a number result in no collapsing (default becomes 0). |
| | local collapse = tonumber(args.collapse) or 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 there's anything to return, then return a list |
| Line 839: |
Line 862: |
| | 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 |
| Line 856: |
Line 886: |
| | strout = nil -- no items had valid reference | | strout = nil -- no items had valid reference |
| | end | | end |
| | + | if replacetext ~= "" and strout then strout = replacetext end |
| | return strout | | return strout |
| | end | | end |
| Line 1,047: |
Line 1,078: |
| | if uabbr then | | if uabbr then |
| | -- see if there's a unit symbol (P5061) | | -- see if there's a unit symbol (P5061) |
| − | local unitsymbols = mw.wikibase.getAllStatements(unitqid, "P5061") | + | local unitsymbols = mw.wikibase.getBestStatements(unitqid, "P5061") |
| − | -- construct fallback table | + | -- construct fallback table, add local lang and multiple languages |
| | local fbtbl = mw.language.getFallbacksFor( args.lang ) | | local fbtbl = mw.language.getFallbacksFor( args.lang ) |
| | table.insert( fbtbl, 1, args.lang ) | | table.insert( fbtbl, 1, args.lang ) |
| | + | table.insert( fbtbl, 1, "mul" ) |
| | local found = false | | local found = false |
| | for idx1, us in ipairs(unitsymbols) do | | for idx1, us in ipairs(unitsymbols) do |
| Line 1,218: |
Line 1,250: |
| | | | |
| | 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 = 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 |
| | | | |
| − | 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 |
| Line 1,244: |
Line 1,317: |
| | -- 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 |
| − | local qsep = (args.qsep or ""):gsub('"', '')
| + | -- collect all wanted qualifier values returned in qlist, indexed by propertyID |
| − | 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
| |
| − | }
| |
| | local qlist = {} | | local qlist = {} |
| − | local t1, t2 = "", "" | + | local timestart, timeend = "", "" |
| − | -- see if we want all qualifiers
| + | -- loop through qualifiers |
| − | if qualID == "ALL" then
| + | for k1, v1 in pairs(v.qualifiers) do |
| − | if v["qualifiers-order"] then
| + | if allflag or qwanted[k1] then |
| − | -- the values in the order table are the keys for the qualifiers table:
| + | if k1 == "P1326" then |
| − | for k1, v1 in ipairs(v["qualifiers-order"]) do
| + | local ts = v1[1].datavalue.value.time |
| − | if v1 == "P1326" then
| + | local dp = v1[1].datavalue.value.precision |
| − | local ts = v.qualifiers[v1][1].datavalue.value.time
| + | qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") |
| − | local dp = v.qualifiers[v1][1].datavalue.value.precision
| + | elseif k1 == "P1319" then |
| − | qlist[#qlist + 1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before")
| + | local ts = v1[1].datavalue.value.time |
| − | elseif v1 == "P1319" then
| + | local dp = v1[1].datavalue.value.precision |
| − | local ts = v.qualifiers[v1][1].datavalue.value.time
| + | qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") |
| − | local dp = v.qualifiers[v1][1].datavalue.value.precision
| + | elseif k1 == "P580" then |
| − | qlist[#qlist + 1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after")
| + | timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid |
| − | else
| + | elseif k1 == "P582" then |
| − | local q = assembleoutput(propertyvalueandquals(v.qualifiers[v1], qargs), qargs)
| + | timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid |
| − | -- we already deal with circa via 'sourcing circumstances'
| + | else |
| − | -- either linked or unlinked *** internationalise later ***
| + | local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) |
| − | if q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then
| + | -- we already deal with circa via 'sourcing circumstances' if the datatype was time |
| − | qlist[#qlist + 1] = q
| + | -- circa may be either linked or unlinked *** internationalise later *** |
| − | end
| + | if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then |
| − | end
| + | qlist[k1] = q |
| − | end | + | 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 |
| − | -- are there cases where qualifiers-order doesn't exist? | + | out[#out] = out[#out] .. " (" .. qstr .. ")" |
| − | local ql = propertyvalueandquals(v.qualifiers, qargs)
| |
| − | for k1, v1 in ipairs(ql) do
| |
| − | -- we already deal with circa via 'sourcing circumstances'
| |
| − | -- either linked or unlinked *** internationalise later ***
| |
| − | if v1 ~= "circa" and not (type(v1) == "string" and v1:find("circa]]")) then
| |
| − | qlist[#qlist + 1] = v1
| |
| − | end
| |
| − | end
| |
| | end | | end |
| − | -- see if we want date/range
| + | elseif t ~= "" then |
| − | elseif qualID == "DATES" then | + | if qualsonly then |
| − | qargs.maxvals = 1
| + | out[#out+1] = timestart .. dsep .. timeend |
| − | for k1, v1 in pairs(v.qualifiers) do
| + | else |
| − | if k1 == "P580" then -- P580 is "start time"
| + | out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" |
| − | 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)
| |
| − | for k2, v2 in ipairs(ql) do
| |
| − | qlist[#qlist + 1] = v2
| |
| − | end
| |
| − | end
| |
| − | end
| |
| − | end
| |
| − | end -- of loop through list of qualifiers in qualID
| |
| − | end -- of testing for what qualID is
| |
| − | local t = t1 .. t2
| |
| − | -- *** internationalise date separators later ***
| |
| − | local dsep = "–"
| |
| − | if t:find("%s") or t:find(" ") then dsep = " – " end
| |
| − | if #qlist > 0 then
| |
| − | local qstr = assembleoutput(qlist, qargs)
| |
| − | if qualsonly then
| |
| − | out[#out+1] = qstr
| |
| − | else
| |
| − | out[#out] = out[#out] .. " (" .. qstr .. ")"
| |
| − | end
| |
| − | elseif t > "" then
| |
| − | if qualsonly then | |
| − | out[#out+1] = t1 .. dsep .. t2 | |
| − | else | |
| − | out[#out] = out[#out] .. " (" .. t1 .. dsep .. t2 .. ")" | |
| | end | | end |
| | end | | end |
| Line 1,585: |
Line 1,612: |
| | until finished or count >= 10 -- limit to 10 levels to avoid infinite loops | | until finished or count >= 10 -- limit to 10 levels to avoid infinite loops |
| | | | |
| − | -- remove the first location if not quired | + | -- remove the first location if not required |
| | if not first then table.remove(out, 1) end | | if not first then table.remove(out, 1) end |
| | | | |
| Line 1,701: |
Line 1,728: |
| | | | |
| | args.reqranks = setRanks(args.rank) | | 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 = {} | | local f = {} |
| Line 2,067: |
Line 2,101: |
| | local f = {} | | local f = {} |
| | f.args = args | | f.args = args |
| − | local pid = mw.text.trim(args[1] or "") | + | 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 | | -- get the qid and table of claims for the property, or nothing and the local value passed |
| Line 2,088: |
Line 2,122: |
| | if maxvals > 0 and #out >= maxvals then break end | | if maxvals > 0 and #out >= maxvals then break end |
| | end | | end |
| | + | |
| | + | return assembleoutput(out, args, qid, pid) |
| | + | end |
| | + | |
| | + | |
| | + | ------------------------------------------------------------------------------- |
| | + | -- getQualifierIDs takes most of the usual parameters. |
| | + | -- The usual whitelisting, blacklisting, onlysourced, etc. are implemented. |
| | + | -- It takes a property-id as the first unnamed parameter, and an optional parameter qlist |
| | + | -- which is a list of qualifier property-ids to search for (default is "ALL") |
| | + | -- It returns the Entity-IDs (Qids) of the values of a property if it is a Wikibase-Entity. |
| | + | -- Otherwise it returns nothing. |
| | + | ------------------------------------------------------------------------------- |
| | + | -- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput; |
| | + | ------------------------------------------------------------------------------- |
| | + | p.getQualifierIDs = function(frame) |
| | + | local args = frame.args |
| | + | args.reqranks = setRanks(args.rank) |
| | + | args.langobj = findLang(args.lang) |
| | + | args.lang = args.langobj.code |
| | + | -- change default for noicon to true |
| | + | args.noicon = tostring(parseParam(args.noicon or "", true)) |
| | + | 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 qid, props = parseInput(f, args[2], pid) |
| | + | if not qid then return 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 qlist = args.qlist or "" |
| | + | if qlist == "" then qlist = "ALL" end |
| | + | qlist = qlist:gsub("[%p%s]+", " ") .. " " |
| | + | |
| | + | out = {} |
| | + | for i, v in ipairs(props) do |
| | + | local snak = v.mainsnak |
| | + | if ( v.rank and args.reqranks[v.rank:sub(1, 1)] ) |
| | + | and ( snak.snaktype == "value" ) |
| | + | and ( sourced(v) or not onlysrc ) |
| | + | then |
| | + | if v.qualifiers then |
| | + | for k1, v1 in pairs(v.qualifiers) do |
| | + | if qlist == "ALL " or qlist:match(k1 .. " ") then |
| | + | for i2, v2 in ipairs(v1) do |
| | + | if v2.datatype == "wikibase-item" and v2.snaktype == "value" then |
| | + | out[#out+1] = 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 qualifiers |
| | + | 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 |
| | | | |
| | return assembleoutput(out, args, qid, pid) | | return assembleoutput(out, args, qid, pid) |
| Line 2,172: |
Line 2,264: |
| | local p734 = mw.wikibase.getBestStatements(qid1, "P734")[1] | | local p734 = mw.wikibase.getBestStatements(qid1, "P734")[1] |
| | local p734id = p734 and p734.mainsnak.snaktype == "value" and p734.mainsnak.datavalue.value.id or "" | | local p734id = p734 and p734.mainsnak.snaktype == "value" and p734.mainsnak.datavalue.value.id or "" |
| − | famname = mw.wikibase.sitelink(p734id) or "" | + | famname = mw.wikibase.getSitelink(p734id) or "" |
| | -- strip namespace and disambigation | | -- strip namespace and disambigation |
| | local pos = famname:find(":") or 0 | | local pos = famname:find(":") or 0 |
| | famname = famname:sub(pos+1):gsub("%s%(.+%)$", "") | | famname = famname:sub(pos+1):gsub("%s%(.+%)$", "") |
| | if famname == "" then | | if famname == "" then |
| − | local lbl = mw.wikibase.label(p734id) | + | local lbl = mw.wikibase.getLabel(p734id) |
| | famname = lbl and mw.text.nowiki(lbl) or "" | | famname = lbl and mw.text.nowiki(lbl) or "" |
| | end | | end |
| Line 2,199: |
Line 2,291: |
| | if statements2[1] and statements2[1].mainsnak.snaktype == "value" then | | if statements2[1] and statements2[1].mainsnak.snaktype == "value" then |
| | local qid3 = statements2[1].mainsnak.datavalue.value.id | | local qid3 = statements2[1].mainsnak.datavalue.value.id |
| − | local sitelink = mw.wikibase.sitelink(qid3) | + | local sitelink = mw.wikibase.getSitelink(qid3) |
| | -- if there's no local sitelink, create the sitelink from English label | | -- if there's no local sitelink, create the sitelink from English label |
| | if not sitelink then | | if not sitelink then |
| Line 2,271: |
Line 2,363: |
| | local p734 = mw.wikibase.getBestStatements(qid, "P734")[1] | | local p734 = mw.wikibase.getBestStatements(qid, "P734")[1] |
| | local p734id = p734 and p734.mainsnak.snaktype == "value" and p734.mainsnak.datavalue.value.id or "" | | local p734id = p734 and p734.mainsnak.snaktype == "value" and p734.mainsnak.datavalue.value.id or "" |
| − | famname = mw.wikibase.sitelink(p734id) or "" | + | famname = mw.wikibase.getSitelink(p734id) or "" |
| | -- strip namespace and disambigation | | -- strip namespace and disambigation |
| | local pos = famname:find(":") or 0 | | local pos = famname:find(":") or 0 |
| | famname = famname:sub(pos+1):gsub("%s%(.+%)$", "") | | famname = famname:sub(pos+1):gsub("%s%(.+%)$", "") |
| | if famname == "" then | | if famname == "" then |
| − | local lbl = mw.wikibase.label(p734id) | + | local lbl = mw.wikibase.getLabel(p734id) |
| | famname = lbl and mw.text.nowiki(lbl) or "" | | famname = lbl and mw.text.nowiki(lbl) or "" |
| | end | | end |
| Line 2,291: |
Line 2,383: |
| | local tmcID = p910.mainsnak.datavalue.value.id | | local tmcID = p910.mainsnak.datavalue.value.id |
| | -- use sitelink or the English label for the cat | | -- use sitelink or the English label for the cat |
| − | local cat = mw.wikibase.sitelink(tmcID) | + | local cat = mw.wikibase.getSitelink(tmcID) |
| | if not cat then | | if not cat then |
| | local lbl = mw.wikibase.getLabelByLang(tmcID, "en") | | local lbl = mw.wikibase.getLabelByLang(tmcID, "en") |
| Line 2,487: |
Line 2,579: |
| | local itemID = mw.text.trim(frame.args[1] or frame.args.qid or "") | | local itemID = mw.text.trim(frame.args[1] or frame.args.qid or "") |
| | if itemID == "" then return end | | if itemID == "" then return end |
| − | local sitelink = mw.wikibase.sitelink(itemID) | + | local sitelink = mw.wikibase.getSitelink(itemID) |
| | local label = labelOrId(itemID) | | local label = labelOrId(itemID) |
| | if sitelink then | | if sitelink then |
| Line 2,511: |
Line 2,603: |
| | local label = labelOrId(itemID, lang) | | local label = labelOrId(itemID, lang) |
| | return label | | return label |
| | + | end |
| | + | |
| | + | |
| | + | ------------------------------------------------------------------------------- |
| | + | -- label has the qid of a Wikidata entity passed as the first unnamed parameter or as |qid= |
| | + | -- if no qid is 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 local language, it returns nil. |
| | + | ------------------------------------------------------------------------------- |
| | + | -- Dependencies: none |
| | + | ------------------------------------------------------------------------------- |
| | + | p.label = function(frame) |
| | + | local qid = mw.text.trim(frame.args[1] or frame.args.qid or "") |
| | + | if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage() end |
| | + | if not qid then return end |
| | + | local lang = frame.args.lang or "" |
| | + | if lang == "" then lang = nil end |
| | + | local label, success = labelOrId(qid, lang) |
| | + | if success then return label end |
| | end | | end |
| | | | |
| Line 2,518: |
Line 2,629: |
| | -- has the qid of a Wikidata entity passed as the first unnamed parameter or as |qid= | | -- 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 the sitelink as plain text. | | -- If there is a sitelink to an article on the local Wiki, it returns the sitelink as plain text. |
| − | -- If there is no sitelink, it returns nothing. | + | -- If there is no sitelink or qid supplied, it returns nothing. |
| | ------------------------------------------------------------------------------- | | ------------------------------------------------------------------------------- |
| | -- Dependencies: none | | -- Dependencies: none |
| Line 2,525: |
Line 2,636: |
| | local itemID = mw.text.trim(frame.args[1] or frame.args.qid or "") | | local itemID = mw.text.trim(frame.args[1] or frame.args.qid or "") |
| | if itemID == "" then return end | | if itemID == "" then return end |
| − | return mw.wikibase.sitelink(itemID) | + | return mw.wikibase.getSitelink(itemID) |
| | end | | end |
| | | | |
| Line 2,544: |
Line 2,655: |
| | if itemID == "" then itemID = nil end | | if itemID == "" then itemID = nil end |
| | if desc:lower() == 'wikidata' then | | if desc:lower() == 'wikidata' then |
| − | return mw.wikibase.description(itemID) | + | return mw.wikibase.getDescription(itemID) |
| | elseif desc:lower() == 'none' then | | elseif desc:lower() == 'none' then |
| | return nil | | return nil |
| Line 2,715: |
Line 2,826: |
| | ------------------------------------------------------------------------------- | | ------------------------------------------------------------------------------- |
| | p.labelorid = function(frame) | | p.labelorid = function(frame) |
| − | return labelOrId( frame.args.qid or frame.args[1] ) | + | return (labelOrId(frame.args.qid or frame.args[1])) |
| | end | | end |
| | | | |
| Line 2,933: |
Line 3,044: |
| | if pid == "" then pid = par[1] end | | if pid == "" then pid = par[1] end |
| | if qid == "" then qid = par[2] 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 pid:sub(1,1) ~= "P" then return "No property supplied" end |
| − | if qid:sub(1,1) ~= "Q" then qid = mw.wikibase.getEntityIdForCurrentPage() end | + | if q1 ~= "Q" and q1 ~= "M" then qid = mw.wikibase.getEntityIdForCurrentPage() end |
| | if not qid then return "No item for this page" end | | if not qid then return "No item for this page" end |
| | return "<pre>" .. mw.dumpObject( mw.wikibase.getAllStatements( qid, pid ) ) .. "</pre>" | | return "<pre>" .. mw.dumpObject( mw.wikibase.getAllStatements( qid, pid ) ) .. "</pre>" |
| Line 3,232: |
Line 3,344: |
| | 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 |
| − | local stat = mw.wikibase.getBestStatements(qid, prop)[1] | + | local onlysrc = parseParam(args.onlysourced or args.osd, true) |
| − | if not stat then return nil end | + | local stat = mw.wikibase.getBestStatements(qid, prop) |
| − | local prec = stat.mainsnak.datavalue
| + | for i, v in ipairs(stat) do |
| − | and stat.mainsnak.datavalue.value
| + | local prec = (onlysrc == false or sourced(v)) |
| − | and stat.mainsnak.datavalue.value.precision
| + | and v.mainsnak.datavalue |
| − | return prec
| + | and v.mainsnak.datavalue.value |
| | + | and v.mainsnak.datavalue.value.precision |
| | + | if prec then return prec end |
| | + | end |
| | end | | end |
| | | | |
| Line 3,258: |
Line 3,373: |
| | getValueByRefSource | | getValueByRefSource |
| | getPropertyIDs | | getPropertyIDs |
| | + | getQualifierIDs |
| | getPropOfProp | | getPropOfProp |
| | getAwardCat | | getAwardCat |
| Line 3,266: |
Line 3,382: |
| | getLink | | getLink |
| | getLabel | | getLabel |
| | + | label |
| | getAT | | getAT |
| | getDescription | | getDescription |