Module:WikidataIB: Difference between revisions

Jump to navigation Jump to search
m (1 revision imported)
(ensure that _getPropOfProp never returns an empty string)
Line 1: Line 1:
-- Version: 2020-12-15
-- 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 14: 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 567: Line 576:
-- uselbl is boolean switch to force display of the label instead of the sitelink (default: false)
-- 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)
-- 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, args)
local linkedItem = function(id, args)
local lprefix = args.lprefix or "" -- toughen against nil values passed
local lprefix = (args.lp or args.lprefix or args.linkprefix or ""):gsub('"', '') -- toughen against nil values passed
local lpostfix = args.lpostfix or ""
local lpostfix = (args.lpostfix or ""):gsub('"', '')
local prefix = args.prefix or ""
local prefix = (args.prefix or ""):gsub('"', '')
local postfix = args.postfix or ""
local postfix = (args.postfix or ""):gsub('"', '')
local dtxt = args.dtxt
local dtxt = args.dtxt
local shortname = args.shortname
local shortname = args.shortname
Line 582: Line 592:
local linkredir = args.linkredir
local linkredir = args.linkredir
linkredir = parseParam(linkredir, false)
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 = ""
if next(formats) then
if next(formats) and formatvalue then
for k, v in ipairs( mw.wikibase.getBestStatements(id, "P31") ) do
for k, v in ipairs( mw.wikibase.getBestStatements(id, "P31") ) do
if v.mainsnak.datavalue and formats[v.mainsnak.datavalue.value.id] then
if v.mainsnak.datavalue and formats[v.mainsnak.datavalue.value.id] then
Line 1,268: 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,396: 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,476: 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,507: 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,549: 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,581: Line 1,601:
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 instid == "Q3624078" or (skip and instid == "Q3336843") then
if instid == "Q6256" or instid == "Q3624078" or (skip and instid == "Q3336843") then
Line 1,895: 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,920: 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,116: 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,134: 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,148: 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,183: 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,243: Line 2,277:
local pid1 = args.prop1 or args.pid1 or ""
local pid1 = args.prop1 or args.pid1 or ""
local pid2 = args.prop2 or args.pid2 or ""
local pid2 = args.prop2 or args.pid2 or ""
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 f = {}
local f = {}
f.args = args
f.args = args
local qid1, statements1 = parseInput(f, localval, pid1)
local qid1, statements1 = parseInput(f, args[1], pid1)
if not qid1 then return localval end
-- 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,466: 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,958: 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,964: 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.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Line 2,972: Line 3,007:
local qid = (args.qid or ""):upper()
local qid = (args.qid or ""):upper()
local all = parseParam(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,994: 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
Line 3,141: 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
ranks = setRanks(args.rank)
local ranks = setRanks(args.rank)
local stats = {}
local stats = {}
if ranks.b then
if ranks.b then
Line 3,151: Line 3,194:
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
ms = v.mainsnak
local ms = v.mainsnak
if ranks[v.rank:sub(1,1)] and ms.snaktype == "value" and ms.datavalue.value.id == val then
if ranks[v.rank:sub(1,1)] and ms.snaktype == "value" and ms.datavalue.value.id == val then
return val
return val
Line 3,389: 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]