Changes

11,041 bytes added ,  01:31, 30 October 2019
sync from sandbox: only remove prefix from sitelink if it's a genuine namespace name
Line 80: Line 80:  
}
 
}
 
}
 
}
-- This allows a internationisation module to override the above table
+
-- This allows an internationisation module to override the above table
 
if 'en' ~= mw.getContentLanguage():getCode() then
 
if 'en' ~= mw.getContentLanguage():getCode() then
 
require("Module:i18n").loadI18n("Module:WikidataIB/i18n", i18n)
 
require("Module:i18n").loadI18n("Module:WikidataIB/i18n", i18n)
Line 95: Line 95:  
if nolinks_exists then
 
if nolinks_exists then
 
donotlink = nolinks.itemsindex
 
donotlink = nolinks.itemsindex
 +
end
 +
 +
-- To satisfy Wikipedia:Manual of Style/Titles, certain types of items are italicised, and others are quoted.
 +
-- The submodule [[Module:WikidataIB/titleformats]] lists the entity-ids used in 'instance of' (P31),
 +
-- which allows this module to identify the values that should be formatted.
 +
-- WikidataIB/titleformats exports a table p.formats, which is indexed by entity-id, and contains the value " or ''
 +
local formats = {}
 +
local titleformats_exists, titleformats = pcall(mw.loadData, "Module:WikidataIB/titleformats")
 +
if titleformats_exists then
 +
formats = titleformats.formats
 
end
 
end
   Line 389: Line 399:  
-- it may also be returned wrapped in a microformat, so remove that
 
-- it may also be returned wrapped in a microformat, so remove that
 
fdate = fdate:gsub("<[^>]*>", "")
 
fdate = fdate:gsub("<[^>]*>", "")
 +
-- there may be leading zeros that we should remove
 +
fdate = fdate:gsub("^0*", "")
 +
-- if a plain date is required, then remove any links (like BC linked)
 +
if pd then
 +
fdate = fdate:gsub("%[%[.*|", ""):gsub("]]", "")
 +
end
 
-- if 'circa', use the abbreviated form *** internationalise later ***
 
-- if 'circa', use the abbreviated form *** internationalise later ***
 
fdate = fdate:gsub('circa ', '<abbr title="circa">c.</abbr>&nbsp;')
 
fdate = fdate:gsub('circa ', '<abbr title="circa">c.</abbr>&nbsp;')
Line 412: Line 428:  
-- it makes the empty string and nil into the (boolean) value passed as default
 
-- it makes the empty string and nil into the (boolean) value passed as default
 
-- allowing the parameter to be true or false by default.
 
-- allowing the parameter to be true or false by default.
 +
-- It returns a boolean.
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
 
-- Dependencies: none
 
-- Dependencies: none
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
 
local parseParam = function(param, default)
 
local parseParam = function(param, default)
 +
if type(param) == "boolean" then param = tostring(param) end
 
if param and param ~= "" then
 
if param and param ~= "" then
 
param = param:lower()
 
param = param:lower()
Line 474: Line 492:  
local prop910 = mw.wikibase.getBestStatements(qid, "P910")[1]
 
local prop910 = mw.wikibase.getBestStatements(qid, "P910")[1]
 
if prop910 then
 
if prop910 then
local tmcid = prop910.mainsnak.datavalue.value.id
+
local tmcid = prop910.mainsnak.datavalue and prop910.mainsnak.datavalue.value.id
 
sitelink = _getSitelink(tmcid, "commonswiki")
 
sitelink = _getSitelink(tmcid, "commonswiki")
 +
end
 +
if not sitelink then
 +
-- check for list's main category
 +
local prop1754 = mw.wikibase.getBestStatements(qid, "P1754")[1]
 +
if prop1754 then
 +
local tmcid = prop1754.mainsnak.datavalue and prop1754.mainsnak.datavalue.value.id
 +
sitelink = _getSitelink(tmcid, "commonswiki")
 +
end
 
end
 
end
 
end
 
end
Line 482: Line 508:  
local prop373 = mw.wikibase.getBestStatements(qid, "P373")[1]
 
local prop373 = mw.wikibase.getBestStatements(qid, "P373")[1]
 
if prop373 then
 
if prop373 then
sitelink = prop373.mainsnak.datavalue.value
+
sitelink = prop373.mainsnak.datavalue and prop373.mainsnak.datavalue.value
 
if sitelink then sitelink = "Category:" .. sitelink end
 
if sitelink then sitelink = "Category:" .. sitelink end
 
end
 
end
Line 499: Line 525:  
-- Dependencies: none
 
