return false, input_parm, nil, nil
end
local entity = mw.wikibase.getEntityObject(qid)
local claims
if entity and entity.claims then
claims = entity.claims[propertyID]
if not claims then
return false, "", nil, nil
end
else
return false, "", nil, nil
end
return true, entity, claims, propertyID
end
local function isType(claims, type)
return claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == type
end
local function getValue(entity, claims, propertyID, delim, labelHook)
if labelHook == nil then
labelHook = function (qnumber)
return nil;
end
end
if isType(claims, "wikibase-entityid") then
local out = {}
for k, v in pairs(claims) do
local qnumber = "Q" .. v.mainsnak.datavalue.value["numeric-id"]
local sitelink = mw.wikibase.sitelink(qnumber)
local label = labelHook(qnumber) or mw.wikibase.label(qnumber) or qnumber
if sitelink then
out[#out + 1] = "" .. label .. ""
else
out[#out + 1] = "" .. label .. "<abbr title='" .. i18n["errors"]["local-article-not-found"] .. "'>[*]</abbr>"
end
end
return table.concat(out, delim)
else
-- just return best values
return entity:formatPropertyValues(propertyID).value
end
end  
---
-- module global functions  
if debug then
function p.inspectI18n
local val = i18n
for _, key in pairs(.args) do
key = mw.text.trim(key)
val = val[key]
end
return val
end
end  
function p.descriptionIn
local langcode = .args[1]
local id = .args[2]
-- return description of a Wikidata entity in the given language or the default language of this Wikipedia site
return mw.wikibase.getEntityObject(id).descriptions[langcode or wiki.langcode].value
end  
function p.labelIn
local langcode = .args[1]
local id = .args[2]
-- return label of a Wikidata entity in the given language or the default language of this Wikipedia site
return mw.wikibase.getEntityObject(id).labels[langcode or wiki.langcode].value
end  
-- This is used to get a value, or a comma separated list of them if multiple values exist
p.getValue = function
local delimdefault = ", " -- **internationalise later**
local delim = .args.delimiter or ""
delim = string.gsub(delim, '"', '')
if #delim == 0 then
delim = delimdefault
end
local go, errorOrentity, claims, propertyID = parseInput
if not go then
return errorOrentity
end
return getValue(errorOrentity, claims, propertyID, delim)
end  
-- Same as above, but uses the short name property for label if available.
p.getValueShortName = function
local go, errorOrentity, claims, propertyID = parseInput
if not go then
return errorOrentity
end
local entity = errorOrentity
-- if wiki-linked value output as link if possible
local function labelHook (qnumber)
local label
local claimEntity = mw.wikibase.getEntity(qnumber)
if claimEntity ~= nil then
if claimEntity.claims.P1813 then
for k2, v2 in pairs(claimEntity.claims.P1813) do
if v2.mainsnak.datavalue.value.language == "en" then
label = v2.mainsnak.datavalue.value.text
end
end
end
end
if label == nil or label == "" then return nil end
return label
end
return getValue(errorOrentity, claims, propertyID, ", ", labelHook);
end  
-- This is used to get a value, or a comma separated list of them if multiple values exist
-- from an arbitrary entry by using its QID.
-- Use :
-- E.g.: - to fetch value of 'spouse' (P26) from 'Richard Burton' (Q151973)
-- Please use sparingly - this is an *expensive call*.
p.getValueFromID = function
local itemID = mw.text.trim(.args[1] or "")
local propertyID = mw.text.trim(.args[2] or "")
local input_parm = mw.text.trim(.args[3] or "")
if input_parm == "FETCH_WIKIDATA" then
local entity = mw.wikibase.getEntity(itemID)
local claims
if entity and entity.claims then
claims = entity.claims[propertyID]
end
if claims then
return getValue(entity, claims, propertyID, ", ")
else
return ""
end
else
return input_parm
end
end
local function getQualifier(, outputHook)
local propertyID = mw.text.trim(.args[1] or "")
local qualifierID = mw.text.trim(.args[2] or "")
local input_parm = mw.text.trim(.args[3] or "")
if input_parm == "FETCH_WIKIDATA" then
local entity = mw.wikibase.getEntityObject
if entity.claims[propertyID] ~= nil then
local out = {}
for k, v in pairs(entity.claims[propertyID]) do
for k2, v2 in pairs(v.qualifiers[qualifierID]) do
if v2.snaktype == 'value' then
out[#out + 1] = outputHook(v2);
end
end
end
return table.concat(out, ", "), true
else
return "", false
end
else
return input_parm, false
end
end
p.getQualifierValue = function
local function outputValue(value)
local qnumber = "Q" .. value.datavalue.value["numeric-id"]
if (mw.wikibase.sitelink(qnumber)) then
return "" .. mw.wikibase.sitelink(qnumber) .. ""
else
return "" ..qnumber .. "<abbr title='" .. i18n["errors"]["local-article-not-found"] .. "'>[*]</abbr>"
end
end
return (getQualifier(, outputValue))
end  
-- This is used to get a value like 'male' (for property p21) which won't be linked and numbers without the thousand separators
p.getRawValue = function
local go, errorOrentity, claims, propertyID = parseInput
if not go then
return errorOrentity
end
local entity = errorOrentity
local result = entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value
-- if number type: remove thousand separators, bounds and units
if isType(claims, "quantity") then
result = mw.ustring.gsub(result, "(%d),(%d)", "%1%2")
result = mw.ustring.gsub(result, "(%d)±.*", "%1")
end
return result
end  
-- This is used to get the unit name for the numeric value returned by getRawValue
p.getUnits = function
local go, errorOrentity, claims, propertyID = parseInput
if not go then
return errorOrentity
end
local entity = errorOrentity
local result = entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value
if isType(claims, "quantity") then
result = mw.ustring.sub(result, mw.ustring.find(result, " ")+1, -1)
end
return result
end  
-- This is used to get the unit's QID to use with the numeric value returned by getRawValue
p.getUnitID = function
local go, errorOrentity, claims = parseInput
if not go then
return errorOrentity
end
local entity = errorOrentity
local result
if isType(claims, "quantity") then
-- get the url for the unit entry on Wikidata:
result = claims[1].mainsnak.datavalue.value.unit
-- and just reurn the last bit from "Q" to the end (which is the QID):
result = mw.ustring.sub(result, mw.ustring.find(result, "Q"), -1)
end
return result
end  
p.getRawQualifierValue = function
local function outputHook(value)
if value.datavalue.value["numeric-id"] then
return mw.wikibase.label("Q" .. value.datavalue.value["numeric-id"])
else
return value.datavalue.value
end
end
local ret, gotData = getQualifier(, outputHook)
if gotData then
ret = string.upper(string.sub(ret, 1, 1)) .. string.sub(ret, 2)
end
return ret
end  
-- This is used to get a date value for date_of_birth (P569), etc. which won't be linked
-- Dates and times are stored in ISO 8601 format (sort of).
-- At present the local formatDate(date, precision, timezone) function doesn't handle timezone
-- So I'll just supply "Z" in the call to formatDate below:
p.getDateValue = function
local date_format = mw.text.trim(.args[3] or i18n["datetime"]["default-format"])
local date_addon = mw.text.trim(.args[4] or i18n["datetime"]["default-addon"])
local go, errorOrentity, claims = parseInput
if not go then
return errorOrentity
end
local entity = errorOrentity
local out = {}
for k, v in pairs(claims) do
if v.mainsnak.datavalue.type == 'time' then
local timestamp = v.mainsnak.datavalue.value.time
local dateprecision = v.mainsnak.datavalue.value.precision
-- 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",
-- and that's the last day of 1871, so the year is wrong.
-- So fix the month 0, day 0 timestamp to become 1 January instead:
timestamp = timestamp:gsub("%-00%-00T", "-01-01T")
out[#out + 1] = parseDateFull(timestamp, dateprecision, date_format, date_addon)
end
end
return table.concat(out, ", ")
end
p.getQualifierDateValue = function