Changes

13,178 bytes removed ,  00:49, 29 November 2020
no edit summary
Line 1: Line 1: −
-- vim: set noexpandtab ft=lua ts=4 sw=4:
  −
require('Module:No globals')
  −
   
local p = {}
 
local p = {}
local debug = false
  −
  −
  −
------------------------------------------------------------------------------
  −
-- module local variables and functions
     −
local wiki =
+
-- module local variables
 +
local wiki =  
 
{
 
{
 
langcode = mw.language.getContentLanguage().code
 
langcode = mw.language.getContentLanguage().code
Line 15: Line 8:     
-- internationalisation
 
-- internationalisation
local i18n =
+
local i18n = {
{
+
    ["errors"] = {
["errors"] =
+
        ["property-not-found"] = "Property not found.",
{
+
        ["entity-not-found"] = "Wikidata entity not found.",
["property-not-found"] = "Property not found.",
+
        ["unknown-claim-type"] = "Unknown claim type.",
["entity-not-found"] = "Wikidata entity not found.",
+
        ["unknown-entity-type"] = "Unknown entity type.",
["unknown-claim-type"] = "Unknown claim type.",
+
        ["qualifier-not-found"] = "Qualifier not found.",
["unknown-entity-type"] = "Unknown entity type.",
+
        ["site-not-found"] = "Wikimedia project not found.",
["qualifier-not-found"] = "Qualifier not found.",
+
    },
["site-not-found"] = "Wikimedia project not found.",
+
    ["datetime"] =
["unknown-datetime-format"] = "Unknown datetime format.",
  −
["local-article-not-found"] = "Article is not yet available in this wiki."
  −
},
  −
["datetime"] =
   
{
 
{
 
-- $1 is a placeholder for the actual number
 
-- $1 is a placeholder for the actual number
Line 37: Line 26:  
[4] = "$100,000 years", -- precision: hundred thousand years
 
[4] = "$100,000 years", -- precision: hundred thousand years
 
[5] = "$10,000 years", -- precision: ten thousand years
 
[5] = "$10,000 years", -- precision: ten thousand years
[6] = "$1 millennium", -- precision: millennium
+
[6] = "$1 millenium", -- precision: millennium
 
[7] = "$1 century", -- precision: century
 
[7] = "$1 century", -- precision: century
 
[8] = "$1s", -- precision: decade
 
[8] = "$1s", -- precision: decade
 
-- the following use the format of #time parser function
 
-- the following use the format of #time parser function
[9]  = "Y", -- precision: year,
+
[9]  = "Y", -- precision: year,  
 
[10] = "F Y", -- precision: month
 
[10] = "F Y", -- precision: month
 
[11] = "F j, Y", -- precision: day
 
[11] = "F j, Y", -- precision: day
Line 50: Line 39:  
["afternow"] = "$1 CE", -- how to format positive numbers for precisions 0 to 5
 
["afternow"] = "$1 CE", -- how to format positive numbers for precisions 0 to 5
 
["bc"] = '$1 "BCE"', -- how print negative years
 
["bc"] = '$1 "BCE"', -- how print negative years
["ad"] = "$1", -- how print positive years
+
["ad"] = "$1" -- how print positive years
-- the following are for function getDateValue() and getQualifierDateValue()
  −
["default-format"] = "dmy", -- default value of the #3 (getDateValue) or
  −
-- #4 (getQualifierDateValue) argument
  −
["default-addon"] = "BC", -- default value of the #4 (getDateValue) or
  −
-- #5 (getQualifierDateValue) argument
  −
["prefix-addon"] = false, -- set to true for languages put "BC" in front of the
  −
-- datetime string; or the addon will be suffixed
  −
["addon-sep"] = " ", -- separator between datetime string and addon (or inverse)
  −
["format"] = -- options of the 3rd argument
  −
{
  −
["mdy"] = "F j, Y",
  −
["my"] = "F Y",
  −
["y"] = "Y",
  −
["dmy"] = "j F Y",
  −
["ymd"] = "Y-m-d",
  −
["ym"] = "Y-m"
  −
}
   
},
 
},
 
["monolingualtext"] = '<span lang="%language">%text</span>',
 
["monolingualtext"] = '<span lang="%language">%text</span>',
["warnDump"] = "[[Category:Called function 'Dump' from module Wikidata]]",
+
["warnDump"] = "[[Category:Called function 'Dump' from module Wikidata]]"
["ordinal"] =
  −
{
  −
[1] = "st",
  −
[2] = "nd",
  −
[3] = "rd",
  −
["default"] = "th"
  −
}
   
}
 
}
   −
if wiki.langcode ~= "en" then
+
function p.descriptionIn(frame)
--require("Module:i18n").loadI18n("Module:Wikidata/i18n", i18n)
+
local langcode = frame.args[1]
-- got idea from [[:w:Module:Wd]]
+
local id = frame.args[2] -- "id" must be nil, as access to other Wikidata objects is disabled in Mediawiki configuration
local module_title; if ... == nil then
+
-- return description of a Wikidata entity in the given language or the default language of this Wikipedia site
module_title = mw.getCurrentFrame():getTitle()
+
return mw.wikibase.getEntityObject(id).descriptions[langcode or wiki.langcode].value
else
  −
module_title = ...
  −
end
  −
require('Module:i18n').loadI18n(module_title..'/i18n', i18n)
   
end
 
end
   −
-- this function needs to be internationalised along with the above:
+
function p.labelIn(frame)
-- takes cardinal numer as a numeric and returns the ordinal as a string
+
local langcode = frame.args[1]
-- we need three exceptions in English for 1st, 2nd, 3rd, 21st, .. 31st, etc.
+
local id = frame.args[2] -- "id" must be nil, as access to other Wikidata objects is disabled in Mediawiki configuration
local function makeOrdinal (cardinal)
+
-- return label of a Wikidata entity in the given language or the default language of this Wikipedia site
local ordsuffix = i18n.ordinal.default
+
return mw.wikibase.getEntityObject(id).labels[langcode or wiki.langcode].value
if cardinal % 10 == 1 then
  −
ordsuffix = i18n.ordinal[1]
  −
elseif cardinal % 10 == 2 then
  −
ordsuffix = i18n.ordinal[2]
  −
elseif cardinal % 10 == 3 then
  −
ordsuffix = i18n.ordinal[3]
  −
end
  −
-- In English, 1, 21, 31, etc. use 'st', but 11, 111, etc. use 'th'
  −
-- similarly for 12 and 13, etc.
  −
if (cardinal % 100 == 11) or (cardinal % 100 == 12) or (cardinal % 100 == 13) then
  −
ordsuffix = i18n.ordinal.default
  −
end
  −
return tostring(cardinal) .. ordsuffix
   
end
 
end
   −
local function printError(code)
+
-- This is used to get a value, or a comma separated list of them if multiple values exist
return '<span class="error">' .. (i18n.errors[code] or code) .. '</span>'
+
p.getValue = function(frame)
end
+
local propertyID = mw.text.trim(frame.args[1] or "")
local function parseDateFormat(f, timestamp, addon, prefix_addon, addon_sep)  
+
local input_parm = mw.text.trim(frame.args[2] or "")
local year_suffix
+
if input_parm == "FETCH_WIKIDATA" then
local tstr = ""
+
local entity = mw.wikibase.getEntityObject()
local lang_obj = mw.language.new(wiki.langcode)
+
local claims = entity.claims[propertyID]
local f_parts = mw.text.split(f, 'Y', true)
+
if claims then
for idx, f_part in pairs(f_parts) do
+
-- if wiki-linked value output as link if possible
year_suffix = ''
+
if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
if string.match(f_part, "x[mijkot]$") then
+
local out = {}
-- for non-Gregorian year
+
for k, v in pairs(claims) do
f_part = f_part .. 'Y'
+
local sitelink = mw.wikibase.sitelink("Q" .. v.mainsnak.datavalue.value["numeric-id"])
elseif idx < #f_parts then
+
local label = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"])
-- supress leading zeros in year
+
if label == nil then label = "Q" .. v.mainsnak.datavalue.value["numeric-id"] end
year_suffix = lang_obj:formatDate('Y', timestamp)
+
year_suffix = string.gsub(year_suffix, '^0+', '', 1)
+
if sitelink then
 +
out[#out + 1] = "[[" .. sitelink .. "|" .. label .. "]]"
 +
else
 +
out[#out + 1] = "[[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]<abbr title='Article is not yet available in this wiki'>[*]</abbr>"
 +
end
 +
end
 +
return table.concat(out, ", ")
 +
else
 +
return entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value
 +
end
 +
else
 +
return ""
 
end
 
end
tstr = tstr .. lang_obj:formatDate(f_part, timestamp) .. year_suffix
  −
end
  −
if addon ~= "" and prefix_addon then
  −
return addon .. addon_sep .. tstr
  −
elseif addon ~= "" then
  −
return tstr .. addon_sep .. addon
   
else
 
else
return tstr
+
return input_parm
 
end
 
end
 
end
 
end
local function parseDateValue(timestamp, date_format, date_addon)
  −
local prefix_addon = i18n["datetime"]["prefix-addon"]
  −
local addon_sep = i18n["datetime"]["addon-sep"]
  −
local addon = ""
     −
-- check for negative date
+
p.getQualifierValue = function(frame)
if string.sub(timestamp, 1, 1) == '-' then
+
local propertyID = mw.text.trim(frame.args[1] or "")
timestamp = '+' .. string.sub(timestamp, 2)
+
local qualifierID = mw.text.trim(frame.args[2] or "")
addon = date_addon
+
local input_parm = mw.text.trim(frame.args[3] or "")
end
+
if input_parm == "FETCH_WIKIDATA" then
local _date_format = i18n["datetime"]["format"][date_format]
+
local entity = mw.wikibase.getEntityObject()
if _date_format ~= nil then
+
if entity.claims[propertyID] ~= nil then
return parseDateFormat(_date_format, timestamp, addon, prefix_addon, addon_sep)
+
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
 +
if (mw.wikibase.sitelink("Q" .. v2.datavalue.value["numeric-id"])) then
 +
out[#out + 1] = "[[" .. mw.wikibase.sitelink("Q" .. v2.datavalue.value["numeric-id"]) .. "]]"
 +
else
 +
out[#out + 1] = "[[:d:Q" .. v2.datavalue.value["numeric-id"] .. "|" .. mw.wikibase.label("Q" .. v2.datavalue.value["numeric-id"]) .. "]]<abbr title='Article is not yet available in this wiki'>[*]</abbr>"
 +
end
 +
end
 +
end
 +
end
 +
return table.concat(out, ", ")
 +
else
 +
return ""
 +
end
 
else
 
else
return printError("unknown-datetime-format")
+
return input_parm
 
end
 
end
 
end
 
end
   −
-- This local function combines the year/month/day/BC/BCE handling of parseDateValue{}
+
-- This is used to get a value like 'male' (for property p21) which won't be linked and numbers without the thousand separators
-- with the millennium/century/decade handling of formatDate()
+
p.getRawValue = function(frame)
local function parseDateFull(timestamp, precision, date_format, date_addon)
+
local propertyID = mw.text.trim(frame.args[1] or "")
local prefix_addon = i18n["datetime"]["prefix-addon"]
+
local input_parm = mw.text.trim(frame.args[2] or "")
local addon_sep = i18n["datetime"]["addon-sep"]
+
if input_parm == "FETCH_WIKIDATA" then
local addon = ""
+
local entity = mw.wikibase.getEntityObject()
 
+
if entity then claims = entity.claims[propertyID] end
-- check for negative date
+
if claims then
if string.sub(timestamp, 1, 1) == '-' then
+
local result = entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value
timestamp = '+' .. string.sub(timestamp, 2)
+
addon = date_addon
+
-- if number type: remove thousand separators
 +
if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "quantity") then
 +
result = mw.ustring.gsub(result, "(%d),(%d)", "%1%2")
 +
end
 +
return result
 +
else
 +
return ""
 +
end
 +
else
 +
return input_parm
 
end
 
end
 +
end
   −
-- get the next four characters after the + (should be the year now in all cases)
+
p.getRawQualifierValue = function(frame)
-- ok, so this is dirty, but let's get it working first
+
local propertyID = mw.text.trim(frame.args[1] or "")
local intyear = tonumber(string.sub(timestamp, 2, 5))
+
local qualifierID = mw.text.trim(frame.args[2] or "")
if intyear == 0 and precision <= 9 then
+
local input_parm = mw.text.trim(frame.args[3] or "")
return ""
+
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
 +
if v2.datavalue.value["numeric-id"] then
 +
out[#out + 1] = mw.wikibase.label("Q" .. v2.datavalue.value["numeric-id"])
 +
else
 +
out[#out + 1] = v2.datavalue.value
 +
end
 +
end
 +
end
 +
end
 +
local ret = table.concat(out, ", ")
 +
return string.upper(string.sub(ret, 1, 1)) .. string.sub(ret, 2)
 +
else
 +
return ""
 +
end
 +
else
 +
return input_parm
 
end
 
end
 +
end
   −
-- precision is 10000 years or more
+
-- This is used to get a date value for date_of_birth (P569), etc. which won't
if precision <= 5 then
+
-- be linked -- consolidate by testing if entity.claims[propertyID].mainsnak.datavalue.type
local factor = 10 ^ ((5 - precision) + 4)
+
-- is "time". Dates and times are stored in ISO 8601 format.
local y2 = math.ceil(math.abs(intyear) / factor)
+
p.getDateValue = function(frame)
local relative = mw.ustring.gsub(i18n.datetime[precision], "$1", tostring(y2))
+
local propertyID = mw.text.trim(frame.args[1] or "")
if addon ~= "" then
+
local input_parm = mw.text.trim(frame.args[2] or "")
-- negative date
+
local date_format = mw.text.trim(frame.args[3] or "dmy")
relative = mw.ustring.gsub(i18n.datetime.beforenow, "$1", relative)
+
if input_parm == "FETCH_WIKIDATA" then
 +
local entity = mw.wikibase.getEntityObject()
 +
if entity.claims[propertyID] ~= nil then
 +
local out = {}
 +
local dt = {}
 +
for k, v in pairs(entity.claims[propertyID]) do
 +
if v.mainsnak.snaktype == 'value' then
 +
local function d(f)
 +
return mw.language.new(wiki.langcode):formatDate(f, v2.datavalue.value.time)
 +
end
 +
if date_format == "mdy" then
 +
out[#out + 1] = d("F j, Y")
 +
elseif date_format == "my" then
 +
out[#out + 1] = d("F Y")
 +
elseif date_format == "y" then
 +
out[#out + 1] = d("Y")
 +
else
 +
out[#out + 1] = d("j F Y")
 +
end
 +
end
 +
end
 +
return table.concat(out, ", ")
 
else
 
else
relative = mw.ustring.gsub(i18n.datetime.afternow, "$1", relative)
+
return ""
 
end
 
end
return relative
+
else
 +
return input_parm
 
end
 
end
 +
end
   −
-- precision is decades (8), centuries (7) and millennia (6)
+
p.getQualifierDateValue = function(frame)
local era, card
+
local propertyID = mw.text.trim(frame.args[1] or "")
if precision == 6 then
+
local qualifierID = mw.text.trim(frame.args[2] or "")
card = math.floor((intyear - 1) / 1000) + 1
+
local input_parm = mw.text.trim(frame.args[3] or "")
era = mw.ustring.gsub(i18n.datetime[6], "$1", makeOrdinal(card))
+
local date_format = mw.text.trim(frame.args[4] or "dmy")
end
+
if input_parm == "FETCH_WIKIDATA" then
if precision == 7 then
+
local entity = mw.wikibase.getEntityObject()
card = math.floor((intyear - 1) / 100) + 1
+
if entity.claims[propertyID] ~= nil then
era = mw.ustring.gsub(i18n.datetime[7], "$1", makeOrdinal(card))
+
local out = {}
end
+
for k, v in pairs(entity.claims[propertyID]) do
if precision == 8 then
+
for k2, v2 in pairs(v.qualifiers[qualifierID]) do
era = mw.ustring.gsub(i18n.datetime[8], "$1", tostring(math.floor(math.abs(intyear) / 10) * 10))
+
if v2.snaktype == 'value' then
end
+
local function d(f)
if era then
+
return mw.language.new(wiki.langcode):formatDate(f, v2.datavalue.value.time)
if addon ~= "" then
+
end
era = mw.ustring.gsub(mw.ustring.gsub(i18n.datetime.bc, '"', ""), "$1", era)
+
if date_format == "mdy" then
 +
out[#out + 1] = d("F j, Y")
 +
elseif date_format == "my" then
 +
out[#out + 1] = d("F Y")
 +
elseif date_format == "y" then
 +
out[#out + 1] = d("Y")
 +
else
 +
out[#out + 1] = d("j F Y")
 +
end
 +
end
 +
end
 +
end
 +
return table.concat(out, ", ")
 
else
 
else
era = mw.ustring.gsub(mw.ustring.gsub(i18n.datetime.ad, '"', ""), "$1", era)
+
return ""
 
end
 
end
return era
+
else
 +
return input_parm
 
end
 
end
 +
end
   −
local _date_format = i18n["datetime"]["format"][date_format]
+
-- This is used to get the TA98 (Terminologia Anatomica first edition 1998) values like 'A01.1.00.005' (property P1323)
if _date_format ~= nil then
+
-- which are then linked to http://www.unifr.ch/ifaa/Public/EntryPage/TA98%20Tree/Entity%20TA98%20EN/01.1.00.005%20Entity%20TA98%20EN.htm
-- check for precision is year and override supplied date_format
+
-- uses the newer mw.wikibase calls instead of directly using the snaks
if precision == 9 then
+
-- formatPropertyValues returns a table with the P1323 values concatenated with ", " so we have to split them out into a table in order to construct the return string
_date_format = i18n["datetime"][9]
+
p.getTAValue = function(frame)
 +
local ent = mw.wikibase.getEntityObject()
 +
local props = ent:formatPropertyValues('P1323')
 +
local out = {}
 +
local t = {}
 +
for k, v in pairs(props) do
 +
if k == 'value' then
 +
t = mw.text.split( v, ", ")
 +
for k2, v2 in pairs(t) do
 +
out[#out + 1] = "[http://www.unifr.ch/ifaa/Public/EntryPage/TA98%20Tree/Entity%20TA98%20EN/" .. string.sub(v2, 2) .. "%20Entity%20TA98%20EN.htm " .. v2 .. "]"
 +
end
 
end
 
end
return parseDateFormat(_date_format, timestamp, addon, prefix_addon, addon_sep)
  −
else
  −
return printError("unknown-datetime-format")
   
end
 
end
 +
ret = table.concat(out, "<br> ")
 +
if #ret == 0 then
 +
ret = "Invalid TA"
 +
end
 +
return ret
 +
end
 +
 +
-- returns the page id (Q...) of the current page or nothing of the page is not connected to Wikidata
 +
function p.pageId(frame)
 +
local entity = mw.wikibase.getEntityObject()
 +
if not entity then return nil else return entity.id end
 
end
 
end
   Line 230: Line 281:  
local function orderedpairs(array, order)
 
local function orderedpairs(array, order)
 
if not order then return pairs(array) end
 
if not order then return pairs(array) end
 
+
 
-- return iterator function
 
-- return iterator function
local i = 0
+
    local i = 0
return function()
+
    return function()
i = i + 1
+
        i = i + 1
if order[i] then
+
        if order[i] then
return order[i], array[order[i]]
+
            return order[i], array[order[i]]
end
+
        end
end
+
    end
 
end
 
end
   Line 251: Line 302:  
end
 
end
   −
local function formatDate(date, precision, timezone)
+
function formatDate(date, precision, timezone)
 
precision = precision or 11
 
precision = precision or 11
local date, year = normalizeDate(date)
+
date, year = normalizeDate(date)
 
if year == 0 and precision <= 9 then return "" end
 
if year == 0 and precision <= 9 then return "" end
 
+
-- precision is 10000 years or more
+
-- precision is 10000 years or more
 
if precision <= 5 then
 
if precision <= 5 then
 
local factor = 10 ^ ((5 - precision) + 4)
 
local factor = 10 ^ ((5 - precision) + 4)
Line 265: Line 316:  
else
 
else
 
relative = mw.ustring.gsub(i18n.datetime.afternow, "$1", relative)
 
relative = mw.ustring.gsub(i18n.datetime.afternow, "$1", relative)
end
+
end
 
return relative
 
return relative
 
end
 
end
 
+
-- precision is decades, centuries and millennia
+
-- precision is decades, centuries and millennia
 
local era
 
local era
 
if precision == 6 then era = mw.ustring.gsub(i18n.datetime[6], "$1", tostring(math.floor((math.abs(year) - 1) / 1000) + 1)) end
 
if precision == 6 then era = mw.ustring.gsub(i18n.datetime[6], "$1", tostring(math.floor((math.abs(year) - 1) / 1000) + 1)) end
Line 279: Line 330:  
return era
 
return era
 
end
 
end
 
+
-- precision is year
+
-- precision is year
if precision == 9 then
+
if precision == 9 then
return year
+
return year
end
+
end
 
+
 
-- precision is less than years
 
-- precision is less than years
 
if precision > 9 then
 
if precision > 9 then
Line 296: Line 347:  
end
 
end
 
]]--
 
]]--
 
+
 
local formatstr = i18n.datetime[precision]
 
local formatstr = i18n.datetime[precision]
 
if year == 0 then formatstr = mw.ustring.gsub(formatstr, i18n.datetime[9], "")
 
if year == 0 then formatstr = mw.ustring.gsub(formatstr, i18n.datetime[9], "")
Line 313: Line 364:  
-- data fields: entity-type [string], numeric-id [int, Wikidata id]
 
-- data fields: entity-type [string], numeric-id [int, Wikidata id]
 
local id
 
local id
 
+
 
if data["entity-type"] == "item" then id = "Q" .. data["numeric-id"]
 
if data["entity-type"] == "item" then id = "Q" .. data["numeric-id"]
 
elseif data["entity-type"] == "property" then id = "P" .. data["numeric-id"]
 
elseif data["entity-type"] == "property" then id = "P" .. data["numeric-id"]
 
else return printError("unknown-entity-type")
 
else return printError("unknown-entity-type")
 
end
 
end
 
+
 
if parameter then
 
if parameter then
 
if parameter == "link" then
 
if parameter == "link" then
Line 325: Line 376:  
if linkTarget then
 
if linkTarget then
 
-- if there is a local Wikipedia article link to it using the label or the article title
 
-- if there is a local Wikipedia article link to it using the label or the article title
return "[[" .. linkTarget .. "|" .. (linkName or linkTarget) .. "]]"
+
return "[[" .. linkTarget .. "|" .. (linkName or linkTarget) .. "]]"
 
else
 
else
 
-- if there is no local Wikipedia article output the label or link to the Wikidata object to let the user input a proper label
 
-- if there is no local Wikipedia article output the label or link to the Wikidata object to let the user input a proper label
Line 361: Line 412:  
end
 
end
   −
local function findClaims(entity, property)
+
function findClaims(entity, property)
 
if not property or not entity or not entity.claims then return end
 
if not property or not entity or not entity.claims then return end
 
+
 
if mw.ustring.match(property, "^P%d+$") then
 
if mw.ustring.match(property, "^P%d+$") then
 
-- if the property is given by an id (P..) access the claim list by this id
 
-- if the property is given by an id (P..) access the claim list by this id
 
return entity.claims[property]
 
return entity.claims[property]
 
else
 
else
property = mw.wikibase.resolvePropertyId(property)
+
-- otherwise, iterate over all properties, fetch their labels and compare this to the given property name
if not property then return end
+
for k, v in pairs(entity.claims) do
 
+
if mw.wikibase.label(k) == property then return v end
return entity.claims[property]
+
end
 +
return
 
end
 
end
 
end
 
end
   −
local function getSnakValue(snak, parameter)
+
function getSnakValue(snak, parameter)
 
if snak.snaktype == "value" then
 
if snak.snaktype == "value" then
 
-- call the respective snak parser
 
-- call the respective snak parser
Line 388: Line 440:  
return mw.wikibase.renderSnak(snak)
 
return mw.wikibase.renderSnak(snak)
 
end
 
end
 
+
local function getQualifierSnak(claim, qualifierId)
+
function getQualifierSnak(claim, qualifierId)
 
-- a "snak" is Wikidata terminology for a typed key/value pair
 
-- a "snak" is Wikidata terminology for a typed key/value pair
 
-- a claim consists of a main snak holding the main information of this claim,
 
-- a claim consists of a main snak holding the main information of this claim,
Line 405: Line 457:  
end
 
end
 
end
 
end
 
+
local function getValueOfClaim(claim, qualifierId, parameter)
+
function getValueOfClaim(claim, qualifierId, parameter)
 
local error
 
local error
 
local snak
 
local snak
Line 417: Line 469:  
end
 
end
   −
local function getReferences(frame, claim)
+
function getReferences(frame, claim)
 
local result = ""
 
local result = ""
 
-- traverse through all references
 
-- traverse through all references
Line 426: Line 478:  
if refparts then refparts = refparts .. ", " else refparts = "" end
 
if refparts then refparts = refparts .. ", " else refparts = "" end
 
-- output the label of the property of the reference part, e.g. "imported from" for P143
 
-- output the label of the property of the reference part, e.g. "imported from" for P143
refparts = refparts .. tostring(mw.wikibase.label(snakkey)) .. ": "
+
refparts = refparts .. tostring(mw.wikibase.label(snakkey)) .. ": "  
 
-- output all values of this reference part, e.g. "German Wikipedia" and "English Wikipedia" if the referenced claim was imported from both sites
 
-- output all values of this reference part, e.g. "German Wikipedia" and "English Wikipedia" if the referenced claim was imported from both sites
 
for snakidx = 1, #snakval do
 
for snakidx = 1, #snakval do
Line 436: Line 488:  
end
 
end
 
return result
 
return result
end
  −
  −
local function parseInput(frame)
  −
local qid = frame.args.qid
  −
if qid and (#qid == 0) then qid = nil end
  −
local propertyID = mw.text.trim(frame.args[1] or "")
  −
local input_parm = mw.text.trim(frame.args[2] or "")
  −
if input_parm ~= "FETCH_WIKIDATA" then
  −
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] = "[[" .. sitelink .. "|" .. label .. "]]"
  −
else
  −
out[#out + 1] = "[[:d:" .. qnumber .. "|" .. 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(frame)
  −
local val = i18n
  −
for _, key in pairs(frame.args) do
  −
key = mw.text.trim(key)
  −
val = val[key]
  −
end
  −
return val
  −
end
  −
end
  −
  −
function p.descriptionIn(frame)
  −
local langcode = frame.args[1]
  −
local id = frame.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(frame)
  −
local langcode = frame.args[1]
  −
local id = frame.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(frame)
  −
local delimdefault = ", " -- **internationalise later**
  −
local delim = frame.args.delimiter or ""
  −
delim = string.gsub(delim, '"', '')
  −
if #delim == 0 then
  −
delim = delimdefault
  −
end
  −
local go, errorOrentity, claims, propertyID = parseInput(frame)
  −
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(frame)
  −
local go, errorOrentity, claims, propertyID = parseInput(frame)
  −
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 : {{#invoke:Wikidata|getValueFromID|<ID>|<Property>|FETCH_WIKIDATA}}
  −
-- E.g.: {{#invoke:Wikidata|getValueFromID|Q151973|P26|FETCH_WIKIDATA}} - to fetch value of 'spouse' (P26) from 'Richard Burton' (Q151973)
  −
-- Please use sparingly - this is an *expensive call*.
  −
p.getValueFromID = function(frame)
  −
local itemID = mw.text.trim(frame.args[1] or "")
  −
local propertyID = mw.text.trim(frame.args[2] or "")
  −
local input_parm = mw.text.trim(frame.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(frame, outputHook)
  −
local propertyID = mw.text.trim(frame.args[1] or "")
  −
local qualifierID = mw.text.trim(frame.args[2] or "")
  −
local input_parm = mw.text.trim(frame.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(frame)
  −
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 "[[:d:" .. qnumber .. "|" ..qnumber .. "]]<abbr title='" .. i18n["errors"]["local-article-not-found"] .. "'>[*]</abbr>"
  −
end
  −
end
  −
return (getQualifier(frame, 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(frame)
  −
local go, errorOrentity, claims, propertyID = parseInput(frame)
  −
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(frame)
  −
local go, errorOrentity, claims, propertyID = parseInput(frame)
  −
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(frame)
  −
local go, errorOrentity, claims = parseInput(frame)
  −
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(frame)
  −
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(frame, 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(frame)
  −
local date_format = mw.text.trim(frame.args[3] or i18n["datetime"]["default-format"])
  −
local date_addon = mw.text.trim(frame.args[4] or i18n["datetime"]["default-addon"])
  −
local go, errorOrentity, claims = parseInput(frame)
  −
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(frame)
  −
local date_format = mw.text.trim(frame.args[4] or i18n["datetime"]["default-format"])
  −
local date_addon = mw.text.trim(frame.args[5] or i18n["datetime"]["default-addon"])
  −
local function outputHook(value)
  −
local timestamp = value.datavalue.value.time
  −
return parseDateValue(timestamp, date_format, date_addon)
  −
end
  −
return (getQualifier(frame, outputHook))
  −
end
  −
  −
-- This is used to fetch all of the images with a particular property, e.g. image (P18), Gene Atlas Image (P692), etc.
  −
-- Parameters are | propertyID | value / FETCH_WIKIDATA / nil | separator (default=space) | size (default=frameless)
  −
-- It will return a standard wiki-markup [[File:Filename | size]] for each image with a selectable size and separator (which may be html)
  −
-- e.g. {{#invoke:Wikidata|getImages|P18|FETCH_WIKIDATA}}
  −
-- e.g. {{#invoke:Wikidata|getImages|P18|FETCH_WIKIDATA|<br>|250px}}
  −
-- If a property is chosen that is not of type "commonsMedia", it will return empty text.
  −
p.getImages = function(frame)
  −
local sep = mw.text.trim(frame.args[3] or " ")
  −
local imgsize = mw.text.trim(frame.args[4] or "frameless")
  −
local go, errorOrentity, claims = parseInput(frame)
  −
if not go then
  −
return errorOrentity
  −
end
  −
local entity = errorOrentity
  −
if (claims[1] and claims[1].mainsnak.datatype == "commonsMedia") then
  −
local out = {}
  −
for k, v in pairs(claims) do
  −
local filename = v.mainsnak.datavalue.value
  −
out[#out + 1] = "[[File:" .. filename .. "|" .. imgsize .. "]]"
  −
end
  −
return table.concat(out, sep)
  −
else
  −
return ""
  −
end
  −
end
  −
  −
-- This is used to get the TA98 (Terminologia Anatomica first edition 1998) values like 'A01.1.00.005' (property P1323)
  −
-- which are then linked to http://www.unifr.ch/ifaa/Public/EntryPage/TA98%20Tree/Entity%20TA98%20EN/01.1.00.005%20Entity%20TA98%20EN.htm
  −
-- uses the newer mw.wikibase calls instead of directly using the snaks
  −
-- formatPropertyValues returns a table with the P1323 values concatenated with ", " so we have to split them out into a table in order to construct the return string
  −
p.getTAValue = function(frame)
  −
local ent = mw.wikibase.getEntityObject()
  −
local props = ent:formatPropertyValues('P1323')
  −
local out = {}
  −
local t = {}
  −
for k, v in pairs(props) do
  −
if k == 'value' then
  −
t = mw.text.split( v, ", ")
  −
for k2, v2 in pairs(t) do
  −
out[#out + 1] = "[http://www.unifr.ch/ifaa/Public/EntryPage/TA98%20Tree/Entity%20TA98%20EN/" .. string.sub(v2, 2) .. "%20Entity%20TA98%20EN.htm " .. v2 .. "]"
  −
end
  −
end
  −
end
  −
local ret = table.concat(out, "<br> ")
  −
if #ret == 0 then
  −
ret = "Invalid TA"
  −
end
  −
return ret
  −
end
  −
  −
--[[
  −
This is used to return an image legend from Wikidata
  −
image is property P18
  −
image legend is property P2096
  −
  −
Call as {{#invoke:Wikidata |getImageLegend | <PARAMETER> | lang=<ISO-639code> |id=<QID>}}
  −
Returns PARAMETER, unless it is equal to "FETCH_WIKIDATA", from Item QID (expensive call)
  −
If QID is omitted or blank, the current article is used (not an expensive call)
  −
If lang is omitted, it uses the local wiki language, otherwise it uses the provided ISO-639 language code
  −
ISO-639: https://docs.oracle.com/cd/E13214_01/wli/docs92/xref/xqisocodes.html#wp1252447
  −
  −
Ranks are: 'preferred' > 'normal'
  −
This returns the label from the first image with 'preferred' rank
  −
Or the label from the first image with 'normal' rank if preferred returns nothing
  −
Ranks: https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua
  −
]]
  −
  −
p.getImageLegend = function(frame)
  −
-- look for named parameter id; if it's blank make it nil
  −
local id = frame.args.id
  −
if id and (#id == 0) then
  −
id = nil
  −
end
  −
  −
-- look for named parameter lang
  −
-- it should contain a two-character ISO-639 language code
  −
-- if it's blank fetch the language of the local wiki
  −
local lang = frame.args.lang
  −
if (not lang) or (#lang < 2) then
  −
lang = mw.language.getContentLanguage().code
  −
end
  −
  −
-- first unnamed parameter is the local parameter, if supplied
  −
local input_parm = mw.text.trim(frame.args[1] or "")
  −
if input_parm == "FETCH_WIKIDATA" then
  −
local ent = mw.wikibase.getEntityObject(id)
  −
local imgs
  −
if ent and ent.claims then
  −
imgs = ent.claims.P18
  −
end
  −
local imglbl
  −
if imgs then
  −
-- look for an image with 'preferred' rank
  −
for k1, v1 in pairs(imgs) do
  −
if v1.rank == "preferred" and v1.qualifiers and v1.qualifiers.P2096 then
  −
local imglbls = v1.qualifiers.P2096
  −
for k2, v2 in pairs(imglbls) do
  −
if v2.datavalue.value.language == lang then
  −
imglbl = v2.datavalue.value.text
  −
break
  −
end
  −
end
  −
end
  −
end
  −
-- if we don't find one, look for an image with 'normal' rank
  −
if (not imglbl) then
  −
for k1, v1 in pairs(imgs) do
  −
if v1.rank == "normal" and v1.qualifiers and v1.qualifiers.P2096 then
  −
local imglbls = v1.qualifiers.P2096
  −
for k2, v2 in pairs(imglbls) do
  −
if v2.datavalue.value.language == lang then
  −
imglbl = v2.datavalue.value.text
  −
break
  −
end
  −
end
  −
end
  −
end
  −
end
  −
end
  −
return imglbl
  −
else
  −
return input_parm
  −
end
  −
end
  −
  −
-- This is used to get the QIDs of all of the values of a property, as a comma separated list if multiple values exist
  −
-- Usage: {{#invoke:Wikidata |getPropertyIDs |<PropertyID> |FETCH_WIKIDATA}}
  −
-- Usage: {{#invoke:Wikidata |getPropertyIDs |<PropertyID> |<InputParameter> |qid=<QID>}}
  −
  −
p.getPropertyIDs = function(frame)
  −
local go, errorOrentity, propclaims = parseInput(frame)
  −
if not go then
  −
return errorOrentity
  −
end
  −
local entity = errorOrentity
  −
-- if wiki-linked value collect the QID in a table
  −
if (propclaims[1] and propclaims[1].mainsnak.snaktype == "value" and propclaims[1].mainsnak.datavalue.type == "wikibase-entityid") then
  −
local out = {}
  −
for k, v in pairs(propclaims) do
  −
out[#out + 1] = "Q" .. v.mainsnak.datavalue.value["numeric-id"]
  −
end
  −
return table.concat(out, ", ")
  −
else
  −
-- not a wikibase-entityid, so return empty
  −
return ""
  −
end
  −
end
  −
  −
-- returns the page id (Q...) of the current page or nothing of the page is not connected to Wikidata
  −
function p.pageId(frame)
  −
local entity = mw.wikibase.getEntityObject()
  −
if not entity then return nil else return entity.id end
   
end
 
end
    
function p.claim(frame)
 
function p.claim(frame)
 
local property = frame.args[1] or ""
 
local property = frame.args[1] or ""
local id = frame.args["id"]
+
local id = frame.args["id"] -- "id" must be nil, as access to other Wikidata objects is disabled in Mediawiki configuration
 
local qualifierId = frame.args["qualifier"]
 
local qualifierId = frame.args["qualifier"]
 
local parameter = frame.args["parameter"]
 
local parameter = frame.args["parameter"]
Line 877: Line 500:  
local default = frame.args["default"]
 
local default = frame.args["default"]
 
if default then showerrors = nil end
 
if default then showerrors = nil end
 
+
 
-- get wikidata entity
 
-- get wikidata entity
 
local entity = mw.wikibase.getEntityObject(id)
 
local entity = mw.wikibase.getEntityObject(id)
Line 888: Line 511:  
if showerrors then return printError("property-not-found") else return default end
 
if showerrors then return printError("property-not-found") else return default end
 
end
 
end
 
+
 
-- get initial sort indices
 
-- get initial sort indices
 
local sortindices = {}
 
local sortindices = {}
Line 897: Line 520:  
local comparator = function(a, b)
 
local comparator = function(a, b)
 
local rankmap = { deprecated = 2, normal = 1, preferred = 0 }
 
local rankmap = { deprecated = 2, normal = 1, preferred = 0 }
local ranka = rankmap[claims[a].rank or "normal"] .. string.format("%08d", a)
+
local ranka = rankmap[claims[a].rank or "normal"] .. string.format("%08d", a)
local rankb = rankmap[claims[b].rank or "normal"] .. string.format("%08d", b)
+
local rankb = rankmap[claims[b].rank or "normal"] .. string.format("%08d", b)
 
return ranka < rankb
 
return ranka < rankb
end
+
end
 
table.sort(sortindices, comparator)
 
table.sort(sortindices, comparator)
 
+
 
local result
 
local result
 
local error
 
local error
Line 911: Line 534:  
for idx in pairs(claims) do
 
for idx in pairs(claims) do
 
local claim = claims[sortindices[idx]]
 
local claim = claims[sortindices[idx]]
value, error = getValueOfClaim(claim, qualifierId, parameter)
+
value, error = getValueOfClaim(claim, qualifierId, parameter)
 
if not value and showerrors then value = error end
 
if not value and showerrors then value = error end
 
if value and references then value = value .. getReferences(frame, claim) end
 
if value and references then value = value .. getReferences(frame, claim) end
Line 918: Line 541:  
result = table.concat(result, list)
 
result = table.concat(result, list)
 
else
 
else
-- return first element
+
-- return first element
 
local claim = claims[sortindices[1]]
 
local claim = claims[sortindices[1]]
 
result, error = getValueOfClaim(claim, qualifierId, parameter)
 
result, error = getValueOfClaim(claim, qualifierId, parameter)
 
if result and references then result = result .. getReferences(frame, claim) end
 
if result and references then result = result .. getReferences(frame, claim) end
 
end
 
end
 
+
 
if result then return result else
 
if result then return result else
 
if showerrors then return error else return default end
 
if showerrors then return error else return default end
Line 931: Line 554:  
-- look into entity object
 
-- look into entity object
 
function p.ViewSomething(frame)
 
function p.ViewSomething(frame)
local f = (frame.args[1] or frame.args.id) and frame or frame:getParent()
+
local data = mw.wikibase.getEntityObject()
local id = f.args.id
  −
if id and (#id == 0) then
  −
id = nil
  −
end
  −
local data = mw.wikibase.getEntityObject(id)
   
if not data then
 
if not data then
 
return nil
 
return nil
 
end
 
end
 +
 +
local f = frame.args[1] and frame or frame:getParent()
    
local i = 1
 
local i = 1
Line 945: Line 565:  
local index = f.args[i]
 
local index = f.args[i]
 
if not index then
 
if not index then
if type(data) == "table" then
+
return tostring(data)
return mw.text.jsonEncode(data, mw.text.JSON_PRESERVE_KEYS + mw.text.JSON_PRETTY)
  −
else
  −
return tostring(data)
  −
end
   
end
 
end
 
+
 
data = data[index] or data[tonumber(index)]
 
data = data[index] or data[tonumber(index)]
 
if not data then
 
if not data then
 
return
 
return
 
end
 
end
 
+
 
i = i + 1
 
i = i + 1
 
end
 
end
end
  −
  −
-- getting sitelink of a given wiki
  −
-- get sitelink of current item if qid not supplied
  −
function p.getSiteLink(frame)
  −
local qid = frame.args.qid
  −
if qid == "" then qid = nil end
  −
local f = mw.text.trim( frame.args[1] or "")
  −
local entity = mw.wikibase.getEntity(qid)
  −
if not entity then
  −
return
  −
end
  −
local link = entity:getSitelink( f )
  −
if not link then
  −
return
  −
end
  −
return link
   
end
 
end
    
function p.Dump(frame)
 
function p.Dump(frame)
local f = (frame.args[1] or frame.args.id) and frame or frame:getParent()
+
local data = mw.wikibase.getEntityObject()
local data = mw.wikibase.getEntityObject(f.args.id)
   
if not data then
 
if not data then
 
return i18n.warnDump
 
return i18n.warnDump
 
end
 
end
 +
 +
local f = frame.args[1] and frame or frame:getParent()
    
local i = 1
 
local i = 1