-- Dependencies: none
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
local labelOrId = function(id)
+
local labelOrId = function(id, lang)
local label = mw.wikibase.label(id)
+
if lang == "default" then lang = findLang().code end
 +
local label
 +
if lang then
 +
label = mw.wikibase.getLabelByLang(id, lang)
 +
else
 +
label = mw.wikibase.label(id)
 +
end
 
if label then
 
if label then
 
return mw.text.nowiki(label), true
 
return mw.text.nowiki(label), true
Line 529: Line 561:  
postfix = postfix or ""
 
postfix = postfix or ""
 
lang = lang or "en" -- fallback to default if missing
 
lang = lang or "en" -- fallback to default if missing
 +
-- see if item might need italics or quotes
 +
local fmt = ""
 +
for k, v in ipairs( mw.wikibase.getBestStatements(id, "P31") ) do
 +
if v.mainsnak.datavalue and formats[v.mainsnak.datavalue.value.id] then
 +
fmt = formats[v.mainsnak.datavalue.value.id]
 +
break -- pick the first match
 +
end
 +
end
 
local disp
 
local disp
 
local sitelink = mw.wikibase.sitelink(id)
 
local sitelink = mw.wikibase.sitelink(id)
Line 553: Line 593:  
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 and use that as label
+
-- strip any namespace or dab from the sitelink
 
local pos = sitelink:find(":") or 0
 
local pos = sitelink:find(":") or 0
label = sitelink:sub(pos+1):gsub("%s%(.+%)$", ""):gsub(",.+$", "")
+
local slink = sitelink
 +
if pos > 0 then
 +
local prefix = sitelink:sub(1,pos-1)
 +
if mw.site.namespaces[prefix] 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(",.+$", "")
 +
--  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
 
if donotlink[label] then
 
if donotlink[label] then
disp = prefix .. label .. postfix
+
disp = prefix .. fmt .. label .. fmt .. postfix
 
else
 
else
disp = "[[" .. lprefix .. sitelink .. lpostfix .. "|" .. prefix .. label .. postfix .. "]]"
+
disp = "[[" .. lprefix .. sitelink .. lpostfix .. "|" .. prefix .. fmt .. label .. fmt .. postfix .. "]]"
 
end
 
end
 
elseif islabel then
 
elseif islabel then
Line 567: Line 621:  
if artitle and artitle.redirectTarget and not donotlink[label] then
 
if artitle and artitle.redirectTarget and not donotlink[label] 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 .. label .. postfix .. "]]"
+
disp = "[[".. lprefix .. label .. lpostfix .. "|" .. prefix .. fmt .. label .. fmt .. postfix .. "]]"
 
else
 
else
 
-- no sitelink, label exists, not redirect (or donotlink) so output plain label
 
-- no sitelink, label exists, not redirect (or donotlink) so output plain label
disp = prefix .. label .. 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
 
else
 
else
Line 724: Line 778:  
local createicon = function(langcode, entityID, propertyID)
 
local createicon = function(langcode, entityID, propertyID)
 
local icon = "&nbsp;[[" .. i18n["filespace"]
 
local icon = "&nbsp;[[" .. i18n["filespace"]
icon = icon .. ":Blue pencil.svg |frameless |text-top |10px |alt="
+
icon = icon .. ":OOjs UI icon edit-ltr-progressive.svg |frameless |text-top |10px |alt="
 
icon = icon .. i18n["editonwikidata"]
 
icon = icon .. i18n["editonwikidata"]
 
icon = icon .. "|link=https://www.wikidata.org/wiki/" .. entityID
 
icon = icon .. "|link=https://www.wikidata.org/wiki/" .. entityID
Line 873: Line 927:  
-- qualifiers (if any) is a nested table or nil
 
-- qualifiers (if any) is a nested table or nil
 
-- lang is given, or user language, or site language
 
-- lang is given, or user language, or site language
 +
--
 +
-- Here we can check whether args.df has a value
 +
-- If not, use code from Module:Sandbox/RexxS/Getdateformat to set it from templates like {{Use mdy dates}}
 
val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel)
 
val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel)
 
------------------------------------
 
------------------------------------
Line 882: Line 939:  
-- don't link if no linkpre/postfix or linkprefix is just ":"
 
-- don't link if no linkpre/postfix or linkprefix is just ":"
 
val = pre .. dv .. post
 
val = pre .. dv .. post
 +
elseif dtype == "external-id" then
 +
val = "[" .. lpre .. dv .. lpost .. " " .. pre .. dv .. post .. "]"
 
else
 
else
 
val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]"
 
val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]"
Line 898: Line 957:  
-- if we have conversions, we won't have formatted numbers or scales
 
-- if we have conversions, we won't have formatted numbers or scales
 
if conv then
 
if conv then
 +
