Changes

5,528 bytes added ,  23:56, 28 November 2020
m
KS update 1.1
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