Modul:Wikidata: Perbedaan antara revisi

Konten dihapus Konten ditambahkan
k by request (https://id.wikipedia.org/w/index.php?title=Pembicaraan_Modul%3AWikidata&type=revision&diff=16187304&oldid=15607696)
-- version 20200415 from master @cawiki
Baris 1:
-- version 2019082620200415 from master @cawiki
 
local p = {}
 
--------------------------------------------------------- Initialization of variables --------------------
 
-- internationalisation at [[Module:Wikidata/i18n]]
local i18n = { -- internationalisation at [[Module:Wikidata/i18n]]
local i18n = {
["errors"] = {
["property-not-found"] = "Property not found.",
["entity-not-found"] = "Wikidata entity not found.",
["unknown-claim-type"] = "Unknown claim type.",
["unknown-entity-type"] = "Unknown entity type.",
["qualifier-not-found"] = "Qualifier not found.",
["site-not-found"] = "Wikimedia project not found.",
["unknown-datetime-format"] = "Unknown datetime format.",
["local-article-not-found"] = "Article is not yet available in this wiki.",
['not-from-content-page'] = "Do not invoke from content page. Use a template or use a module subpage like /sandbox for testing."
},
["datetime"] =
["datetime"] = {
{
-- $1 is a placeholder for the actual number
["beforenow"] = "$1 BCE", -- how to format negative 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
["ad"] = "$1", -- how print 1st century AD dates
[0] = "$1 billion years", -- precision: billion years
[1] = "$100 million years", -- precision: hundred million years
Baris 30 ⟶ 28:
[8] = "$1s", -- precision: decade
-- the following use the format of #time parser function
[9] = "Y", -- precision: year,
[10] = "F Y", -- precision: month
[11] = "F j, Y", -- precision: day
[12] = "F j, Y ga", -- precision: hour
[13] = "F j, Y g:ia", -- precision: minute
[14] = "F j, Y g:i:sa", -- precision: second
["beforenow"] = "$1 BCE", -- how to format negative 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
["ad"] = "$1", -- how print positive years
["bc-addon"] = " BC", -- suffix for negative dates
["ad-addon"] = "" -- suffix for 1st century AD dates
},
["monolingualtext"] = '<span lang="%language">%text</span>',
["years-old"] = {
["singular"] = "", -- year old, as in {{PLURAL:$1|singular|plural}}
["plural"] = "", -- years old
["paucal"] = "", -- for languages with 3 plural forms as in {{PLURAL:$1|singular|paucal|plural}}
},
["cite"] = { -- Cite web parameters
["url"] = "url",
["title"] = "title",
["website"] = "website",
["access-date"] = "access-date",
["archive-url"] = "archive-url",
["archive-date"] = "archive-date",
["author"] = "author",
["publisher"] = "publisher",
["quote"] = "quote",
["language"] = "language",
["date"] = "date",
["pages"] = "pages"
},
-- local wiki settings
["addpencil"] = false, -- adds a pencil icon linked to Wikidata statement, planned to overwrite by Wikidata Bridge
["categorylabels"] = "", -- Category:Pages with Wikidata labels not translated (void for no local category)
["addfallback"] = {} -- additional fallback language codes
}
 
local cases = {} -- functions for local grammatical cases defined at [[Module:Wikidata/i18n]]
 
local required = ... -- variadic arguments from require function
----------------------------------------------------------------------------
-- module local functions
 
local wiki =
{
langcode = mw.language.getContentLanguage().code,
module_title = 'Module:Wikidata', --required titleor to search for /subpages, change it if neededmw.getCurrentFrame():getTitle()
}
 
p.Untranslated = false
-- Credit to http://stackoverflow.com/a/1283608/2644759
 
-- cc-by-sa 3.0
-- Module local functions --------------------------------------------
 
-- Credit to http://stackoverflow.com/a/1283608/2644759, cc-by-sa 3.0
local function tableMerge(t1, t2)
for k,v in pairs(t2) do
Baris 90 ⟶ 89:
end
 
local function loadI18n(lang)
local exist, resi18n_title = pcall(require, wiki.module_title .. "/i18n")
if lang ~= wiki.langcode then i18n_title = "/i18n/" .. lang end
local exist, res = pcall(require, wiki.module_title .. i18n_title)
if exist and next(res) ~= nil then
tableMerge(i18n, res.i18n)
Baris 98 ⟶ 99:
end
 
-- Table of language codes: requested or default and its fallbacks
loadI18n()
 
local function case(word, localcase, lang)
if word == nil or word == '' or cases[localcase] == nil then
return word
end
return cases[localcase](word, lang)
end
 
local function findLang(langcode)
if langcode == nil or langcode == "" or mw.language.isKnownLanguageTag(langcode or '') == false then
local myframecframe = mw.getCurrentFrame()
local pframe = cframe:getParent()
langcode = myframe.args.lang
if langcode == nilpframe orand langcode == "" orpframe.args.lang
if mw.language.isKnownLanguageTag(langcode or '') == false then
if not mw.title.getCurrentTitle().isContentPage then
langcode = myframe:getParent().args.lang
langcode = cframe:preprocess('{{int:lang}}')
if langcode == nil or langcode == "" or mw.language.isKnownLanguageTag(langcode) == false then
end
if not mw.title.getCurrentTitle().isContentPage then
if mw.language.isKnownLanguageTag(langcode or '') == false then
langcode = myframe:preprocess( '{{int:lang}}' )
langcode = wiki.langcode
end
if langcode == nil or langcode == "" or mw.language.isKnownLanguageTag(langcode) == false then
langcode = wiki.langcode
end
end
end
end
loadI18n(langcode)
local languages = mw.language.getFallbacksFor(langcode)
table.insert(languages, 1, langcode)
if langcode == wiki.langcode then
for _, l in ipairs(i18n.addfallback) do
table.insert(languages, l)
end
end
return languages
end
 
-- Argument is 'set' when it exists (not nil) or when it is not an empty string.
local function isSet(var)
return not (var == nil or var == '')
end
 
-- Set local case to a label
local function case(localcase, label, ...)
if not isSet(label) then return label end
if localcase == "smallcaps" then
return '<span style="font-variant: small-caps;">' .. label .. '</span>'
elseif cases[localcase] then
return cases[localcase](label, ...)
end
return label
end
 
Baris 132 ⟶ 149:
local function getLabelByLangs(id, languages)
local label
local lang = languages[1]
for _, l in ipairs(languages) do
if lang == wiki.langcode then
if l == wiki.langcode then
-- using getLabelWithLang when possible instead of getLabelByLang
label, -- langusing = mw.wikibase.getLabelWithLang(id) when possible instead of getLabelByLang
label, l = mw.wikibase.getLabelWithLang(id)
else
else
for _, l in ipairs(languages) do
label = mw.wikibase.getLabelByLang(id, l)
end
if label then
lang = l
break
if label then
break
end
end
end
Baris 174 ⟶ 191:
end
 
-- get safely a serialized snak
-- Fetch unit symbol
local function unitSymbolgetSnak(idstatement, langsnaks)
local ret = statement
local claims = findClaims(mw.wikibase.getEntity(id), 'P5061')
for i, v in ipairs(snaks) do
local langclaims = {}
if claimsret == nil then return end
ret = ret[v]
for _, snak in ipairs(claims) do
end
if snak.mainsnak and snak.mainsnak.datavalue and snak.mainsnak.datavalue.value and
return ret
not langclaims[snak.mainsnak.datavalue.value.language] -- just the first one by language
end
then
 
langclaims[snak.mainsnak.datavalue.value.language] = snak.mainsnak.datavalue.value.text
-- Add an icon for no label in requested language
end
local function addLabelIcon(label_id, lang, uselang, icon)
local ret_lang, ret_icon = '', ''
if icon then
if lang and lang ~= uselang then
ret_lang = " <sup>(" .. lang .. ")</sup>"
end
if label_id and (lang == nil or lang ~= uselang) then
for _, l in ipairs(lang) do
ret_icon = " [[File:Noun Project label icon 1116097 cc mirror.svg|10px|baseline|"
if langclaims[l] then
.. mw.message.new('Translate-taction-translate'):inLanguage(uselang):plain()
return langclaims[l]
.. "|link=https://www.wikidata.org/wiki/Special:EntityPage/" .. label_id .. "?uselang=" .. uselang .. "]]"
end
p.Untranslated = true
end
if isSet(i18n.categorylabels) and lang ~= uselang and uselang == wiki.langcode then
ret_icon = ret_icon .. '[[' .. i18n.categorylabels .. (lang and ']]' or '/Q]]')
end
end
return langclaims["mul"]ret_lang --.. last tryret_icon
end
 
-- Add aan smallicon pencilfor asediting icona forstatement editwith onrequirements for Wikidata Bridge
local function addEditIcon(id, lang, uselang, iconparameters)
local ret = ''
if icon and lang ~= uselang then
if i18n.addpencil and parameters.editicon and parameters.id and parameters.property then
return " [[File:Arbcom ru editing.svg|12px|" .. mw.message.new('Translate-taction-translate'):inLanguage(uselang):plain() .. "|link=d:" .. id .. "]]"
ret = ' <span data-bridge-edit-flow="overwrite">'
.. "[[File:Arbcom ru editing.svg|10px|baseline|"
.. mw.message.new('Editlink'):inLanguage(parameters.lang[1]):plain()
.. "|link=https://www.wikidata.org/wiki/" .. parameters.id .. "?uselang=" .. parameters.lang[1] .. "#" .. parameters.property .. "]]"
.. "</span>"
end
return ''ret
end
-- add edit icon to the last element of a table
local function addEditIconTable(thetable, parameters)
if #thetable == 0 or not i18n.addpencil then
return thetable
end
local last_element = thetable[#thetable]
local the_icon = addEditIcon(parameters)
-- add it before last html closing tags
local tags = ''
local rev_element = string.reverse(last_element)
for tag in string.gmatch(rev_element, '(>%l+/<)') do
if string.match(rev_element, '^' .. tags .. tag) then
tags = tags .. tag
else
break
end
end
local last_tags = string.reverse(tags)
local offset = string.find(last_element, last_tags .. '$')
if offset then
thetable[#thetable] = string.sub(last_element, 1, offset - 1) .. the_icon .. last_tags
else
thetable[#thetable] = last_element .. the_icon
end
return thetable
end
 
-- Escape Lua captures
local function urlEscapes(text)
local function captureEscapes(text)
-- escape URL escapes to avoid Lua captures
return mw.ustring.gsub(text, "(%%%d)", "%%%1")
end
 
-- expandTemplate or callParserFunction
local function expandBraces(text, formatting)
if text == nil or formatting == nil then return text end
Baris 238 ⟶ 296:
end
braces = mw.ustring.gsub(braces, "([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1") -- escape magic characters
braces_expanded = urlEscapescaptureEscapes(braces_expanded)
text = mw.ustring.gsub(text, "{{" .. braces .. "}}", braces_expanded)
end
Baris 245 ⟶ 303:
end
 
-- Resolve Wikidata redirects, pending phab:T157868
local function resolveEntityId(id)
if not id or not mw.wikibase.isValidEntityId(id) then return id end
-- if no label in local language nor its fallbacks, maybe it is a redirect
-- not using mw.title.new(id).isRedirect as it is expensive
if mw.wikibase.getLabel(id) == nil then
local entity = mw.wikibase.getEntity(id) -- expensive function
if not entity then return nil end
if id ~= entity.id then
-- Qid redirected to be fixed
-- see [[Special:WhatLinksHere/Template:Track/wikidata/redirect]]
require(wiki.module_title .. '/debug').track('redirect')
require(wiki.module_title .. '/debug').track('redirect/' .. id)
else
-- no redirect and no label, fix it to avoid expensive functions
require(wiki.module_title .. '/debug').track('label')
require(wiki.module_title .. '/debug').track('label/' .. id)
end
return entity.id
end
return id
end
 
-- format data type math
local function printDatatypeMath(data)
return mw.getCurrentFrame():callParserFunction('#tag:math', data)
end
 
-- format data type musical-notation
local function printDatatypeMusical(data, formatting)
local attr = {}
if formatting == 'sound' then
attr.sound = 1
end
return mw.getCurrentFrame():extensionTag('score', data, attr)
end
 
-- format data value string
local function printDatavalueString(data, parameters)
if mw.ustring.find((parameters.formatting ==or 'weblink'), '$1', 1, true) then -- formatting = a pattern
return expandBraces(mw.ustring.gsub(parameters.formatting, '$1', {['$1'] = data}), parameters.formatting)
return '[' .. data .. ' ' .. mw.text.split(data, '//' )[2] .. ']'
elseif mw.ustring.find((parameters.formatting or ''), '$1', 1, true) then -- formatting = a pattern
--local escaped_data = mw.ustring.gsub(data, "%%", "%%%") -- escape % character, normally used in url, avoiding invalid capture in gsub
-- done in expandBraces
return expandBraces(mw.ustring.gsub(parameters.formatting, '$1', data), parameters.formatting)
elseif parameters.case then
return case(data, parameters.case, data, parameters.lang[1])
else
return data
end
return data
end
 
-- format data type url
local function printDatavalueUrl(data, parameters)
local function printDatatypeUrl(data, parameters)
-- escape URL escapes to avoid Lua captures
if parameters.formatting == 'weblink' then
return printDatavalueString(urlEscapes(data), parameters)
local label_parts = mw.text.split(string.gsub(data, '/$', ''), '/')
local label = string.gsub(label_parts[3], '^www%.', '')
if #label_parts > 3 then
label = label .. '…'
end
return '[' .. data .. ' ' .. label .. ']'
end
return printDatavalueString(data, parameters)
end
 
-- format data type commonsMedia
local function printDatatypeMedia(data, parameters)
local icon
if not string.find((parameters.formatting or ''), '$1', 1, true) then
icon = "no-icon"
end
return printDatavalueString(data, parameters), icon
end
 
-- format data value globecoordinate
local function printDatavalueCoordinate(data, formatting)
local function globes(globe_id)
local globes = {['Q3134']='callisto',['Q596']='ceres',['Q15040']='dione',['Q2']='earth',['Q3303']='enceladus',
['Q3143']='europa',['Q17975']='phoebe',['Q3169']='ganymede',['Q3123']='io',['Q17958']='iapetus',
['Q308']='mercury',['Q15034']='mimas',['Q405']='moon',['Q15050']='rhea',['Q15047']='tethys',
['Q111']='mars',['Q2565']='titan',['Q3359']='triton',['Q313']='venus',['Q3030']='vesta'}
return globes[globe_id]
end
local function roundPrecision(num, prec)
if prec == nil or prec <= 0 then return num end
local sig = 10^math.floor(math.log10(prec)+.5) -- significant figure from sexagesimal precision: 0.00123 -> 0.001
return math.floor(num / sig + 0.5) * sig
end
local precision = data.precision
local function printDatavalueCoordinate(data, parameter)
local latitude = roundPrecision(data.latitude, precision)
local globes = {['Q3134']='callisto',['Q596']='ceres',['Q15040']='dione',['Q2']='earth',['Q3303']='enceladus',
local longitude = roundPrecision(data.longitude, precision)
['Q3143']='europa',['Q17975']='phoebe',['Q3169']='ganymede',['Q3123']='io',['Q17958']='iapetus',
if formatting and string.find(formatting, '$lat', 1, true) and string.find(formatting, '$lon', 1, true) then
['Q308']='mercury',['Q15034']='mimas',['Q405']='moon',['Q15050']='rhea',['Q15047']='tethys',
local ret = mw.ustring.gsub(formatting, '$l[ao][tn]', {['$lat'] = latitude, ['$lon'] = longitude})
['Q111']='mars',['Q2565']='titan',['Q3359']='triton',['Q313']='venus',['Q3030']='vesta'}
if parameter and mw.ustring.find(parameter, '$lat', 1, true) and mw.ustringstring.find(parameterformatting, '$longlobe', 1, true) then
local ret = mw.ustring.gsub(mw.ustring.gsub(parameter, '$lat', data.latitude), '$lon', data.longitude)
if mw.ustring.find(parameter, '$globe', 1, true) then
local myglobe = 'earth'
if isSet(data.globe and data.globe ~= '') then
local globenum = mw.text.split(data.globe, 'entity/')[2] -- http://www.wikidata.org/wiki/Q2
myglobe = globes[(globenum]) or 'earth'
end
ret = mw.ustring.gsub(ret, '$globe', myglobe)
end
return expandBraces(ret, parameterformatting)
elseif parameterformatting == 'latitude' then
return data.latitude, "no-icon"
elseif parameterformatting == 'longitude' then
return data.longitude, "no-icon"
elseif parameterformatting == 'dimension' then
return data.dimension, "no-icon"
else --default formatting='globe'
if isSet(data.globe) == '' or data.globe == nilfalse or data.globe == 'http://www.wikidata.org/entity/Q2' then
return 'earth', "no-icon"
else
local globenum = mw.text.split(data.globe, 'entity/')[2] -- http://www.wikidata.org/wiki/Q2
return globes[(globenum]) or globenum, "no-icon"
end
end
end
 
-- Local functions for data value quantity
local function unitSymbol(id, lang) -- get unit symbol or code
local unit_symbol = ''
if lang == wiki.langcode and pcall(require, wiki.module_title .. "/Units") then
unit_symbol = require(wiki.module_title .. "/Units").getUnit(0, '', id, true)
end
if unit_symbol == '' then
-- fetch it
local claims = findClaims(id, 'P5061')
if claims then
local langclaims = {}
table.insert(lang, 'mul') -- multilingual as last try
for _, snak in ipairs(claims) do
local snak_language = getSnak(snak, {"mainsnak", "datavalue", "value", "language"})
if snak_language and not langclaims[snak_language] then -- just the first one by language
langclaims[snak_language] = snak.mainsnak.datavalue.value.text
end
end
for _, l in ipairs(lang) do
if langclaims[l] then
return langclaims[l]
end
end
end
end
return unit_symbol
end
 
local function getUnit(amount, id, parameters) -- get unit symbol or name
local suffix = ''
if parameters.formatting == "unitcode" then
-- get unit symbol
local unit_symbol = unitSymbol(id, parameters.lang)
if isSet(unit_symbol) then
suffix = unit_symbol
end
end
if suffix == '' then -- formatting=unit, or formatting=unitcode not found
-- get unit name
local unit_label, lang = getLabelByLangs(id, parameters.lang)
if lang == wiki.langcode and pcall(require, wiki.module_title .. "/Units") then
suffix = require(wiki.module_title .. "/Units").getUnit(amount, unit_label, id, false)
else
suffix = (unit_label or id) .. addLabelIcon(id, lang, parameters.lang[1], parameters.editicon)
end
end
if suffix ~= '' then
suffix = ' ' .. suffix
end
return suffix
end
 
local function roundPrecision(in_num, out_num)
-- rounds out_num with significant figures of in_num (default precision)
-- first, count digits after decimal mark, handling cases like '12.345e6'
local exponent, prec
local integer, dot, decimals, expstr = in_num:match('^(%d*)(%.?)(%d*)(.*)')
local e = expstr:sub(1, 1)
if e == 'e' or e == 'E' then
exponent = tonumber(expstr:sub(2))
end
if dot == '' then
prec = -integer:match('0*$'):len()
else
prec = #decimals
end
if exponent then
-- So '1230' and '1.23e3' both give prec = -1, and '0.00123' and '1.23e-3' give 5.
prec = prec - exponent
end
-- significant figures
local in_bracket = 10^-prec -- -1 -> 10, 5 -> 0.00001
local out_bracket = in_bracket * out_num / in_num
out_bracket = 10^math.floor(math.log10(out_bracket)+.5) -- 1230 -> 1000, 0.00123 -> 0.001
-- round it (credit to Luc Bloom from http://lua-users.org/wiki/SimpleRound)
return math.floor(out_num/out_bracket + (out_num >=0 and 1 or -1) * 0.5) * out_bracket
end
 
-- format data value quantity
local function printDatavalueQuantity(data, parameters)
-- exemples: 277±1 Centímetre, 1,94 metre
local amount = data.amount
amount = mw.ustring.gsub(amount, "%+", "")
local sortkey = string.format("%09d", amount)
amount = mw.language.new(parameters.lang[1]):formatNum(tonumber(amount))
-- This is used to get the unit name for a numeric value
local suffix = ""
local conv_amount, conv_suffix
if parameters.formatting == "unit" or parameters.formatting == "unitcode" then
if string.sub(parameters.formatting or '', 1, 4) == "unit" or parameters.convert then
-- get the url for the unit entry on Wikidata:
-- example "unit": "http://www.wikidata.org/entity/Q174728"
local unitID = data.unit
local unit_id = data.unit
-- and just return the last bit from "Q" to the end (which is the QID):
unitIDunit_id = mw.ustring.sub(unitIDunit_id, mw.ustring.find(unitIDunit_id, "Q"), -1)
if mw.ustringstring.sub(unitIDunit_id, 1, 1) == "Q" then
suffix = getUnit(amount, unit_id, parameters)
local unit_symbol = ''
local convert_to
if parameters.formatting == "unitcode" then
if parameters.lang[1]convert == wiki.langcode"default" andor pcall(require, wikiparameters.module_titleconvert ..== "/Unitsdefault2") then
unit_symbollocal exist, units = pcall(require(, wiki.module_title .. "/Units").getUnit(amount, '', unitID, true, '')
if exist and next(units.convert_default) ~= nil then
end
convert_to = units.convert_default[unit_id]
if unit_symbol == '' then
unit_symbol = unitSymbol(unitID, parameters.lang)
end
if unit_symbol then
suffix = " " .. unit_symbol
end
elseif string.sub(parameters.convert or '', 1, 1) == "Q" then
convert_to = parameters.convert
end
if suffixconvert_to =and convert_to ~= ''unit_id then
-- convert units
local unit_label, lang = getLabelByLangs(unitID, parameters.lang)
local conv_temp = { -- formulae for temperatures ºC, ºF, ªK: [from] = {[to] = 'formula'}
if lang == wiki.langcode and pcall(require, wiki.module_title .. "/Units") then
['Q25267'] = {['Q42289'] = '$1*1.8+32', ['Q11597'] = '$1+273.15'},
suffix = " " .. require(wiki.module_title .. "/Units").getUnit(amount, unit_label, unitID, false, '')
['Q42289'] = {['Q25267'] = '($1-32)/1.8', ['Q11597'] = '($1+459.67)*5/9'},
['Q11597'] = {['Q25267'] = '$1-273.15', ['Q42289'] = '($1-273.15)*1.8000+32.00'}
}
if conv_temp[unit_id] and conv_temp[unit_id][convert_to] then
local amount_f = mw.getCurrentFrame():callParserFunction('#expr', mw.ustring.gsub(conv_temp[unit_id][convert_to], "$1", amount))
conv_amount = math.floor(tonumber(amount_f) + 0.5)
else
local conversions = mw.wikibase.getAllStatements(unit_id, 'P2442') -- conversion to standard unit
suffix = " " .. (unit_label or unitID) .. addEditIcon(unitID, lang, parameters.lang[1], parameters.editicon)
table.insert(conversions, mw.wikibase.getBestStatements(unit_id, 'P2370')[1]) -- conversion to SI unit
for _, conv in ipairs(conversions) do
if conv.mainsnak.snaktype == 'value' then -- no somevalue nor novalue
if conv.mainsnak.datavalue.value.unit == "http://www.wikidata.org/entity/" .. convert_to then
conv_amount = roundPrecision(amount, amount * tonumber(conv.mainsnak.datavalue.value.amount))
break
end
end
end
end
if conv_amount then
conv_suffix = getUnit(conv_amount, convert_to, parameters)
end
elseif parameters.convert == 'M' and tonumber(amount) > 10^8 then
conv_amount = math.floor(amount/10^6 + 0.5)
conv_suffix = ' M' .. string.sub(suffix, 2)
end
end
end
local lang_obj = mw.language.new(parameters.lang[1])
local sortkey = string.format("%019d", tonumber(amount) * 1000)
if parameters.case then
amount = case(parameters.case, amount, parameters.lang[1])
else
amount = lang_obj:formatNum(tonumber(amount))
end
if conv_amount then
local conv_sortkey = string.format("%019d", tonumber(conv_amount) * 1000)
conv_amount = lang_obj:formatNum(tonumber(conv_amount))
if parameters.convert == 'default2' then
return conv_amount .. conv_suffix .. ' (' .. amount .. suffix .. ')', conv_sortkey
else
return conv_amount .. conv_suffix, conv_sortkey
end
end
Baris 339 ⟶ 567:
end
 
-- format data value time
local function printDatavalueTime(data, parameters)
-- Dates and times are stored in ISO 8601 format
local timestamp = data.time
local sortkey = timestamppost_format
local addon = ""
local calendar_add = ""
local precision = data.precision or 11
-- check for negative date, ex. "-0027-01-16T00:00:00Z"
if string.sub(timestamp, 1, 1) == '-' then
post_format = i18n.datetime["bc"]
timestamp = '+' .. string.sub(timestamp, 2)
addon = i18n.datetime["bc-addon"]
elseif string.sub(timestamp, 2, 3) == '00' then
addonpost_format = i18n.datetime["ad-addon"]
elseif precision > 8 then
else
-- calendar model
local calendar_model = {["Q12138"] = "gregorian", ["Q1985727"] = "gregorian", ["Q11184"] = "julian", ["Q1985786"] = "julian"}
Baris 362 ⟶ 589:
end
end
local function d(f, t)
local function formatTime(form, stamp)
local ts = t or timestamp
local pattern
local form = type(f) == "function" and f(ts) or f -- function in i18n.datetime[precision]
if type(form) == "function" then
return mw.language.new(parameters.lang[1]):formatDate(form, ts) .. addon .. calendar_add
pattern = form(stamp)
else
pattern = form
end
stamp = tostring(stamp)
if mw.ustring.find(pattern, "$1") then
return mw.ustring.gsub(pattern, "$1", stamp)
elseif string.sub(stamp, 1, 1) == '-' then -- formatDate() only supports years from 0
stamp = '+' .. string.sub(stamp, 2)
elseif string.sub(stamp, 1, 1) ~= '+' then -- not a valid timestamp, it is a number
stamp = string.format("%04d", stamp)
end
local ret = mw.language.new(parameters.lang[1]):formatDate(pattern, stamp)
ret = string.gsub(ret, "^(%[?%[?)0+", "%1") -- supress leading zeros
ret = string.gsub(ret, "( %[?%[?)0+", "%1")
return ret
end
local precision = data.precision or 11
local function postFormat(t)
local intyear = tonumber(mw.ustring.match(timestamp, "^\+?%d+"))
if post_format and mw.ustring.find(post_format, "$1") then
return mw.ustring.gsub(post_format, "$1", t)
end
return t
end
local intyear = tonumber(string.match(timestamp, "[+-](%d+)"))
local ret = ""
if precision <= 5 then -- precision is 10000 years or more
if precision <= 5 then
local factor = 10 ^ ((5 - precision) + 4)
local y2 = math.ceil(math.abs(intyear) / factor)
local relative = mw.ustring.gsubformatTime(i18n.datetime[precision], "$1", tostring(y2))
if addonpost_format == i18n.datetime["bc-addon"] then
-- negative date
ret = mw.ustring.gsub(i18n.datetime.beforenow, "$1", relative)
else
Baris 386 ⟶ 634:
ret = mw.ustring.gsub(ret, ret_number, mw.language.new(parameters.lang[1]):formatNum(tonumber(ret_number)))
end
--elseif precision is== millennia,6 centuriesor precision == 7 then -- millennia or decadescenturies
local card = math.floor((intyear - 1) / 10^(9 - precision)) + 1
elseif precision == 6 then
ret = formatTime(i18n.datetime[precision], card)
local card = math.floor((intyear - 1) / 1000) + 1
ret = postFormat(ret)
if mw.ustring.find(i18n.datetime[6], "$1") then
elseif precision == 8 then -- decades
ret = mw.ustring.gsub(i18n.datetime[6], "$1", tostring(card)) .. addon .. calendar_add
else
ret = d(i18n.datetime[6], string.format("%04d", tostring(card)))
end
elseif precision == 7 then
local card = math.floor((math.abs(intyear) - 1) / 100) + 1
if mw.ustring.find(i18n.datetime[7], "$1") then
ret = mw.ustring.gsub(i18n.datetime[7], "$1", tostring(card)) .. addon .. calendar_add
else
ret = d(i18n.datetime[7], string.format("%04d", tostring(card)))
end
elseif precision == 8 then
local card = math.floor(math.abs(intyear) / 10) * 10
ret = mw.ustring.gsubformatTime(i18n.datetime[8], "$1", tostring(card)) .. addon .. calendar_add
ret = postFormat(ret)
-- precision is year
elseif parameters.formattingintyear ==> 'Y'9999 orthen precision-- ==not 9a thenvalid timestamp
return
ret = tostring(intyear) .. addon .. calendar_add
elseif precision == 9 or parameters.formatting == 'Y' then -- precision is monthyear
ret = formatTime(i18n.datetime[9], intyear)
elseif precision == 10 then
ret = postFormat(ret) .. calendar_add
timestamp = timestamp .. " + 1 day" -- formatDate yyyy-mm-00 returns the previous month
elseif precision == 10 then -- month
ret, _ = string.gsub(d(i18n.datetime[10]), " 0+", " ") -- supress leading zeros in year
ret = formatTime(i18n.datetime[10], timestamp .. " + 1 day") -- formatDate yyyy-mm-00 returns the previous month
elseif parameters.formatting then
ret = postFormat(ret) .. calendar_add
ret, _ = string.gsub(d(parameters.formatting), "([ %[])0+", "%1") -- supress leading zeros in year optionally linked
else -- precision 11, day
else
ret, _ = stringformatTime(parameters.gsub(d(formatting or i18n.datetime[11]), " 0+", " "timestamp)
ret = postFormat(ret) .. calendar_add
end
return ret, sortkeytimestamp
end
 
-- format data value entity
local function printDatavalueEntity(data, parameters)
local entityIdentity_id = data['id']
local entityIdPreffix = data['entity-type'] == 'property' and "Property:" .. entityId or entityId
if parameters.formatting == 'raw' then
if data['entity-type'] == 'item' then
return entityId, entityId
entity_id = resolveEntityId(entity_id)
end
return entity_id, entity_id
end
local entity_page = 'Special:EntityPage/' .. entity_id
local label, lang = getLabelByLangs(entityId, parameters.lang)
local label, lang = getLabelByLangs(entity_id, parameters.lang)
local sitelink = mw.wikibase.getSitelink(entityId)
local sitelink = mw.wikibase.getSitelink(entity_id)
local parameter = parameters.formatting
local labelcase = label or sitelink
if parameters.gender == 'feminineform' and lang ~= nil then -- case gender and item is female
labelcase = feminineForm(entityIdentity_id, lang) or labelcase
end
if parameters.case ~= 'gender' then
labelcase = case(labelcase, parameters.case, labelcase, lang, entity_id, parameters.id)
end
local ret1, ret2
if parameter == 'label' then
ret1 = (labelcase or entityId)entity_id
ret2 = labelcase or entityIdentity_id
elseif parameter == 'sitelink' then
ret1 = (sitelink or 'wikidatad:' .. entityIdPreffixentity_page)
ret2 = sitelink or entityIdentity_id
elseif mw.ustring.find((parameter or ''), '$1', 1, true) then -- formatting = a pattern
ret1 = mw.ustring.gsub(parameter, '$1', labelcase or entityIdentity_id)
ret1 = expandBraces(ret1, parameter)
ret2 = labelcase or entityIdentity_id
else
if parameter == "ucfirst" or parameter == "ucinternallink" then
if labelcase =and lang then
labelcase and= mw.language.new(lang):ucfirst(labelcase)
end
-- only first of a list, reset formatting for next ones
if parameter == "ucinterlanllink" then
Baris 464 ⟶ 708:
ret2 = labelcase
else
ret1 = '[[wikidatad:' .. entityIdPreffixentity_page .. '|' .. (labelcase or entityIdentity_id) .. ']]'
ret2 = labelcase or entityIdentity_id
end
end
return ret1 .. addEditIconaddLabelIcon(entityIdPreffixentity_id, lang, parameters.lang[1], parameters.editicon), ret2
end
 
-- format data value monolingualtext
local function printDatavalueMonolingualText(data, parameters)
-- data fields: language [string], text [string]
Baris 482 ⟶ 727:
local result = data["text"]
if data["language"] ~= wiki.langcode then
result = mw.ustring.gsub(mw.ustring.gsub(i18n.monolingualtext,'<span lang="%%language$1">$2</span>', '$[12]', {["$1"]=data["language"]), ["%%text$2", ]=data["text"]})
end
if mw.ustring.find((parameters.formatting or ''), '$', 1, true) then
Baris 493 ⟶ 738:
 
local function printError(key)
return '<span class="error">' .. i18n.errors[key] .. '</span>'
end
 
Baris 512 ⟶ 757:
end
 
function findClaims(entityentityId, property)
if not property or not entity or not entity.claimsentityId then return end
if not mw.ustring.match(property, "^P%d+$") then
Baris 520 ⟶ 765:
if not property then return end
end
local claims = mw.wikibase.getAllStatements(entityId, property)
returnif entity.#claims[property] == 0 then
claims = nil
end
return claims
end
 
Baris 529 ⟶ 777:
if snak.datatype == 'math' then
return printDatatypeMath(snak.datavalue.value)
elseif snak.datatype == 'musical-notation' then
return printDatatypeMusical(snak.datavalue.value, parameters.formatting)
elseif snak.datatype == "url" then
return printDatavalueUrlprintDatatypeUrl(snak.datavalue.value, parameters)
elseif snak.datatype == "commonsMedia" then
return printDatatypeMedia(snak.datavalue.value, parameters)
elseif snak.datavalue.type == "string" then
return printDatavalueString(snak.datavalue.value, parameters)
Baris 545 ⟶ 797:
end
elseif snak.snaktype == 'novalue' then
if parameters.formatting == 'raw' then return end
return mw.message.new('Wikibase-snakview-snaktypeselector-novalue'):inLanguage(parameters.lang[1]):plain()
elseif snak.snaktype == 'somevalue' then
if parameters.formatting == 'raw' then return end
return mw.message.new('Wikibase-snakview-snaktypeselector-somevalue'):inLanguage(parameters.lang[1]):plain()
end
Baris 564 ⟶ 818:
-- iterate over monolingualtext qualifiers to get local language
for idx in pairs(qualifier) do
if getSnak(qualifier[idx]., {"datavalue.", "value", and qualifier[idx].datavalue.value."language"}) == parameters.lang[1] then
return qualifier[idx]
end
Baris 583 ⟶ 837:
 
function getValueOfClaim(claim, qualifierId, parameters)
local snak, error = getQualifierSnak(claim, qualifierId, parameters)
local error
local snak
snak, error = getQualifierSnak(claim, qualifierId, parameters)
if not snak then
return nil, nil, error
Baris 612 ⟶ 864:
if parent_claims[1] ~= nil then
value, sortkey, _ = getValueOfClaim(parent_claims[1], nil, parameters)
-- raw parent value needed fotfor while/black lists, lang for avoiding an error on types other than entity
valueraw, _, _ = getValueOfClaim(parent_claims[1], nil, {["formatting"]="raw", ["lang"]=parameters.lang})
end
end
Baris 620 ⟶ 872:
 
local function getReferences(claim)
local refaliasesnotproperref = {
["P143"] = true, -- imported from
citeWeb = "Q5637226",
["P3452"] = true, -- inferred from
author = "P50",
["P887"] = true, -- based on heuristic
publisher = "P123",
["P4656"] = true -- Wikimedia import URL
importedFrom = "P143",
statedIn = "P248",
pages = "P304",
publicationDate = "P577",
startTime = "P580",
endTime = "P582",
chapter = "P792",
retrieved = "P813",
referenceURL = "P854",
archiveURL = "P1065",
title = "P1476",
quote = "P1683",
shortName = "P1813",
language = "P2439",
archiveDate = "P2960"
}
local result = ""
Baris 645 ⟶ 883:
local refparts
local refs = {}
local validref = true
-- traverse through all parts of the current reference
for snakkey, snakval in pairs(claim.references[ref].snaks or {}) do
for partkey, _ in pairs(claim.references[ref].snaks[snakkey] or {}) do
if snakkey ~= refaliases.importedFrom then -- "imported from" is not a proper reference
if notproperref[snakkey] then -- not a proper reference
validref = false
break
end
end
if validref then
for snakidx = 1, #snakval do
if snakidx > 1 then refparts = refparts .. ", " end
Baris 658 ⟶ 903:
-- get title of general template for citing web references
local template = mw.wikibase.getSitelink(refaliases.citeWeb'Q5637226') or ""
template = mw.text.split(template, ":")[2] -- split off namespace from front
-- (1) if both "reference URL" and "title" (or "stated in") are present, then use thelocal general template for citingcite web referencestemplate
if refs[refaliases.referenceURL'P854'] and (refs[refaliases.title'P1476'] or refs[refaliases.statedIn'P248']) and template then
local citeParams = {}
citeParams[i18n['cite']['url']] = refs[refaliases.referenceURL'P854']
citeParams[i18n['cite']['title']] = refs[refaliases.title'P1476'] or refs[refaliases.statedIn'P248']:match("^%[%[.-|(.-)%]%]")
citeParams[i18n['cite']['websiteauthor']] = refs[refaliases.statedIn'P50']
citeParams[i18n['cite']['languagewebsite']] = refs[refaliases.language'P248']
citeParams[i18n['cite']['datelanguage']] = refs[refaliases.publicationDate'P2439']
citeParams[i18n['cite']['access-datepublisher']] = refs[refaliases.retrieved'P123']
citeParams[i18n['cite']['archive-urldate']] = refs[refaliases.archiveURL'P577']
citeParams[i18n['cite']['archive-datepages']] = refs[refaliases.archiveDate'P304']
citeParams[i18n['cite']['publisheraccess-date']] = refs[refaliases.publisher'P813']
citeParams[i18n['cite']['quotearchive-url']] = refs[refaliases.quote'P1065']
citeParams[i18n['cite']['pagesarchive-date']] = refs[refaliases.pages'P2960']
citeParams[i18n['cite']['authorquote']] = refs[refaliases.author'P1683']
refparts = mw.getCurrentFrame():expandTemplate{title=template, args=citeParams}
else
-- raw ouput
local italics = "''"
for k, v in orderedpairs(refs or {}, claim.references[ref]["snaks-order"]) do
if k and v then
if refparts then= refparts =and refparts .. ", " else refparts =or "" end
refparts = refparts .. tostringmw.ustring.gsub(mw.wikibase.getLabel(k), "^%l", mw.ustring.upper) .. ": "
refparts = refparts .. italics .. v .. italics .. "."
italics = ""
end
end
Baris 690 ⟶ 937:
end
return result
end
 
-- Return the site link (for the current site) for a given data item.
function p.getSiteLink(frame)
if frame.args[1] == nil then
entity = mw.wikibase.getEntity()
if not entity then
return nil
end
id = entity.id
else
id = frame.args[1]
end
return mw.wikibase.getSitelink(id)
end
 
-- Set whitelist or blacklist values
local function setWhiteOrBlackList(type_list, num_qual, args)
local i = 0
local listed = false
local list = {}
whilefor i <= 0, num_qual do
if isSet(args[type_list .. i] and args[type_list .. i] ~= '') then
listed = true
list[tostring(i)] = {}
Baris 719 ⟶ 950:
for _, v in ipairs(values) do
list[tostring(i)][v] = true
list[tostring(i)][resolveEntityId(v)] = true
end
end
i = i + 1
end
return list, listed
end
 
local function tableParameters(args, parameters, column)
-- returns the page id (Q...) of the current page or nothing of the page is not connected to Wikidata
local column_params = mw.clone(parameters)
function p.pageId(frame)
column_params.formatting = args["colformat"..column]; if column_params.formatting == "" then column_params.formatting = nil end
local entity = mw.wikibase.getEntityObject()
column_params.convert = args["convert" .. column]
if not entity then return nil else return entity.id end
if args["case" .. column] then
column_params.case = args["case" .. column]
end
return column_params
end
 
local function p.claimgetEntityId(frame, unnamed)
local args = frame.args or frame
if mw.title.new(frame:getParent():getTitle()).isContentPage then
local pargs = frame.args and frame:getParent().args
if not mw.title.new(frame:getTitle()).isSubpage then
local id = args.item or args.from or (unnamed and mw.text.trim(args[1] or '') or nil)
-- invoked from a content page and not invoking a module subpage
if not isSet(id) and pargs then
return printError("not-from-content-page")
id = pargs.item or pargs.from or (unnamed and mw.text.trim(pargs[1] or '') or nil)
end
if isSet(id) then
if string.find(id, ":") then -- remove prefix as Property:Pid
id = mw.text.split(id, ":")[2]
end
else
id = mw.wikibase.getEntityIdForCurrentPage()
end
return id
return p._main(frame.args, frame:getParent().args)
end
 
-- Main function claim ---------------------------------------------
-- Entry point from other modules or debugging, with a list of arguments.
-- Fromon otherdebug modulesconsole use: require("Module:Wikidata")=p._main(claim{item="Q...", property="P...", ...})
function p.claim(frame)
-- On debug console use: =p._main({item="Q...", lang="xx", property="P...", ...})
p.Untranslated = false
function p._main(args, pargs)
if not required and frame.args and isSet(frame:getParent().args.sandbox) then
return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).claim(frame)
end
local args = frame.args or frame -- via invoke or require
--If a value is already set, use it
if isSet(args.value) andthen
if args.value ~== 'NONE' then
return args.value
else
return args.value
end
end
-- arguments
local id = args.item or getEntityId(pargs and pargs.itemframe)
if id == nil orthen idreturn == "" thenend
local property = string.upper(args.property or "")
id = mw.wikibase.getEntityIdForCurrentPage()
end
local languages = findLang(args.lang)
local itemgender = args["itemgender"]
local idgender
if itemgender then
if string.match(itemgender, "^P%d+$") then
local snak = mw.wikibase.getBestStatements(id, itemgender)[1]
if snak and snak.mainsnak and snak.mainsnak.datavalue and snak.mainsnak.datavalue.value then
idgender = snak.mainsnak.datavalue.value.id
end
elseif string.match(itemgender, "^Q%d+$") then
idgender = itemgender
end
end
local property = string.upper(args["property"] or "")
local qualifierId = {}
qualifierId[1] = isSet(args[".qualifier"]) and string.upper(args[".qualifier"]) or nil
local i = 2
while isSet(args["qualifier" .. i]) do
qualifierId[i] = string.upper(args["qualifier" .. i])
i = i + 1
end
local parameterformatting = args[".formatting"] or ''; if parameterformatting == "" then parameterformatting = nil end
local convert = args.convert; if convert == "" then convert = nil end
local case = args.case
local list = args[".list"] or true; if (list == "false" or list == "no") then list = false end
local sorting_col = args.tablesort
local sorting_up = (args.sorting or "") ~= "-1"
local separator = isSet(args.separator) and args.separator
local conjunction = isSet(args.conjunction) orand args.conjunction or separator
local rowformat = args.rowformat
local references = args[".references"]
local showerrors = args[".showerrors"]
local default = args[".default"]
if default then showerrors = nil end
local editicon = not (args.editicon == "false" or args.editicon == "no")
local editicon = not (args.editicon == "false" or args.editicon == "no" or formatting == "raw")
local parameters = {["propertyid"] = propertyid, ["formattingproperty"] = parameterproperty, ["listformatting"] = listformatting, ["caseconvert"] = caseconvert,
["langlist"] = languageslist, ["case"] = case, ["editicon"] = editicon,
["separator"] = separator, ["conjunction"] = conjunction, ["qseparator"] = separator, ["qconjunction"] = conjunction}
parameters.lang = findLang(args.lang)
-- defaults for table
Baris 828 ⟶ 1.066:
blacklist, blacklisted = setWhiteOrBlackList("blacklist", #qualifierId, args)
end
if default then showerrors = nil end
-- fetch property
-- get wikidata entity
local claims
local entity = mw.wikibase.getEntity(id)
for p in string.gmatch(property, 'P%d+') do
if not entity then
claims = findClaims(id, p)
if showerrors then return printError("entity-not-found") else return default end
if claims and claims[1] then
parameters.property = p
break
end
end
-- fetch the first claim of satisfying the given property
local claims = findClaims(entity, property)
if not claims or not claims[1] then
if showerrors then return printError("property-not-found") else return default end
Baris 842 ⟶ 1.081:
-- set feminine case if gender is requested
local itemgender = args["itemgender"]
local genderCase
local genderRequested = falseidgender
if itemgender then
if string.match(itemgender, "^P%d+$") then
local snak_id = getSnak(mw.wikibase.getBestStatements(id, itemgender), {1, "mainsnak", "datavalue", "value", "id"})
if snak_id then
idgender = snak_id
end
elseif string.match(itemgender, "^Q%d+$") then
idgender = itemgender
end
end
local gender_requested = false
if parameters.case == "gender" or idgender then
genderRequestedgender_requested = true
elseif parameters.formatting == "table" then
for i=0, #qualifierId do
if args["case0"] and args["case0"] == "gender" then
if args["case" .. i] and args["case" .. i] == "gender" then
genderRequested = true
gender_requested = true
else
break
for i, qual in ipairs(qualifierId) do
if args["case" .. i] and args["case" .. i] == "gender" then
genderRequested = true
break
end
end
end
end
if genderRequestedgender_requested then
if feminineGender(idgender or id) then
genderCaseparameters.gender = "feminineform"
if parameters.case == "gender" or idgender then
parameters.gender = genderCase
end
end
end
Baris 875 ⟶ 1.118:
local comparator = function(a, b)
local rankmap = { deprecated = 2, normal = 1, preferred = 0 }
local ranka = rankmap[claims[a].rank or "normal"] .. string.format("%08d", a)
local rankb = rankmap[claims[b].rank or "normal"] .. string.format("%08d", b)
return ranka < rankb
end
table.sort(sortindices, comparator)
local result, result2
local error
if parameters.list or parameters.formatting == "table" then
Baris 900 ⟶ 1.143:
for idx in pairs(claims) do
local claim = claims[sortindices[idx]]
local reference = {}
if not whitelisted then rowlist[idx] = true end
if firstrank ~= '' and firstrank ~= claim.rank then
Baris 906 ⟶ 1.149:
end
if parameters.formatting == "table" then
local params = mw.clonetableParameters(args, parameters, "0")
value, sortkey, error = getValueOfClaim(claim, nil, params)
params.formatting = args["colformat0"]; if params.formatting == "" then params.formatting = nil end
if args["case0"] then
if args["case0"] == "gender" then
params.gender = genderCase
else
params.case = args["case0"]
end
end
value, sortkey, error = getValueOfClaim(claim, nil, params)
if value then
values[#values + 1] = {}
Baris 930 ⟶ 1.165:
for i, qual in ipairs(qualifierId) do
local j = tostring(i)
params = tableParameters(args, parameters, j)
params.formatting = args["colformat" .. j]; if params.formatting == "" then params.formatting = nil end
params.case = parameters.case
params.gender = parameters.gender
if args["case" .. j] then
if args["case" .. j] == "gender" then
params.gender = genderCase
else
params.case = args["case" .. j]
end
end
local valueq, sortkeyq, valueraw
if qual == property then -- hack for getting the property with another formatting, i.e. colformat1=raw
valueq, sortkeyq, _ = getValueOfClaim(claim, nil, params)
else
for q in mw.text.gsplit(qual, '%s*OR%s*') do
if string.find(q, ".+/.+") then
valueq, sortkeyq, valueraw = getValueOfParentClaim(claim, q, params)
elseif string.find(q, "^/.+") then
local claim2 = findClaims(entityid, string.sub(q, 2))
if claim2 then
valueq, sortkeyq, _ = getValueOfClaim(claim2[1], nil, params)
end
else
valueq, sortkeyq, _ = getValueOfClaim(claim, q, params)
end
if valueq then break end
Baris 971 ⟶ 1.197:
end
else
value, sortkey, error = getValueOfClaim(claim, qualifierId[1], parameters)
values[#values + 1] = {}
sortkeys[#sortkeys + 1] = {}
Baris 978 ⟶ 1.204:
if not value and showerrors then value = error end
if value then
if references and claim.references then reference = claim.references end
refs[#refs]["col0"] = reference
values[#values]["col0"] = value
sortkeys[#sortkeys]["col0"] = sortkey or value
Baris 1.011 ⟶ 1.237:
local valuerow = values[sortindices[idx]]
local reference = getReferences({["references"] = refs[sortindices[idx]]["col0"]})
 
value = valuerow["col0"]
if parameters.formatting == "table" then
Baris 1.017 ⟶ 1.243:
value = nil
else
valuelocal rowformatting = mw.ustring.gsub(rowformat .. "$", "$0", value) -- fake end character added for easy gsub
value = mw.ustring.gsub(rowformatting, "$0", value)
value = mw.ustring.gsub(value, "$R0", reference) -- add reference
local rowformatting = rowformat .. "$"
for i, _ in ipairs(qualifierId) do
local valueq = valuerow["col" .. i]
Baris 1.026 ⟶ 1.252:
-- gsub $i not followed by a number so $1 doesn't match $10, $11...
-- remove fake end character
valueq = captureEscapes(valueq)
valueq = mw.ustring.gsub(args["rowsubformat" .. i] .. "$", "$" .. i .. "(%D)", valueq .. "%1")
valueq = string.sub(valueq, 1, -2)
rowformatting = mw.ustring.gsub(rowformatting, "$" .. i .. "(%D)", args["rowsubformat" .. i] .. "%1")
end
valueq = valueq and urlEscapescaptureEscapes(valueq) or ''
value = mw.ustring.gsub(value, "$" .. i .. "(%D)", valueq .. "%1")
end
Baris 1.036 ⟶ 1.263:
value = expandBraces(value, rowformatting)
end
elseif value then
else
value = expandBraces(value, parameters.formatting)
value = value .. reference
end
if isSet(value) then
result[#result + 1] = value
result[#result + 1] = value
if not parameters.list then
if not parameters.list then
break
break
end
end
end
-- in a table, add edit icon on last element
if parameters.formatting == 'table' and parameters.editicon then
result = addEditIconTable(result, parameters)
end
result = preformat .. mw.text.listToText(result, parameters.separator, parameters.conjunction) .. postformat
Baris 1.048 ⟶ 1.282:
-- return first element
local claim = claims[sortindices[1]]
result, _result2, error = getValueOfClaim(claim, qualifierId[1], parameters)
if result and references then result = result .. getReferences(claim) end
end
if isSet(result) then return result else
-- add edit icon
if parameters.formatting == 'table' then
return result -- added previously on last element
elseif result2 and result2 == 'no-icon' then
return result
elseif i18n.addpencil then
return result .. addEditIcon(parameters)
else
return result
end
else
if showerrors then return error else return default end
end
Baris 1.062 ⟶ 1.307:
-- 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.getEntity()
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
end
local ret = table.concat(out, "<br> ")
if #ret == 0 then
ret = "Invalid TA"
end
return ret
end
 
-- debuggingLocal functions, seefor modulegetParentValues ../debug.-----------------------
function p.ViewSomething(frame)
return require(wiki.module_title .. "/debug").ViewSomething(frame)
end
 
function p.Dump(frame)
return require(wiki.module_title .. "/debug").Dump(frame)
end
 
function p.getEntityFromTree(frame)
return require(wiki.module_title .. "/debug").getEntityFromTree(frame)
end
 
-- getParentValues: returns a property value with its instance label fetching a recursive tree
 
local function uc_first(word)
Baris 1.100 ⟶ 1.332:
end
 
local function getPropertyValue(id, property, parameter, langs, editicon, case)
local snaks = mw.wikibase.getBestStatements(id, property)
local mysnak
Baris 1.109 ⟶ 1.341:
end
local entityIdentity_id
local result = '-' -- default for 'no value'
if mysnak.datavalue then
entityIdentity_id = "Q" .. tostring(mysnak.datavalue.value['numeric-id'])
result, _ = getSnakValue(mysnak, {formatting=parameter, lang=langs, editicon=editicon, case=case})
end
return entityIdentity_id, result
end
 
local function p.getParentValuescontains(frametab, val)
for index, value in ipairs(tab) do
local args = frame.args
if value == val then
local id = args.item or frame:getParent().args.item
return true
if id == "" or id == nil then
end
id = mw.wikibase.getEntityIdForCurrentPage()
if id == nil then return end
end
local languages = findLang(args.lang)
return false
local propertySup = args["property"]; if (propertySup == nil or propertySup == "") then propertySup = "P131" end --administrative entity
end
local propertyLabel = args["label"]; if (propertyLabel == nil or propertyLabel == "") then propertyLabel = "P31" end --instance
 
local propertyLink = args["valuetext"]; if propertyLink == "" then propertyLink = nil end --internallink
local function getParentObjects(id,
local upto = args["upto"]; if upto == "" then upto = nil end
formatting,
local labelShow = args["labelshow"]; if labelShow == "" then labelShow = nil end
languages,
local rowformat = args["rowformat"]; if (rowformat == nil or rowformat == "") then rowformat = "$0 = $1" end
propertySupString,
local separator = args["separator"]; if (separator == nil or separator == "") then separator = "<br />" end
propertyLabel,
local sorting = args["sorting"]; if sorting == "" then sorting = nil end
propertyLink,
local editicon = not (args.editicon == "false" or args.editicon == "no")
labelShow,
editicon,
upto,
upto_linkId,
last_only,
grammatical_case,
include_self)
if (upto_linkId == nil) then upto_linkId = "" end
local upto_link_ids = mw.text.split(upto_linkId, '[/%s]+')
local propertySups = mw.text.split(propertySupString, '[/%s]+')
local lastlabel = uc_first(upto or '')
Baris 1.146 ⟶ 1.388:
end
end
local label_self
_, label_self = getPropertyValue(id, propertyLabel, "label", languages)
local result = {}
local label, link, linktext
for iter = 1, maxloop do
local label, link
for _, propertySup in pairs(propertySups) do
id, link = getPropertyValue(id, propertySup, args.formatting, languages, editicon)
_id, _link = getPropertyValue(id, propertySup, formatting, languages, editicon, grammatical_case)
if id then
if _id and _link then id = _id link = _link break end
_, label = getPropertyValue(id, propertyLabel, "label", languages)
end
if label and link then
if propertyLink then
if not id or not link then break end
_, linktext = getPropertyValue(id, propertyLink, "label", languages)
if linktext then
if propertyLink then
link = mw.ustring.gsub(link, "%[%[(.*)%|(.+)%]%]", "[[%2|" .. linktext .. "]] [[%1|·]]")
_, linktext = getPropertyValue(id, propertyLink, "label", languages)
end
if linktext then
end
link = mw.ustring.gsub(link, "%[%[(.*)%|.+%]%]", "[[%1|" .. linktext .. "]]")
label = case(label, "infoboxlabel", languages[1])
if labelShow == nil or labelFilter[label] then
result[#result + 1] = {label, link}
labelFilter[label] = nil -- only first label found
end
if label == lastlabel then
break
end
else
break
end
elseend
_, label = getPropertyValue(id, propertyLabel, "label", languages, editicon, "infoboxlabel")
if labelShow == nil or labelFilter[label] then
result[#result + 1] = {label, link}
if label then
labelFilter[label] = nil -- only first label found
end
end
if not tonumber(upto) and label == lastlabel then
break
end
if contains(upto_link_ids, id) then
break
end
end
if last_only then
result = {result[#result]}
end
if include_self then table.insert(result, 1, {label_self, mw.title.getCurrentTitle().text}) end
return result
end
 
local function parentObjectsToString(result,
rowformat,
cascade,
sorting)
local ret = {}
Baris 1.183 ⟶ 1.450:
local iter = 1
if sorting == "-1" then first = #result; last = 1; iter = -1 end
 
for i = first, last, iter do
local rowtext = mw.ustring.gsub(rowformat, "$[01]", {["$0"] = result[i][1], ["$1"] = result[i][2]})
ret[#ret +1] = expandBraces(rowtext, rowformat)
end
if cascade then
local prefix = ""
for i = 1, #ret do
ret[i] = prefix .. "• " .. ret[i]
prefix = prefix .. "&nbsp;"
end
end
return ret
end
 
-- Returns pairs of instance label and property value fetching a recursive tree
function p.getParentValues(frame)
if not required and frame.args and frame:getParent().args.sandbox then
return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).getParentValues(frame)
end
local args = frame.args or frame -- via invoke or require
local id = getEntityId(frame)
if id == nil then return end
local languages = findLang(args.lang)
local propertySup = args.property; if not isSet(propertySup) then propertySup = "P131" end --administrative entity
local propertyLabel = args.label; if not isSet(propertyLabel) then propertyLabel = "P31" end --instance
local propertyLink = args.valuetext; if propertyLink == "" then propertyLink = nil end --internallink
local upto = args.upto; if upto == "" then upto = nil end
local last_only = (args.last_only == "true" or args.last_only == "yes")
local labelShow = args.labelshow; if labelShow == "" then labelShow = nil end
local editicon = not (args.editicon == "false" or args.editicon == "no")
local include_self = (args.include_self == "true" or args.include_self == "yes")
local case = args.case; if case == "" then case = nil end
if isSet(args.uptolabelid) then
upto = mw.wikibase.getLabel(args.uptolabelid)
end
if isSet(args.showlabelid) then
local showLabelList = {}
for substring in mw.text.gsplit(args.showlabelid, '[/%s]+') do
table.insert(showLabelList, mw.wikibase.getLabel(substring))
end
if #showLabelList > 0 then
labelShow = table.concat(showLabelList,"/")
end
end
local result = getParentObjects(id,
args.formatting,
languages,
propertySup,
propertyLabel,
propertyLink,
labelShow,
editicon,
upto,
args.uptolinkid,
last_only,
case,
include_self)
if #result == 0 then return end
local rowformat = args.rowformat; if not isSet(rowformat) then rowformat = "$0 = $1" end
local separator = args.separator; if not isSet(separator) then separator = "<br />" end
local sorting = args.sorting; if sorting == "" then sorting = nil end
local cascade = (args.cascade == "true" or args.cascade == "yes")
local ret = parentObjectsToString(result,
rowformat,
cascade,
sorting)
ret = addEditIconTable(ret, {property=propertySup, editicon=editicon, id=id, lang=languages})
return mw.text.listToText(ret, separator, separator)
end
 
-- Link with a parent label --------------------
function p.linkWithParentLabel(frame)
if not required and frame.args and frame:getParent().args.sandbox then
return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).linkWithParentLabel(frame)
end
local args = {}
if frame.args then
for k, v in pairs(frame.args) do -- metatable
args[k] = v
end
else
args = frame -- via require
end
if isSet(args.value) then
return args.value
-- get internal link of property/qualifier
args.list = "true"
args.formatting = "internallink"
args.separator = "/·/"
local pargs = frame:getParent().args
local link_list = p._main(args, pargs)
if link_list == nil or link_list == "" then
return
end
local link_table = mw.text.split(link_list, "/·/", true)
-- get id value of property/qualifier
local largs = mw.clone(args)
args.formatting = "raw"
largs.list = "true"
local items_list = p._main(args, pargs)
largs.formatting = "raw"
largs.separator = "/·/"
largs.editicon = "false"
local items_list = p.claim(largs)
if not isSet(items_list) then return end
local items_table = mw.text.split(items_list, "/·/", true)
-- get internal link of property/qualifier
largs.formatting = "internallink"
local link_list = p.claim(largs)
local link_table = mw.text.split(link_list, "/·/", true)
-- get label of parent property
local parent_claim = getSnak(findClaims(items_table[1], args.parent), {1, "mainsnak", "datatype"})
args.property = args.parent
if parent_claim == 'monolingualtext' then
args.qualifier = nil
largs.formatting = nil
local parent_claims = findClaims(mw.wikibase.getEntity(items_table[1]), args.parent)
largs.list = 'lang'
if parent_claims and parent_claims[1].mainsnak.datatype == 'monolingualtext' then
args.formatting = nil
args.list = 'lang'
else
argslargs.formatting = "label"
argslargs.list = "false"
end
largs.property = args.parent
largs.qualifier = nil
for i, v in ipairs(items_table) do
argslargs.item = v
local link_label = p._mainclaim(args, pargslargs)
if isSet(link_label and link_label ~= '') then
link_table[i] = mw.ustring.gsub(link_table[i] or '', "%[%[(.*)%|.+%]%]", "[[%1|" .. link_label .. "]]")
end
end
args.editicon = not (args.editicon == "false" or args.editicon == "no")
args.id = getEntityId(frame)
return mw.text.listToText(link_table)
args.lang = findLang(args.lang)
return mw.text.listToText(link_table) .. addEditIcon(args)
end
 
-- Calculate number of years old ----------------------------
function p.years_old(frame)
function p.yearsOld(frame)
local args = frame.args
if not required and frame.args and frame:getParent().args.sandbox then
local id = args.item
return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).yearsOld(frame)
if id == '' or id == nil then
id = mw.wikibase.getEntityIdForCurrentPage()
end
local args = frame.args or frame -- via invoke or require
local id = getEntityId(frame)
local lang = mw.language.new('en')
local function getBestValue(id, prop)
local snaksnak_value = getSnak(mw.wikibase.getBestStatements(id, prop)[, {1], "mainsnak", "datavalue", "value"})
return snak_value
if snak and snak.mainsnak and snak.mainsnak.datavalue and snak.mainsnak.datavalue.value then
return snak.mainsnak.datavalue.value
end
end
Baris 1.304 ⟶ 1.651:
local old_min = age(dates[1].max, dates[2].min)
local old_max = age(dates[1].min, dates[2].max)
local old, old_expr
local old = old_min == old_max and old_min or old_min .. "/" .. old_max
if args.formattingold_min == 0 and old_max == 0 then
old = "< 1"
old = expandBraces(mw.ustring.gsub(args.formatting, '$1', old), args.formatting)
old_max = 1 -- expression in singular
elseif old_min == old_max then
old = old_min
else
old = old_min .. "/" .. old_max
end
if args.formatting == 'unit' then
local langs = findLang(args.lang)
local yo, yo_sg, yo_pl, yo_pau
if langs[1] == wiki.langcode then
yo_sg = i18n["years-old"].singular
yo_pl = i18n["years-old"].plural
yo_pau = i18n["years-old"].paucal
end
if not isSet(yo_pl) then
yo_pl = getLabelByLangs('Q24564698', langs)
yo_sg = yo_pl
end
if not isSet(yo_pau) then
yo_pau = yo_pl
end
yo = mw.language.new(langs[1]):plural(old_max, {yo_sg, yo_pau, yo_pl})
if mw.ustring.find(yo, '$1', 1, true) then
old_expr = mw.ustring.gsub(yo, "$1", old)
else
old_expr = old .. '&nbsp;' .. yo
end
elseif args.formatting then
old_expr = expandBraces(mw.ustring.gsub(args.formatting, '$1', old), args.formatting)
else
old_expr = old
end
return oldold_expr
end
 
-- Gets a label in a given language (content language by default) or its fallbacks, optionnally linked.
function p.getLabel(frame)
p.Untranslated = false
if not required and frame.args and frame:getParent().args.sandbox then
return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).getLabel(frame)
end
local args = frame.args or frame -- via invoke or require
local id = mw.text.trimgetEntityId(args[1]frame, or ""true)
if id == ""nil then return end
local editicon = not (args.editicon == "false" or args.editicon == "no") and mw.wikibase.isValidEntityId(id)
local pencillabel_icon = ''
local label, lang
if args.label then
Baris 1.325 ⟶ 1.707:
else
local languages = findLang(args.lang)
-- exceptions or labels fixed
if languages[1] == wiki.langcode then
local exist, labels = pcall(require, wiki.module_title .. "/labels" .. (languages[1] == wiki.langcode and '' or '/' .. languages[1]))
-- exceptions or labels fixed
if exist and next(labels.infoboxLabelsFromId) ~= nil then
local exist, labels = pcall(require, wiki.module_title .. "/labels")
iflabel exist= and next(labels.infoboxLabelsFromId) ~= nil then[id]
label = labels.infoboxLabelsFromId[id]
end
end
if label == nil then
label,local langnew_id = getLabelByLangsresolveEntityId(id, languages)
if labelnew_id then
label, lang = getLabelByLangs(new_id, languages)
if args.itemgender and feminineGender(args.itemgender) then
if label = feminineForm(id, lang) or labelthen
if args.itemgender and feminineGender(args.itemgender) then
label = feminineForm(new_id, lang) or label
end
label = mw.language.new(lang):ucfirst(mw.text.nowiki(label)) -- sanitize
end
label_icon = addLabelIcon(new_id or id, lang, languages[1], editicon)
label = mw.language.new(lang):ucfirst(mw.text.nowiki(label)) -- sanitize
end
pencil = addEditIcon(id, lang, languages[1], editicon)
end
end
local linked = args.linked
if isSet(linked and linked ~= "") and linked ~= "no" then
local article = mw.wikibase.getSitelink(id) or ("d:" .. id)
return "[[" .. article .. "|" .. (label or id) .. "]]" .. pencillabel_icon
else
return (label or id) .. pencillabel_icon
end
end
 
-- Utilities -----------------------------
-- Return default language used
-- See also module ../debug.
function p.lang(frame)
return findLang(frame.args[1])[1]
end
 
-- Copied from Module:Wikibase
--[[
function p.getSiteLink(frame)
This is used to return an image legend from Wikidata
local id = getEntityId(frame, 1)
image is property P18
if id == nil then
image legend is property P2096
return
 
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
return mw.wikibase.getSitelink(id, mw.text.trim(frame.args[2] or ''))
end
 
-- Helper function for the default language code used
-- look for named parameter lang
function p.lang(frame)
-- it should contain a two-character ISO-639 language code
local lang = frame and frame.args[1] -- nil via require
-- if it's blank fetch the language of the local wiki
return findLang(lang)[1]
local lang = frame.args.lang
end
if (not lang) or (#lang < 2) then
lang = mw.language.getContentLanguage().code
end
 
-- Number of statements
-- first unnamed parameter is the local parameter, if supplied
function p.numStatements(frame)
local input_parm = mw.text.trim(frame.args[1] or "")
local id = getEntityId(frame)
if input_parm == "FETCH_WIKIDATA" then
if id == nil then
local ent = mw.wikibase.getEntityObject(id)
localreturn imgs0
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
local args = frame.args
local prop = mw.text.trim(args[1])
local num = mw.wikibase.getBestStatements(id, prop)
return #num
end
 
-- Returns true if property datavalue is found excluding novalue/somevalue
-- This is used to get the QIDs of all of the values of a property, as a comma separated list if multiple values exist
function p.validProperty(frame)
-- Usage: {{#invoke:Wikidata |getPropertyIDs |<PropertyID> |FETCH_WIKIDATA}}
local property = mw.text.trim(frame.args[1])
-- Usage: {{#invoke:Wikidata |getPropertyIDs |<PropertyID> |<InputParameter> |qid=<QID>}}
local item = getEntityId(frame)
 
if item == nil then return end
p.getPropertyIDs = function(frame)
local properties = mw.wikibase.getBestStatements(item, property)
local go, errorOrentity, propclaims = parseInput(frame)
if not#properties go== 0 then return end
return properties[1].mainsnak.datavalue and true or nil
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