uabbr = true
 
fnum = false
 
fnum = false
 
args.scale = "0"
 
args.scale = "0"
Line 1,002: Line 1,062:  
end
 
end
 
-- format display:
 
-- format display:
if conv and usym ~= "" then
+
if conv then
 
if range == "" then
 
if range == "" then
val = mw.getCurrentFrame():expandTemplate{title = "cvt", args = {amount, usym}}
+
val = mw.getCurrentFrame():expandTemplate{title = "cvt", args = {amount, unit}}
 
else
 
else
val = mw.getCurrentFrame():expandTemplate{title = "cvt", args = {lowb, "to", upb, usym}}
+
val = mw.getCurrentFrame():expandTemplate{title = "cvt", args = {lowb, "to", upb, unit}}
 
end
 
end
 
elseif unit == "$" or unit == "£" then
 
elseif unit == "$" or unit == "£" then
Line 1,023: Line 1,083:  
-- default is deg/min/sec -- decimal degrees needs |format = dec
 
-- default is deg/min/sec -- decimal degrees needs |format = dec
 
local form = (args.format or ""):lower():sub(1,3)
 
local form = (args.format or ""):lower():sub(1,3)
if form ~= "dec" then form = "dms" end
+
if form ~= "dec" then form = "dms" end -- not needed for now
 
--
 
--
-- show parameter allows just the latitude or longitude to be shown
+
-- show parameter allows just the latitude, or just the longitude, or both
 +
-- to be returned as a signed decimal, ignoring the format parameter.
 
local show = (args.show or ""):lower()
 
local show = (args.show or ""):lower()
 
if show ~= "longlat" then show = show:sub(1,3) end
 
if show ~= "longlat" then show = show:sub(1,3) end
Line 1,148: Line 1,209:  
local pd = args.plaindate or args.pd or "no"
 
local pd = args.plaindate or args.pd or "no"
 
args.pd = pd
 
args.pd = pd
 +
 +
-- allow qualifiers to have a different date format; default to year
 +
args.qdf = args.qdf or args.qualifierdateformat or args.df or "y"
    
local lang = args.lang or findlang().code
 
local lang = args.lang or findlang().code
 
-- 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 values for this property
 
-- out[] holds the values for this property
Line 1,175: Line 1,240:  
-- 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=="value" then
+
if hasvalue and v.qualifiers and qualID and snak.snaktype~="novalue" then
 
local qsep = (args.qsep or ""):gsub('"', '')
 
local qsep = (args.qsep or ""):gsub('"', '')
 
local qargs = {
 
local qargs = {
Line 1,187: Line 1,252:  
["unitabbr"]    = tostring(uabbr),
 
["unitabbr"]    = tostring(uabbr),
 
["maxvals"]    = 0,
 
["maxvals"]    = 0,
["sorted"]      = args.qsorted,
+
["sorted"]      = tostring(args.qsorted),
 
["noicon"]      = "true",
 
["noicon"]      = "true",
 
["list"]        = args.qlist,
 
["list"]        = args.qlist,
Line 1,193: Line 1,258:  
["langobj"]    = args.langobj,
 
["langobj"]    = args.langobj,
 
["lang"]        = args.langobj.code,
 
["lang"]        = args.langobj.code,
 +
["df"]          = args.qdf
 
}
 
}
 
local qlist = {}
 
local qlist = {}
Line 1,204: Line 1,270:  
local ts = v.qualifiers[v1][1].datavalue.value.time
 
local ts = v.qualifiers[v1][1].datavalue.value.time
 
local dp = v.qualifiers[v1][1].datavalue.value.precision
 
local dp = v.qualifiers[v1][1].datavalue.value.precision
qlist[#qlist + 1] = dateFormat(ts, dp, args.df, args.bc, pd, "", lang, "before")
+
qlist[#qlist + 1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before")
 
elseif v1 == "P1319" then
 
elseif v1 == "P1319" then
 
local ts = v.qualifiers[v1][1].datavalue.value.time
 
local ts = v.qualifiers[v1][1].datavalue.value.time
 
local dp = v.qualifiers[v1][1].datavalue.value.precision
 
local dp = v.qualifiers[v1][1].datavalue.value.precision
qlist[#qlist + 1] = dateFormat(ts, dp, args.df, args.bc, pd, "", lang, "after")
+
qlist[#qlist + 1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after")
 
else
 
else
 
local q = assembleoutput(propertyvalueandquals(v.qualifiers[v1], qargs), qargs)
 
local q = assembleoutput(propertyvalueandquals(v.qualifiers[v1], qargs), qargs)
 
-- we already deal with circa via 'sourcing circumstances'
 
-- we already deal with circa via 'sourcing circumstances'
 
-- either linked or unlinked *** internationalise later ***
 
-- either linked or unlinked *** internationalise later ***
if q ~= "circa" and not q:find("circa]]") then
+
if q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then
 
qlist[#qlist + 1] = q
 
qlist[#qlist + 1] = q
 
end
 
end
Line 1,224: Line 1,290:  
-- we already deal with circa via 'sourcing circumstances'
 
-- we already deal with circa via 'sourcing circumstances'
 
-- either linked or unlinked *** internationalise later ***
 
-- either linked or unlinked *** internationalise later ***
if v1 ~= "circa" and not v1:find("circa]]") then
+
if v1 ~= "circa" and not (type(v1) == "string" and v1:find("circa]]")) then
 
qlist[#qlist + 1] = v1
 
qlist[#qlist + 1] = v1
 
end
 
end
Line 1,249: Line 1,315:  
local ts = v1[1].datavalue.value.time
 
local ts = v1[1].datavalue.value.time
 
local dp = v1[1].datavalue.value.precision
 
local dp = v1[1].datavalue.value.precision
qlist[#qlist + 1] = dateFormat(ts, dp, args.df, args.bc, pd, "", lang, "before")
+
qlist[#qlist + 1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before")
 
end
 
end
 
end
 
end
Line 1,373: Line 1,439:  
-- 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
 
-- so see if matches the required value
 
-- so see if matches the required value
-- We'll only deal with wikibase-items for now
+
-- We'll only deal with wikibase-items and strings for now
 
if v1q[qualID][1].datatype == "wikibase-item" then
 
if v1q[qualID][1].datatype == "wikibase-item" then
 
if checkvalue(v1q[qualID][1].datavalue.value.id) then
 
if checkvalue(v1q[qualID][1].datavalue.value.id) then
 +
out[#out + 1] = rendersnak(v1, args, linked, lpre, lpost, pre, post, uabbr, filter)
 +
end
 +
elseif v1q[qualID][1].datatype == "string" then
 +
if checkvalue(v1q[qualID][1].datavalue.value) then
 
out[#out + 1] = rendersnak(v1, args, linked, lpre, lpost, pre, post, uabbr, filter)
 
out[#out + 1] = rendersnak(v1, args, linked, lpre, lpost, pre, post, uabbr, filter)
 
end
 
end
Line 1,411: Line 1,481:  
local finished = false
 
local finished = false
 
local count = 0
 
local count = 0
local prevqid = ""
+
local prevqid = "Q0"
 
repeat
 
repeat
 
local prop
 
local prop
Line 1,417: Line 1,487:  
local proptbl = mw.wikibase.getBestStatements(qid, v1)
 
local proptbl = mw.wikibase.getBestStatements(qid, v1)
 
if #proptbl > 1 then
 
if #proptbl > 1 then
-- there is more than one parent location
+
-- there is more than one higher location
 +
local prevP131, prevP131id
 +
if prevqid ~= "Q0" then
 +
prevP131 = mw.wikibase.getBestStatements(prevqid, "P131")[1]
 +
prevP131id = prevP131
 +
and prevP131.mainsnak.datavalue
 +
and prevP131.mainsnak.datavalue.value.id
 +
end
 
for i2, v2 in ipairs(proptbl) do
 
for i2, v2 in ipairs(proptbl) do
 
parttbl = v2.qualifiers and v2.qualifiers.P518
 
parttbl = v2.qualifiers and v2.qualifiers.P518
 
if parttbl then
 
if parttbl then
-- this parent location has qualifier 'applies to part' (P518)
+
-- this higher location has qualifier 'applies to part' (P518)
 
for i3, v3 in ipairs(parttbl) do
 
for i3, v3 in ipairs(parttbl) do
 
if v3.snaktype == "value" and v3.datavalue.value.id == prevqid then
 
if v3.snaktype == "value" and v3.datavalue.value.id == prevqid then
Line 1,429: Line 1,506:  
end -- of test for matching last location
 
end -- of test for matching last location
 
end -- of loop through values of 'applies to part'
 
end -- of loop through values of 'applies to part'
 +
else
 +
-- there's no qualifier 'applies to part' (P518)
 +
-- so check if the previous location had a P131 that matches this alternate
 +
if qid == prevP131id then
 +
prop = proptbl[i2]
 +
break
 +
end -- of test for matching previous P131
 
end
 
end
 
end -- of loop through parent locations
 
end -- of loop through parent locations
Line 1,576: Line 1,660:  
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
-- getValue is used to get the value(s) of a property
+
-- _getValue makes the functionality of getValue available to other modules
-- The property ID is passed as the first unnamed parameter and is required.
  −
-- A locally supplied parameter may optionaly be supplied as the second unnamed parameter.
  −
-- The function will now also return qualifiers if parameter qual is supplied
   
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
 
-- Dependencies: setRanks; parseInput; propertyvalueandquals; assembleoutput; parseParam; sourced;
 
-- Dependencies: setRanks; parseInput; propertyvalueandquals; assembleoutput; parseParam; sourced;
 
-- labelOrId; i18n.latestdatequalifier; format_Date; makeOrdinal; roundto; decimalPrecision; decimalToDMS;
 
-- labelOrId; i18n.latestdatequalifier; format_Date; makeOrdinal; roundto; decimalPrecision; decimalToDMS;
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
p.getValue = function(frame)
+
p._getValue = function(args)
if not frame.args[1] then
  −
frame.args = frame:getParent().args
  −
if not frame.args[1] then return i18n.errors["No property supplied"] end
  −
end
  −
 
   
-- parameter sets for commonly used groups of parameters
 
-- parameter sets for commonly used groups of parameters
local paraset = tonumber(frame.args.ps or frame.args.parameterset or 0)
+
local paraset = tonumber(args.ps or args.parameterset or 0)
 
if paraset == 1 then
 
if paraset == 1 then
frame.args.rank = "best"
+
-- a common setting
frame.args.fetchwikidata = "ALL"
+
args.rank = "best"
frame.args.onlysourced = "no"
+
args.fetchwikidata = "ALL"
frame.args.noicon = "true"
+
args.onlysourced = "no"
 +
args.noicon = "true"
 
elseif paraset == 2 then
 
elseif paraset == 2 then
-- second set goes here
+
-- 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
 
end
   −
local propertyID = mw.text.trim(frame.args[1] or "")
+
-- implement eid parameter
 +
local eid = args.eid
 +
if eid == "" then
 +
return nil
 +
elseif eid then
 +
args.qid = eid
 +
end
   −
frame.args.reqranks = setRanks(frame.args.rank)
+
local propertyID = mw.text.trim(args[1] or "")
   −
local entityid, props = parseInput(frame, frame.args[2], propertyID)
+
args.reqranks = setRanks(args.rank)
 +
 
 +
local f = {}
 +
f.args = args
 +
local entityid, props = parseInput(f, f.args[2], propertyID)
    
if not entityid then
 
if not entityid then
 
return props -- either the input parameter or nothing
 
return props -- either the input parameter or nothing
 
end
 
end
 +
 
-- qual is a string containing the property ID of the qualifier(s) to be returned
 
-- qual is a string containing the property ID of the qualifier(s) to be returned
 
-- if qual == "ALL" then all qualifiers returned
 
-- if qual == "ALL" then all qualifiers returned
 
-- if qual == "DATES" then qualifiers P580 (start time) and P582 (end time) returned
 
-- if qual == "DATES" then qualifiers P580 (start time) and P582 (end time) returned
 
-- if nothing or an empty string is passed set it nil -> no qualifiers returned
 
-- if nothing or an empty string is passed set it nil -> no qualifiers returned
local qualID = mw.text.trim(frame.args.qual or ""):upper()
+
local qualID = mw.text.trim(args.qual or ""):upper()
 
if qualID == "" then qualID = nil end
 
if qualID == "" then qualID = nil end
   −
-- set a language object and code in the frame.args table
+
-- set a language object and code in the args table
frame.args.langobj = findLang(frame.args.lang)
+
args.langobj = findLang(args.lang)
frame.args.lang = frame.args.langobj.code
+
args.lang = args.langobj.code
    
-- table 'out' stores the return value(s):
 
-- table 'out' stores the return value(s):
local out = propertyvalueandquals(props, frame.args, qualID)
+
local out = propertyvalueandquals(props, args, qualID)
    
-- format the table of values and return it as a string:
 
-- format the table of values and return it as a string:
return assembleoutput(out, frame.args, entityid, propertyID)
+
return assembleoutput(out, args, entityid, propertyID)
 +
end
 +
 
 +
 
 +
-------------------------------------------------------------------------------
 +
-- getValue is used to get the value(s) of a property
 +
-- The property ID is passed as the first unnamed parameter and is required.
 +
-- A locally supplied parameter may optionaly be supplied as the second unnamed parameter.
 +
-- The function will now also return qualifiers if parameter qual is supplied
 +
-------------------------------------------------------------------------------
 +
-- Dependencies: _getValue; setRanks; parseInput; propertyvalueandquals; assembleoutput; parseParam; sourced;
 +
-- labelOrId; i18n.latestdatequalifier; format_Date; makeOrdinal; roundto; decimalPrecision; decimalToDMS;
 +
-------------------------------------------------------------------------------
 +
p.getValue = function(frame)
 +
local args= frame.args
 +
if not args[1] then
 +
args = frame:getParent().args
 +
if not args[1] then return i18n.errors["No property supplied"] end
 +
end
 +
 
 +
return p._getValue(args)
 
end
 
end
   Line 1,791: Line 1,907:  
-- a property ID (the unnamed parameter or 1=Pxxx)
 
-- a property ID (the unnamed parameter or 1=Pxxx)
 
-- the ID of a qualifier for that property (qualID=Pyyy)
 
-- the ID of a qualifier for that property (qualID=Pyyy)
-- the Wikibase-entity ID of a value for that qualifier (qvalue=Qzzz)
+
-- either the Wikibase-entity ID of a value for that qualifier (qvalue=Qzzz)
 +
-- or a string value for that qualifier (qvalue=abc123)
 
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented
 
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
Line 1,821: Line 1,938:  
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
 
p.getValueByLang = function(frame)
 
p.getValueByLang = function(frame)
   
-- The language code for the qualifier we want to match is in named parameter |lang=
 
-- The language code for the qualifier we want to match is in named parameter |lang=
local langcode = frame.args.lang or ""
+
local langcode = findLang(frame.args.lang).code
if langcode == "" then
  −
langcode = frame:callParserFunction{ name = "int", args = "lang" }
  −
end
   
local function checkLanguage(id)
 
local function checkLanguage(id)
 
-- id should represent a language like "British English (Q7979)"
 
-- id should represent a language like "British English (Q7979)"
Line 1,842: Line 1,955:  
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
 
-- getValueByRefSource gets the value of a property which has a reference "stated in" (P248)
 
-- getValueByRefSource gets the value of a property which has a reference "stated in" (P248)
-- whose value has the given entity code.
+
-- whose value has the given entity-ID.
 
-- The call needs:
 
-- The call needs:
 
-- a property ID (the unnamed parameter or 1=Pxxx)
 
-- a property ID (the unnamed parameter or 1=Pxxx)
Line 1,934: Line 2,047:     
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
-- getPropOfProp takes two propertyIDs: prop1 and prop2 (as well as the usual parameters)
+
-- getPropertyIDs takes most of the usual parameters.
-- If the value(s) of prop1 are of type "wikibase-item" then it returns the value(s) of prop2
+
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented.
-- of each of those wikibase-items.
+
-- It returns the Entity-IDs (Qids) of the values of a property if it is a Wikibase-Entity.
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented
+
-- Otherwise it returns nothing.
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
 
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput;
 
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput;
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
p.getPropOfProp = function(frame)
+
p.getPropertyIDs = 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 "")
 +
 
 +
-- 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
 +
local onlysrc = parseParam(args.onlysourced or args.osd, true)
 +
local maxvals = tonumber(args.maxvals) or 0
 +
 
 +
out = {}
 +
for i, v in ipairs(props) do
 +
local snak = v.mainsnak
 +
if ( snak.datatype == "wikibase-item" )
 +
and ( v.rank and args.reqranks[v.rank:sub(1, 1)] )
 +
and ( snak.snaktype == "value" )
 +
and ( sourced(v) or not onlysrc )
 +
then
 +
out[#out+1] = snak.datavalue.value.id
 +
end
 +
if maxvals > 0 and #out >= maxvals then break end
 +
end
 +
 
 +
return assembleoutput(out, args, qid, pid)
 +
end
 +
 
 +
 
 +
-------------------------------------------------------------------------------
 +
-- getPropOfProp takes two propertyIDs: prop1 and prop2 (as well as the usual parameters)
 +
-- If the value(s) of prop1 are of type "wikibase-item" then it returns the value(s) of prop2
 +
-- of each of those wikibase-items.
 +
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented
 +
-------------------------------------------------------------------------------
 +
-- Dependencies: parseParam; setRanks; parseInput; sourced; propertyvalueandquals assembleoutput;
 +
-------------------------------------------------------------------------------
 +
p.getPropOfProp = function(frame)
 
frame.args.reqranks = setRanks(frame.args.rank)
 
frame.args.reqranks = setRanks(frame.args.rank)
 
frame.args.langobj = findLang(frame.args.lang)
 
frame.args.langobj = findLang(frame.args.lang)
Line 2,175: Line 2,331:     
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
-- getGlobe takes an optional qid of a Wikidata entity passed as |qid=
+
-- qualsToTable takes most of the usual parameters.
-- otherwise it uses the linked item for the current page.
+
-- The usual whitelisting, blacklisting, onlysourced, etc. are implemented.
-- If returns the Qid of the globe used in P625 (coordinate location),
+
-- A qid may be given, and the first unnamed parameter is the property ID, which is of type wikibase item.
-- or nil if there isn't one.
+
-- It takes a list of qualifier property IDs as |quals=
 +
-- For a given qid and property, it creates the rows of an html table,
 +
-- each row being a value of the property (optionally only if the property matches the value in |pval= )
 +
-- each cell being the first value of the qualifier corresponding to the list in |quals
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
-- Dependencies: none
+
-- Dependencies: parseParam; setRanks; parseInput; sourced;
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
p.getGlobe = function(frame)
+
p.qualsToTable = function(frame)
local qid = frame.args.qid or frame.args[1] or ""
+
local args = frame.args
 +
 
 +
local quals = args.quals or ""
 +
if quals == "" then return "" end
 +
 
 +
args.reqranks = setRanks(args.rank)
 +
 
 +
local propertyID = mw.text.trim(args[1] or "")
 +
local f = {}
 +
f.args = args
 +
local entityid, props = parseInput(f, "", propertyID)
 +
if not entityid then return "" end
 +
 
 +
args.langobj = findLang(args.lang)
 +
args.lang = args.langobj.code
 +
 
 +
local pval = args.pval or ""
 +
 
 +
local qplist = mw.text.split(quals, "%p") -- split at punctuation and make a sequential table
 +
for i, v in ipairs(qplist) do
 +
qplist[i] = mw.text.trim(v):upper() -- remove whitespace and capitalise
 +
end
 +
 
 +
local col1 = args.firstcol or ""
 +
if col1 ~= "" then
 +
col1 = col1 .. "</td><td>"
 +
end
 +
 
 +
local emptycell = args.emptycell or "&nbsp;"
 +
 
 +
-- construct a 2-D array of qualifier values in qvals
 +
local qvals = {}
 +
for i, v in ipairs(props) do
 +
local skip = false
 +
if pval ~= "" then
 +
local pid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id
 +
if pid ~= pval then skip = true end
 +
end
 +
if not skip then
 +
local qval = {}
 +
local vqualifiers = v.qualifiers or {}
 +
-- go through list of wanted qualifier properties
 +
for i1, v1 in ipairs(qplist) do
 +
-- check for that property ID in the statement's qualifiers
 +
local qv, qtype
 +
if vqualifiers[v1] then
 +
qtype = vqualifiers[v1][1].datatype
 +
if qtype == "time" then
 +
if vqualifiers[v1][1].snaktype == "value" then
 +
qv = mw.wikibase.renderSnak(vqualifiers[v1][1])
 +
qv = frame:expandTemplate{title="dts", args={qv}}
 +
else
 +
qv = "?"
 +
end
 +
elseif qtype == "url" then
 +
qv = mw.wikibase.renderSnak(vqualifiers[v1][1])
 +
local display = mw.ustring.match( mw.uri.decode(qv, "WIKI"), "([%w ]+)$" )
 +
if display then
 +
qv = "[" .. qv .. " " .. display .. "]"
 +
end
 +
else
 +
qv = mw.wikibase.formatValue(vqualifiers[v1][1])
 +
end
 +
end
 +
-- record either the value or a placeholder
 +
qval[i1] = qv or emptycell
 +
end -- of loop through list of qualifiers
 +
-- add the list of qualifier values as a "row" in the main list
 +
qvals[#qvals+1] = qval
 +
end
 +
end -- of for each value loop
 +
 
 +
local out = {}
 +
for i, v in ipairs(qvals) do
 +
out[i] = "<tr><td>" .. col1 .. table.concat(qvals[i], "</td><td>") .. "</td></tr>"
 +
end
 +
return table.concat(out, "\n")
 +
end
 +
 
 +
 
 +
-------------------------------------------------------------------------------
 +
-- getGlobe takes an optional qid of a Wikidata entity passed as |qid=
 +
-- otherwise it uses the linked item for the current page.
 +
-- If returns the Qid of the globe used in P625 (coordinate location),
 +
-- or nil if there isn't one.
 +
-------------------------------------------------------------------------------
 +
-- Dependencies: none
 +
-------------------------------------------------------------------------------
 +
p.getGlobe = function(frame)
 +
local qid = frame.args.qid or frame.args[1] or ""
 
if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage() end
 
if qid == "" then qid = mw.wikibase.getEntityIdForCurrentPage() end
 
local coords = mw.wikibase.getBestStatements(qid, "P625")[1]
 
local coords = mw.wikibase.getBestStatements(qid, "P625")[1]
Line 2,255: Line 2,503:  
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 label = labelOrId(itemID)
+
local lang = frame.args.lang or ""
 +
if lang == "" then lang = nil end
 +
local label = labelOrId(itemID, lang)
 
return label
 
return label
 
end
 
end
Line 2,512: Line 2,762:  
-- getQid returns the qid, if supplied
 
-- getQid returns the qid, if supplied
 
-- failing that, the Wikidata entity ID of the "category's main topic (P301)", if it exists
 
-- failing that, the Wikidata entity ID of the "category's main topic (P301)", if it exists
-- failing that, the Wikidata entity ID asociated with the curent page, if it exists
+
-- failing that, the Wikidata entity ID associated with the current page, if it exists
 
-- otherwise, nothing
 
-- otherwise, nothing
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
Line 2,536: Line 2,786:     
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
-- followQid takes two optional parameters: qid and props
+
-- followQid takes three optional parameters: qid, props, 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,576: Line 2,826:  
return qid
 
return qid
 
end
 
end
 +
end
 +
 +
 +
-------------------------------------------------------------------------------
 +
-- globalSiteID returns the globalSiteID for the current wiki
 +
-- e.g. returns "enwiki" for the English Wikipedia, "enwikisource" for English Wikisource, etc.
 +
-------------------------------------------------------------------------------
 +
-- Dependencies: none
 +
-------------------------------------------------------------------------------
 +
p.globalSiteID = function(frame)
 +
return mw.wikibase.getGlobalSiteId()
 
end
 
end
   Line 2,918: Line 3,179:  
else
 
else
 
return false
 
return false
 +
end
 +
end
 +
 +
 +
-------------------------------------------------------------------------------
 +
-- getEntityFromTitle returns the Entity-ID (Q-number) for a given title.
 +
-- Modification of Module:ResolveEntityId
 +
-- The title is the first unnamed parameter.
 +
-- The site parameter determines the site/language for the title. Defaults to current wiki.
 +
-- The showdab parameter determines whether dab pages should return the Q-number or nil. Defaults to true.
 +
-- Returns the Q-number or nil if it does not exist.
 +
-------------------------------------------------------------------------------
 +
-- Dependencies: parseParam
 +
-------------------------------------------------------------------------------
 +
function p.getEntityFromTitle(frame)
 +
local args=frame.args
 +
if not args[1] then args=frame:getParent().args end
 +
if not args[1] then return nil end
 +
local title = mw.text.trim(args[1])
 +
local site = args.site or ""
 +
local showdab = parseParam(args.showdab, true)
 +
qid = mw.wikibase.getEntityIdForTitle(title, site)
 +
if qid then
 +
local prop31 = mw.wikibase.getBestStatements(qid, "P31")[1]
 +
if not showdab and prop31 and prop31.mainsnak.datavalue.value.id == "Q4167410" then
 +
return nil
 +
else
 +
return qid
 +
end
 
end
 
end
 
end
 
end
Line 2,928: Line 3,218:  
-- List of exported functions
 
-- List of exported functions
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
-- getValue
+
--[[
-- getPreferredValue
+
_getValue
-- getCoords
+
getValue
-- getQualifierValue
+
getPreferredValue
-- getSumOfParts
+
getCoords
-- getValueByQual
+
getQualifierValue
-- getValueByLang
+
getSumOfParts
-- getValueByRefSource
+
getValueByQual
-- getPropOfProp
+
getValueByLang
-- getAwardCat
+
getValueByRefSource
-- getIntersectCat
+
getPropertyIDs
-- getGlobe
+
getPropOfProp
-- getCommonsLink
+
getAwardCat
-- getSiteLink
+
getIntersectCat
-- getLink
+
getGlobe
-- getLabel
+
getCommonsLink
-- getAT
+
getSiteLink
-- getDescription
+
getLink
-- getAliases
+
getLabel
-- pageId
+
getAT
-- formatDate
+
getDescription
-- location
+
getAliases
-- checkBlacklist
+
pageId
-- emptyor
+
formatDate
-- labelorid
+
location
-- getLang
+
checkBlacklist
-- findLanguage
+
emptyor
 
+
labelorid
-- getQID
+
getLang
-- followQid
+
getItemLangCode
-- siteID
+
findLanguage
-- projID
+
getQID
-- formatNumber
+
followQid
-- examine
+
globalSiteID
-- checkvalue
+
siteID
-- url2
+
projID
-- getWebsite
+
formatNumber
-- getAllLabels
+
examine
-- getAllDescriptions
+
checkvalue
-- getAllAliases
+
url2
-- showNoLinks
+
getWebsite
-- checkValidity
+
getAllLabels
 +
getAllDescriptions
 +
getAllAliases
 +
showNoLinks
 +
checkValidity
 +
getEntityFromTitle
 +
--]]
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
Anonymous user