Modul:Wikidata/bakpasir: Perbedaan revisi

6.115 bita ditambahkan ,  1 bulan yang lalu
-- version 20200701 from master @cawiki
(+pageId)
(-- version 20200701 from master @cawiki)
 
-- version 2020041520200701 from master @cawiki
 
local p = {}
[10] = "F Y", -- precision: month
[11] = "F j, Y", -- precision: day
["hms"] = {["hours"] = "h", ["minutes"] = "m", ["seconds"] = "s"}, -- duration: xh xm xs
},
},
["cite"] = { -- Cite webcite parameters
["urltitle"] = "urltitle",
["titleauthor"] = "titleauthor",
["websitedate"] = "websitedate",
["access-datepages"] = "access-datepages",
["archive-urllanguage"] = "archive-urllanguage",
-- cite web parameters
["archive-date"]= "archive-date",
["authorurl"] = "authorurl",
["publisherwebsite"] = "publisherwebsite",
["quoteaccess-date"] = "quoteaccess-date",
["languagearchive-url"] = "languagearchive-url",
["archive-date"] = "archive-date",
["pagespublisher"] = "pagespublisher",
["quote"] = "quote",
-- cite journal parameters
["work"] = "work",
["issue"] = "issue",
["issn"] = "issn",
["doi"] = "doi"
},
}
 
local untranslated -- used in infobox modules: nil or true
p.Untranslated = false
local _ -- variable for unused returned values, avoiding globals
 
-- 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
if type(v) == "table" then
if type(t1[k] or false) == "table" then
 
local function loadI18n(lang)
local i18n_titleexist, res = 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)
cases = res.cases
end
if lang ~= wiki.langcode then
exist, res = pcall(require, wiki.module_title .. "/i18n/" .. lang)
if exist and next(res) ~= nil then
tableMerge(i18n, res.i18n)
tableMerge(cases, res.cases)
end
end
end
-- Argument is 'set' when it exists (not nil) or when it is not an empty string.
local function isSet(var)
return not (not var == nil or var == '')
end
 
return label
end
 
-- get safely a serialized snak
local function getSnak(statement, snaks)
local ret = statement
for i, v in ipairs(snaks) do
if not ret then return end
ret = ret[v]
end
return ret
end
 
for _, l in ipairs(languages) do
if l == wiki.langcode then
-- using getLabelWithLang when possible instead of getLabelByLang, do not solve redirects pending phab:T157868
label, l = mw.wikibase.getLabelWithLang(id)
else
end
return label, lang
end
 
-- getBestStatements if bestrank=true, else getAllStatements with no deprecated
local function getStatements(entityId, property, bestrank)
local claims = {}
if not (entityId and mw.ustring.match(property, "^P%d+$")) then return claims end
if bestrank then
claims = mw.wikibase.getBestStatements(entityId, property)
else
local allclaims = mw.wikibase.getAllStatements(entityId, property)
for _, c in ipairs(allclaims) do
if c.rank ~= "deprecated" then
table.insert(claims, c)
end
end
end
return claims
end
 
local function feminineGender(id)
local claims = mw.wikibase.getBestStatements(id or mw.wikibase.getEntityIdForCurrentPage(),'P21')
if getSnak(claims, {1, "mainsnak", "datavalue"}) == nil then -- no claim, novalue or somevalue
if #claims == 0 then
return false
elseif claims[1].mainsnak.datavalue == nil then -- novalue or somevalue
return false
else
-- Fetch female form of label
local function feminineForm(id, lang)
local feminine_claims = mw.wikibase.getBestStatementsgetStatements(id, 'P2521') -- female form of label
for _, feminine_claim in ipairs(feminine_claims) do
if getSnak(feminine_claim., {'mainsnak.', 'datavalue.', 'value.', 'language'}) == lang then
return feminine_claim.mainsnak.datavalue.value.text
end
end
end
 
-- get safely a serialized snak
local function getSnak(statement, snaks)
local ret = statement
for i, v in ipairs(snaks) do
if ret == nil then return end
ret = ret[v]
end
return ret
end
 
.. mw.message.new('Translate-taction-translate'):inLanguage(uselang):plain()
.. "|link=https://www.wikidata.org/wiki/Special:EntityPage/" .. label_id .. "?uselang=" .. uselang .. "]]"
p.Untranslated untranslated = true
end
if isSet(i18n.categorylabels) and lang ~= uselang and uselang == wiki.langcode then
end
return ret_lang .. ret_icon
end
 
-- editicon values: true/false (no=false), right, void defaults to i18n.addpencil
local function setEditIcon(param)
if not isSet(param) then return i18n.addpencil end
if param == "false" or param == "no" then return false end
return param
end
 
local function addEditIcon(parameters)
local ret = ''
if i18n.addpencil and parameters.editicon and parameters.id and parameters.property then
local icon_style = parameters.editicon == "right" and ' style="float: right;"' or ''
ret = ' <span data-bridge-edit-flow="overwrite">'
ret = ' <span class="penicon" data-bridge-edit-flow="single-best-value"' .. icon_style .. '>'
.. "[[File:Arbcom ru editing.svg|10px|baseline|"
.. string.gsub(mw.message.new('EditlinkWikibase-client-data-bridge-bailout-suggestion-go-to-repo-button'):inLanguage(parameters.lang[1]):plain(), '{{WBREPONAME}}', 'Wikidata')
.. "|link=https://www.wikidata.org/wiki/" .. parameters.id .. "?uselang=" .. parameters.lang[1] .. "#" .. parameters.property .. "]]"
.. "</span>"
-- add edit icon to the last element of a table
local function addEditIconTable(thetable, parameters)
if #thetable == 0 or not i18nparameters.addpencilediticon == false then
return thetable
end
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 fallbacksEnglish, maybe it is a redirect
-- not using mw.title.new(id).isRedirect as it is expensive
-- currently getLabelByLang does not follows redirects
if mw.wikibase.getLabel(id) == nil then
if mw.wikibase.getLabelByLang(id, 'en') == nil then
local entity = mw.wikibase.getEntity(id) -- expensive function
if not entity then return nil end
require(wiki.module_title .. '/debug').track('redirect/' .. id)
else
-- no redirect and no English label, fix it to avoid expensive functions
require(wiki.module_title .. '/debug').track('label')
require(wiki.module_title .. '/debug').track('label/' .. id)
end
 
-- format data valuetype string
local function printDatavalueStringprintDatatypeString(data, parameters)
if mw.ustring.find((parameters.formatting or ''), '$1', 1, true) then -- formatting = a pattern
return expandBraces(mw.ustring.gsub(parameters.formatting, '$1', {['$1'] = data}), parameters.formatting)
elseif parameters.case then
return case(parameters.case, data, parameters.lang[1])
end
local data_number = string.match(data, "^%d+")
if data_number then -- sort key by initial number and remaining string
local sortkey = string.format("%019d", data_number * 1000)
return data, sortkey .. string.sub(data, #data_number + 1)
end
return data
return '[' .. data .. ' ' .. label .. ']'
end
return printDatavalueStringprintDatatypeString(data, parameters)
end
 
-- format data type external-id
local function printDatatypeExternal(data, parameters)
if parameters.formatting == 'externalid' then
local p_stat = mw.wikibase.getBestStatements(parameters.property, 'P1630') -- formatter URL
local p_link_pattern = getSnak(p_stat, {1, "mainsnak", "datavalue", "value"})
if p_link_pattern then
local p_link = mw.ustring.gsub(p_link_pattern, '$1', {['$1'] = data})
return '[' .. p_link .. ' ' .. data .. ']'
end
end
return printDatatypeString(data, parameters)
end
 
icon = "no-icon"
end
return printDatavalueStringprintDatatypeString(data, parameters), icon
end
 
-- format data valuetype globecoordinateglobe-coordinate
local function printDatavalueCoordinateprintDatatypeCoordinate(data, formatting)
local function globes(globe_id)
local globes = {['Q3134']='callisto',['Q596']='ceres',['Q15040']='dione',['Q2']='earth',['Q3303']='enceladus',
if unit_symbol == '' then
-- fetch it
local claims = findClaimsmw.wikibase.getBestStatements(id, 'P5061')
if #claims > 0 then
local langclaims = {}
table.insert(lang, 'mul') -- multilingual as last try
end
 
local function roundPrecisionroundDefPrecision(in_num, out_numfactor)
-- rounds out_num with significant figures of in_num (default precision)
local out_num = in_num * factor
if factor/60 == math.floor(factor/60) then -- sexagesimal integer
return out_num
end
-- first, count digits after decimal mark, handling cases like '12.345e6'
local exponent, prec
end
 
-- format data valuetype quantity
local function printDatavalueQuantityprintDatatypeQuantity(data, parameters)
local amount = data.amount
amount = mw.ustring.gsub(amount, "%+", "")
local suffix = ""
local conv_amount, conv_suffix
if string.sub(parameters.formatting or '', 1, 4) == "unit" or string.sub(parameters.formatting or '', 1, 8) == "duration" or parameters.convert then
-- example "unit": "http://www.wikidata.org/entity/Q174728"
local unit_id = data.unit
unit_id = mw.ustring.sub(unit_id, mw.ustring.find(unit_id, "Q"), -1)
end
elseif string.sub(parameters.convert or '', 1, 1) == "Q" then
convert_to = resolveEntityId(parameters.convert)
elseif string.sub(parameters.formatting or '', 1, 8) == "duration" then
convert_to = 'Q11574' -- seconds
end
if convert_to and convert_to ~= unit_id then
conv_amount = math.floor(tonumber(amount_f) + 0.5)
else
local conversions = mw.wikibase.getAllStatementsgetStatements(unit_id, 'P2442') -- conversion to standard unit
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 = roundPrecisionroundDefPrecision(amount, amount * tonumber(conv.mainsnak.datavalue.value.amount))
break
end
local lang_obj = mw.language.new(parameters.lang[1])
local sortkey = string.format("%019d", tonumber(amount) * 1000)
if string.sub(parameters.formatting or '', 1, 8) == "duration" then
local sec = tonumber(conv_amount or amount)
if parameters.formatting == 'durationhms' or parameters.formatting == 'durationh:m:s' then
local intervals = {"hours", "minutes", "seconds"}
local sec2table = lang_obj:getDurationIntervals(sec, intervals)
sec2table["seconds"] = (sec2table["seconds"] or 0) + tonumber("." .. (tostring(sec):match("%.(%d+)") or "0")) -- add decimals
local duration = ''
for i, v in ipairs(intervals) do
if parameters.formatting == 'durationh:m:s' then
if i == 1 and sec2table[v] then
duration = duration .. sec2table[v] .. ":"
elseif i == 2 then
duration = duration .. string.format("%02d", sec2table[v] or 0) .. ":"
elseif i == 3 then
local sec_str = tostring(lang_obj:formatNum(sec2table[v] or 0))
duration = duration .. (sec2table[v] < 10 and "0" or "") .. sec_str
end
elseif sec2table[v] then
duration = duration .. lang_obj:formatNum(sec2table[v]) .. i18n.datetime.hms[v] .. (i < 3 and " " or "")
end
end
return duration
else
return lang_obj:formatDuration(sec)
end
end
if parameters.case then
amount = case(parameters.case, amount, parameters.lang[1])
end
 
-- format data valuetype time
local function printDatavalueTimeprintDatatypeTime(data, parameters)
-- Dates and times are stored in ISO 8601 format
local timestamp = data.time
end
 
-- format data value entitywikibase-entityid: types wikibase-item, wikibase-property
local function printDatavalueEntityprintDatatypeEntity(data, parameters)
local entity_id = data['id']
if parameters.formatting == 'raw' then
if data['entity-type'] == 'item' then
entity_id = resolveEntityId(entity_id)
end
return entity_id, entity_id
end
end
if parameters.case ~= 'gender' then
labelcase = case(parameters.case, labelcase, lang, parameters.lang[1], entity_id, parameters.id)
end
local ret1, ret2
ret1 = '[[' .. sitelink .. '|' .. labelcase .. ']]'
ret2 = labelcase
elseif label and string.match(parameter ==or '', 'internallink$') orand parameternot == 'ucinternallink'mw.wikibase.getEntityIdForTitle(label) then
ret1 = '[[' .. label .. '|' .. labelcase .. ']]'
ret2 = labelcase
end
 
-- format data valuetype monolingualtext
local function printDatavalueMonolingualTextprintDatatypeMonolingual(data, parameters)
-- data fields: language [string], text [string]
end
return result
end
 
local function printError(key)
return '<span class="error">' .. i18n.errors[key] .. '</span>'
end
 
-- the "qualifiers" and "snaks" field have a respective "qualifiers-order" and "snaks-order" field
-- use these as the second parameter and this function instead of the built-in "pairs" function
-- to iterate over all qualifiers and snaks in the intended order.
local function orderedpairs(array, order)
if not order then return pairs(array) end
 
-- return iterator function
local i = 0
return function()
i = i + 1
if order[i] then
return order[i], array[order[i]]
end
end
end
 
function findClaims(entityId, property)
if not property or not entityId then return end
if not mw.ustring.match(property, "^P%d+$") then
-- get property id for the given label
property = mw.wikibase.resolvePropertyId(property)
if not property then return end
end
local claims = mw.wikibase.getAllStatements(entityId, property)
if #claims == 0 then
claims = nil
end
return claims
end
 
local function getSnakValue(snak, parameters)
if snak.snaktype == 'value' then
-- see Special:ListDatatypes
-- call the respective snak parser
if snak.datatype == 'math'"string" then
return printDatatypeString(snak.datavalue.value, parameters)
-- other data value string, tabular-data not implemented
elseif snak.datatype == "commonsMedia" then
return printDatatypeMedia(snak.datavalue.value, parameters)
elseif snak.datatype == "url" then
return printDatatypeUrl(snak.datavalue.value, parameters)
elseif snak.datatype == "external-id" then
return printDatatypeExternal(snak.datavalue.value, parameters)
elseif snak.datatype == 'math' then
return printDatatypeMath(snak.datavalue.value)
elseif snak.datatype == 'musical-notation' then
return printDatatypeMusical(snak.datavalue.value, parameters.formatting)
-- other data types
elseif snak.datatype == "url" then
elseif snak.datatype == 'wikibase-item' or snak.datatype == 'wikibase-property' then
return printDatatypeUrl(snak.datavalue.value, parameters)
return printDatatypeEntity(snak.datavalue.value, parameters)
elseif snak.datatype == "commonsMedia" then
elseif snak.datatype == 'monolingualtext' then
return printDatatypeMedia(snak.datavalue.value, parameters)
elseif return printDatatypeMonolingual(snak.datavalue.typevalue, == "string" thenparameters)
elseif snak.datatype == "globe-coordinate" then
return printDatavalueString(snak.datavalue.value, parameters)
elseif return printDatatypeCoordinate(snak.datavalue.typevalue, == "globecoordinate" thenparameters.formatting)
elseif snak.datatype == "quantity" then
return printDatavalueCoordinate(snak.datavalue.value, parameters.formatting)
elseif return printDatatypeQuantity(snak.datavalue.typevalue, == "quantity" thenparameters)
elseif snak.datatype == "time" then
return printDatavalueQuantity(snak.datavalue.value, parameters)
elseif return printDatatypeTime(snak.datavalue.typevalue, == "time" thenparameters)
return printDatavalueTime(snak.datavalue.value, parameters)
elseif snak.datavalue.type == 'wikibase-entityid' then
return printDatavalueEntity(snak.datavalue.value, parameters)
elseif snak.datavalue.type == 'monolingualtext' then
return printDatavalueMonolingualText(snak.datavalue.value, parameters)
end
elseif snak.snaktype == 'novalue' then
if parameters.formatting == 'raw' or parameters.shownovalue == false then return end
return mw.message.new('Wikibase-snakview-snaktypeselector-novalue'):inLanguage(parameters.lang[1]):plain()
elseif snak.snaktype == 'somevalue' then
end
return mw.wikibase.renderSnak(snak)
end
 
local function printError(key)
return '<span class="error">' .. i18n.errors[key] .. '</span>'
end
 
end
 
local function getValueOfClaim(claim, qualifierId, parameters)
local snak, error = getQualifierSnak(claim, qualifierId, parameters)
if not snak then
return nil, nil, error
elseif snak[1] then -- a multi qualifier
local result, sortkey = {}, {}
local sortkeymaxvals = {}tonumber(parameters.list)
for idx in pairs(snak) do
result[#result + 1], sortkey[#sortkey + 1] = getSnakValue(snak[idx], parameters)
if maxvals and maxvals == #result then break end
end
return mw.text.listToText(result, parameters.qseparator, parameters.qconjunction), sortkey[1]
local function getValueOfParentClaim(claim, qualifierId, parameters)
local qids = mw.text.split(qualifierId, '/', true)
local valuerawvalue, parent_claimssortkey, valuevalueraw = {}, sortkey{}, {}
local parent_raw, value_text
if qids[1] == parameters.property then
valuerawparent_raw, _, _ = getValueOfClaim(claim, nil, {["formatting"]="raw", ["lang"]=parameters.lang})
else
valuerawparent_raw, _, _ = getValueOfClaim(claim, qids[1], {["formatting"]="raw", ["lang"]=parameters.lang, ["list"]=true, ["qseparator"]='/', ["qconjunction"]='/'})
end
if string.sub(valuerawparent_raw or '', 1, 1) == "Q" then -- protection for 'no value'
local parent_qids = mw.text.split(parent_raw, '/', true)
parent_claims = mw.wikibase.getBestStatements(valueraw, qids[2])
for idx, p_qid in ipairs(parent_qids) do
if parent_claims[1] ~= nil then
local parent_claims = mw.wikibase.getBestStatements(p_qid, qids[2])
value, sortkey, _ = getValueOfClaim(parent_claims[1], nil, parameters)
if parent_claims[1] then
-- raw parent value needed for while/black lists, lang for avoiding an error on types other than entity
valueraw value[idx], _sortkey[idx], _ = getValueOfClaim(parent_claims[1], nil, {["formatting"]="raw", ["lang"]=parameters.lang})
-- raw parent value needed for while/black lists, lang for avoiding an error on types other than entity
valueraw[idx], _, _ = getValueOfClaim(parent_claims[1], nil, {["formatting"]="raw", ["lang"]=parameters.lang})
end
end
end
returnif value,[1] sortkey, valuerawthen
value_text = mw.text.listToText(value, parameters.qseparator, parameters.qconjunction)
end
return value_text, sortkey[1], valueraw[1]
end
 
-- see d:Help:Sources
local function getReferences(claim)
local function getReferences(claim, lang)
local notproperref = {
["P143"] = true, -- imported from
local refs = {}
local validref = true
local ref_name
-- traverse through all parts of the current reference
for snakkey, snakval in pairs(claim.references[ref].snaks or {}) do
for snakidx = 1, #snakval do
if snakidx > 1 then refparts = refparts .. ", " end
refparts = refparts or '' .. getSnakValue(snakval[snakidx], {lang={wiki.langcode}lang})
end
refs[snakkey] = refparts
refparts = nil
if snakkey == "P248" then -- stated in
ref_name = snakval[1].datavalue.value.id
end
end
end
-- fill missing values with parent item
-- get title of general template for citing web references
if ref_name then
local template = mw.wikibase.getSitelink('Q5637226') or ""
local function refParent(qid, pid, formatting)
template = mw.text.split(template, ":")[2] -- split off namespace from front
local snak = getSnak(mw.wikibase.getBestStatements(qid, pid), {1, "mainsnak"})
return snak and getSnakValue(snak, {formatting=formatting, lang=lang})
end
refs['P50'] = refs['P50'] or refParent(ref_name, 'P50', 'label') -- author
refs['P407'] = refs['P407'] or refParent(ref_name, 'P407', 'label') -- language of work
refs['P123'] = refs['P123'] or refParent(ref_name, 'P123', 'label') -- publisher
refs['P577'] = refs['P577'] or refParent(ref_name, 'P577') -- date
refs['P1433'] = refs['P1433'] or refParent(ref_name, 'P1433', 'label') -- published in
refs['P304'] = refs['P304'] or refParent(ref_name, 'P304') -- page(s)
refs['P433'] = refs['P433'] or refParent(ref_name, 'P433') -- issue
refs['P236'] = refs['P236'] or refParent(ref_name, 'P236') -- ISSN
refs['P356'] = refs['P356'] or refParent(ref_name, 'P356') -- DOI
end
-- get title of local templates for citing references
-- if both "reference URL" and "title" (or "stated in") are present, then use local cite web template
local template_web = mw.wikibase.getSitelink('Q5637226') or ""
if refs['P854'] and (refs['P1476'] or refs['P248']) and template then
template_web = mw.text.split(template_web, ":")[2] -- split off namespace from front
local citeParams = {}
local template_journal = mw.wikibase.getSitelink('Q5624899') or ""
template_journal = mw.text.split(template_journal, ":")[2]
local citeParams = {}
if refs['P854'] and (refs['P1476'] or refs['P248']) and template_web then
-- if both "reference URL" and "title" (or "stated in") are present, then use cite web template
citeParams[i18n['cite']['url']] = refs['P854']
citeParams[i18nif refs['citeP248']['title']] =and refs['P1476'] or== refs['P248']:match("^%[%[.-|(.-)%]%]")nil then
citeParams[i18n['cite']['title']] = refs['P248']:match("^%[%[.-|(.-)%]%]")
else
citeParams[i18n['cite']['title']] = refs['P1476']
citeParams[i18n['cite']['website']] = refs['P248']
end
citeParams[i18n['cite']['author']] = refs['P50']
citeParams[i18n['cite']['websitelanguage']] = refs['P248P407']
citeParams[i18n['cite']['language']] = refs['P2439']
citeParams[i18n['cite']['publisher']] = refs['P123']
citeParams[i18n['cite']['date']] = refs['P577']
citeParams[i18n['cite']['archive-date']] = refs['P2960']
citeParams[i18n['cite']['quote']] = refs['P1683']
refparts = mw.getCurrentFrame():expandTemplate{title=templatetemplate_web, args=citeParams}
elseif refs['P1433'] and (refs['P1476'] or refs['P248']) and template_journal then
else
-- if both "published in" and "title" (or "stated in") are present, then use cite journal template
citeParams[i18n['cite']['work']] = refs['P1433']
citeParams[i18n['cite']['title']] = refs['P1476'] or refs['P248']
citeParams[i18n['cite']['author']] = refs['P50']
citeParams[i18n['cite']['date']] = refs['P577']
citeParams[i18n['cite']['issue']] = refs['P433']
citeParams[i18n['cite']['pages']] = refs['P304']
citeParams[i18n['cite']['language']] = refs['P407']
citeParams[i18n['cite']['issn']] = refs['P236']
citeParams[i18n['cite']['doi']] = refs['P356']
refparts = mw.getCurrentFrame():expandTemplate{title=template_journal, args=citeParams}
elseif validref then
-- raw ouput
local snaksorder = claim.references[ref]["snaks-order"]
local function indexed(a)
for _, b in ipairs(snaksorder) do
if b == a then return true end
end
return false
end
for k, _ in pairs(refs or {}) do
if not indexed(k) then
table.insert(snaksorder, k)
end
end
local italics = "''"
for k_, vk in orderedpairsipairs(refs or {}, claim.references[ref]["snaks-order"]snaksorder) do
if refs[k and v] then
refparts = refparts and refparts .. " " or ""
refparts = refparts .. mw.ustring.gsub(mw.wikibase.getLabelgetLabelByLangs(k, lang), "^%l", mw.ustring.upper) .. ": "
refparts = refparts .. italics .. vrefs[k] .. italics .. "."
italics = ""
end
end
end
if refparts then result = result .. mw.getCurrentFrame():extensionTag("ref", refparts, {name=ref_name}) end
end
return result
 
-- Set whitelist or blacklist values
local function setWhiteOrBlackList(type_list, num_qual, args)
local lists = {['whitelist']={}, ['blacklist']={}, ['ignorevalue']={}, ['selectvalue']={}}
local listed = false
local list = {}
for i = 0, num_qual do
for k, _ in pairs(lists) do
if isSet(args[type_list .. i]) then
if isSet(args[k .. i]) then
listed = true
list lists[k][tostring(i)] = {}
local for valuesq =in mwstring.text.splitgmatch(args[type_listk .. i], "/",'Q%d+') true)do
lists[k][tostring(i)][resolveEntityId(q)] = true
for _, v in ipairs(values) do
end
list[tostring(i)][v] = true
list[tostring(i)][resolveEntityId(v)] = true
end
end
end
return lists['whitelist'], lists['blacklist'], lists['ignorevalue'], lists['selectvalue']
return list, listed
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
 
function p.claim(frame)
if mw.title.new(frame:getParent():getTitle()).isContentPage then
if not mw.title.new(frame:getTitle()).isSubpage then
-- invoked from a content page and not invoking a module subpage
return printError("not-from-content-page")
end
end
return p._main(frame.args, frame:getParent().args)
end
 
end
 
local function getEntityId(frameargs, pargs, unnamed)
local argspargs = frame.argspargs or frame{}
local pargs = frame.args and frame:getParent().args
local id = args.item or args.from or (unnamed and mw.text.trim(args[1] or '') or nil)
if not isSet(id) and pargs then
id = pargs.item or pargs.from or (unnamed and mw.text.trim(pargs[1] or '') or nil)
end
-- on debug console use: =p.claim{item="Q...", property="P...", ...}
function p.claim(frame)
local args = frame.args or frame -- via invoke or require
p.Untranslated = false
iflocal notpargs required and= frame.args and isSet(frame:getParent().args.sandbox) thenor {}
local is_sandbox = isSet(pargs.sandbox)
if not required and is_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) then
-- arguments
local id = getEntityId(frameargs, pargs)
if id == nil then return end
local property = string.upper(args.property or "")
i = i + 1
end
local formatting = isSet(args.formatting;) ifand args.formatting == "" then formatting =or nil end
local convert = isSet(args.convert;) ifand args.convert == "" then convert =or nil end
local case = args.case
local list = args.list or true; if (list == "false" or list == "no") then list = false end
if list == 'firstrank' then list = 'bestrank' end -- alias
local shownovalue = args.shownovalue or true; if (shownovalue == "false" or shownovalue == "no") then shownovalue = false end
local sorting_col = args.tablesort
local sorting_up = (args.sorting or "") ~= "-1"
local default = args.default
if default then showerrors = nil end
local editicon = not (args.editicon == "false" or args.editicon == "no" or formatting == "raw")
local parameters = {["id"] = id, ["property"] = property, ["formatting"] = formatting, ["convert"] = convert,
["list"] = list, ["case"] = case, ["editiconshownovalue"] = editiconshownovalue,
["separator"] = separator, ["conjunction"] = conjunction, ["qseparator"] = separator, ["qconjunction"] = conjunction}
parameters.lang = findLang(args.lang)
parameters.editicon = formatting ~= "raw" and setEditIcon(args.editicon or pargs.editicon) or false -- needs loadI18n by findLand
-- fetch property
local claims = {}
local bestrank = (parameters.list == false or parameters.list == 'bestrank') and parameters.list ~= 'lang'
for p in string.gmatch(parameters.property, 'P%d+') do
claims = getStatements(id, p, bestrank)
if #claims > 0 then
parameters.property = p
break
end
end
if #claims == 0 then
if showerrors then return printError("property-not-found") else return default end
end
-- defaults for table
local preformat, postformat = "", ""
local whitelisted, blacklisted = false, false
local whitelist, blacklist, ignorevalue, selectvalue = {}, {}, {}, {}
if parameters.formatting == "table" then
parameters.separator = parameters.separator or "<br />"
-- set whitelist and blacklist values
whitelist, whitelistedblacklist, ignorevalue, selectvalue = setWhiteOrBlackList("whitelist", #qualifierId, args)
local next = next
blacklist, blacklisted = setWhiteOrBlackList("blacklist", #qualifierId, args)
if next(whitelist) ~= nil then whitelisted = true end
end
-- fetch property
local claims
for p in string.gmatch(property, 'P%d+') do
claims = findClaims(id, p)
if claims and claims[1] then
parameters.property = p
break
end
end
if not claims or not claims[1] then
if showerrors then return printError("property-not-found") else return default end
end
-- set feminine case if gender is requested
local itemgender = args[".itemgender"]
local idgender
if itemgender then
local sortkeys = {}
local refs = {}
local firstrank = parameters.list == "firstrank" and claims[sortindices[1]].rank or ''
local rowlist = {} -- rows to list with whitelist or blacklist
for idx in pairs(claims) do
local reference = {}
if not whitelisted then rowlist[idx] = true end
if firstrank ~= '' and firstrank ~= claim.rank then
break
end
if parameters.formatting == "table" then
local params = tableParameters(args, parameters, "0")
params = tableParameters(args, parameters, j)
local valueq, sortkeyq, valueraw
if qual == parameters.property then -- hack for getting the property with another formatting, i.e. colformat1=raw
valueq, sortkeyq, _ = getValueOfClaim(claim, nil, params)
else
valueq, sortkeyq, valueraw = getValueOfParentClaim(claim, q, params)
elseif string.find(q, "^/.+") then
local claim2 = findClaimsgetStatements(id, string.sub(q, 2), bestrank)
if #claim2 > 0 then
valueq, sortkeyq, _ = getValueOfClaim(claim2[1], nil, params)
end
values[#values]["col" .. j] = valueq
sortkeys[#sortkeys]["col" .. j] = sortkeyq or valueq
if whitelist[j] or blacklist[j] or ignorevalue[j] or selectvalue[j] then
valueq = valueraw or getValueOfClaim(claim, qual, {["formatting"]="raw", ["lang"]=params.lang})
if whitelist[j] and whitelist[j][valueq or ""] then
elseif blacklist[j] and blacklist[j][valueq or ""] then
rowlist[#values] = false
elseif ignorevalue[j] and ignorevalue[j][valueq or ""] then
values[#values]["col" .. j] = nil
elseif selectvalue[j] and not selectvalue[j][valueq or ""] then
values[#values]["col" .. j] = nil
end
end
end
if sorting_col then
local sorting_table = mw.text.split(sorting_col, '/%D+', true)
local comparator = function(a, b)
local valuea, valueb
table.sort(sortindices, comparator)
end
local maxvals = tonumber(parameters.list)
result = {}
for idx in pairs(values) do
local valuerow = values[sortindices[idx]]
local reference = getReferences({["references"] = refs[sortindices[idx]]["col0"]}, parameters.lang)
value = valuerow["col0"]
for i, _ in ipairs(qualifierId) do
local valueq = valuerow["col" .. i]
if args["rowsubformat" .. i] and isSet(valueq) then
-- add fake end character $
-- gsub $i not followed by a number so $1 doesn't match $10, $11...
if isSet(value) then
result[#result + 1] = value
if not parameters.list or (maxvals and maxvals == #result) then
break
end
end
-- in a table, add edit icon on last element
if parameters.formatting == 'table' and parameters.editicon then
result = addEditIconTable(result, parameters)
end
local claim = claims[sortindices[1]]
result, result2, error = getValueOfClaim(claim, qualifierId[1], parameters)
if result and references then result = result .. getReferences(claim, parameters.lang) end
end
if isSet(result) then
if not (parameters.formatting == 'table' or (result2 and result2 == 'no-icon')) then
-- add edit icon
-- add edit icon, except table added previously and except explicit no-icon internal flag
if parameters.formatting == 'table' then
result = result .. addEditIcon(parameters)
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 returnresult = error else returnresult = default end
end
return result, (required and not is_sandbox) and untranslated or ''
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.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
local ret = table.concat(out, "<br> ")
if #ret == 0 then
ret = "Invalid TA"
end
return ret
end
 
local function getPropertyValue(id, property, parameter, langs, editicon, case)
local snaks = mw.wikibase.getBestStatements(id, property)
local mysnak = getSnak(snaks, {1, "mainsnak"})
if snaksmysnak and== snaks[1] and snaks[1].mainsnaknil then
mysnak = snaks[1].mainsnak
else
return
end
return entity_id, result
end
 
local function contains(tab, val)
for index, value in ipairs(tab) do
if value == val then
return true
end
end
return false
end
 
local function getParentObjects(id,
prop_format,
formatting,
label_format,
languages,
propertySupString,
include_self)
if (upto_linkId == nil) then upto_linkId = "" end
local upto_link_ids = mw.text.split(upto_linkId, '[/%s]+'){}
localfor propertySupsq =in mw.text.splitgsplit(propertySupStringupto_linkId, '[/^Q%sd]+') do
upto_link_ids[resolveEntityId(q)] = true
end
local propertySups = mw.text.split(propertySupString, '[^P%d]')
local lastlabel = uc_first(upto or '')
local maxloop = tonumber(upto) or ((lastlabel .. upto_linkId) == '' and 10 or 50)
local labelFilter = {}
if labelShow then
for i_, v in ipairs(mw.text.split(labelShow, "/")) do
labelFilter[uc_first(v)] = true
end
local label_self
_, label_self = getPropertyValue(id, propertyLabel, "label"label_format, languages)
local result = {}
local label, link, linktext
for iter = 1, maxloop do
local link, label, linklinktext, _id, _link
for _, propertySup in pairs(propertySups) do
_id, _link = getPropertyValue(id, propertySup, formattingprop_format, languages, editicon, grammatical_case)
if _id and _link then id = _id; link = _link break end
end
end
_, label = getPropertyValue(id, propertyLabel, "label"label_format, languages, editiconfalse, "infoboxlabel")
if labelShow == nil or labelFilter[label] then
end
if not tonumber(upto) and label == lastlabel or upto_link_ids[id] then
break
end
if contains(upto_link_ids, id) then
break
end
-- Returns pairs of instance label and property value fetching a recursive tree
function p.getParentValues(frame)
iflocal notargs required and= frame.args andor frame:getParent().args.sandbox then-- via invoke or require
local pargs = frame.args and frame:getParent().args or {}
if not required and isSet(pargs.sandbox) then
return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).getParentValues(frame)
end
local argsid = frame.getEntityId(args, or frame -- via invoke or requirepargs)
local id = getEntityId(frame)
if id == nil then return end
local languages = findLang(args.lang)
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 property_format = args.formatting; if property_format == "" then property_format = nil end
local label_format = args.labelformat; if not isSet(label_format) then label_format = "label" end
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 setEditIcon(args.editicon == "false" or argspargs.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.getLabelgetLabelByLangs(args.uptolabelid, languages)
end
if isSet(args.showlabelid) then
local showLabelList = {}
for substring in mw.text.gsplit(args.showlabelid, '[/^Q%sd]+') do
table.insert(showLabelList, mw.wikibase.getLabel(getLabelByLangs(substring, languages)))
end
if #showLabelList > 0 then
local result = getParentObjects(id,
property_format,
args.formatting,
label_format,
languages,
propertySup,
editicon,
upto,
args.uptovalueid or args.uptolinkid,
last_only,
case,
-- Link with a parent label --------------------
function p.linkWithParentLabel(frame)
iflocal notpargs required and= frame.args and frame:getParent().args.sandbox thenor {}
if not required and isSet(pargs.sandbox) then
return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).linkWithParentLabel(frame)
end
-- get id value of property/qualifier
local largs = mw.clone(args)
largs.list = tonumber(args.list) and args.list or "true"
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(findClaimsgetStatements(items_table[1], args.parent, true), {1, "mainsnak", "datatype"})
if parent_claim == 'monolingualtext' then
largs.formatting = nil
for i, v in ipairs(items_table) do
largs.item = v
local link_label, _ = p.claim(largs)
if isSet(link_label) then
link_table[i] = mw.ustring.gsub(link_table[i] or '', "%[%[(.*)%|.+%]%]", "[[%1|" .. link_label .. "]]")
end
end
args.editicon = not setEditIcon(args.editicon == "false" or argspargs.editicon == "no")
args.id = getEntityId(frameargs, pargs)
args.lang = findLang(args.lang)
return mw.text.listToText(link_table) .. addEditIcon(args)
-- Calculate number of years old ----------------------------
function p.yearsOld(frame)
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()).yearsOld(frame)
end
local args = frame.args or frame -- via invoke or require
local idpargs = getEntityId(frame.args and frame:getParent().args or {}
local id = getEntityId(args, pargs)
local lang = mw.language.new('en')
end
if not isSet(yo_pl) then
yo_pl, _ = getLabelByLangs('Q24564698', langs)
yo_sg = yo_pl
end
-- Gets a label in a given language (content language by default) or its fallbacks, optionnally linked.
function p.getLabel(frame)
local args = frame.args or frame -- via invoke or require
p.Untranslated = false
iflocal notpargs required and= frame.args and frame:getParent().args.sandbox thenor {}
if not required and isSet(pargs.sandbox) then
return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).getLabel(frame)
end
local argsid = frame.getEntityId(args, or frame -- via invoke orpargs, require1)
local id = getEntityId(frame, true)
if id == nil then return end
local languages = findLang(args.lang)
local editicon = not (args.editicon == "false" or args.editicon == "no") and mw.wikibase.isValidEntityId(id)
local editicon = mw.wikibase.isValidEntityId(id) and setEditIcon(args.editicon or pargs.editicon) or false
local label_icon = ''
label = args.label
else
local languages = findLang(args.lang)
-- exceptions or labels fixed
local exist, labels = pcall(require, wiki.module_title .. "/labels" .. (languages[1] == wiki.langcode and '' or '/' .. languages[1]))
if label == nil then
locallabel, new_idlang = resolveEntityIdgetLabelByLangs(id, languages)
if new_idlabel then
if args.itemgender and feminineGender(args.itemgender) then
label, lang = getLabelByLangs(new_id, languages)
if label then= feminineForm(id, lang) or label
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 = mw.language.new(lang):ucfirst(mw.text.nowiki(label)) -- sanitize
label_icon = addLabelIcon(new_id or id, lang, languages[1], editicon)
end
label_icon = addLabelIcon(id, lang, languages[1], editicon)
end
end
local linked = args.linked
if isSet(linked) and linked ~= "no" then
local article = mw.wikibase.getSitelink(id) or ("d:Special:EntityPage/" .. id)
return "[[" .. article .. "|" .. (label or id) .. "]]" .. label_icon, not required and '' or untranslated
else
return (label or id) .. label_icon, not required and '' or untranslated
end
end
-- Copied from Module:Wikibase
function p.getSiteLink(frame)
local idargs = getEntityId(frame,.args 1)or frame -- via invoke or require
local pargs = frame.args and frame:getParent().args or {}
local id = getEntityId(args, pargs, 1)
if id == nil then
return
-- Number of statements
function p.numStatements(frame)
local idargs = getEntityId(frame).args or frame -- via invoke or require
local pargs = frame.args and frame:getParent().args or {}
if id == nil then
local id = getEntityId(args, pargs)
return 0
if id == nil then return 0 end
end
local args = frame.args
local prop = mw.text.trim(args[1])
local num = mw.wikibase.getBestStatements(id, prop){}
if args[2] then -- qualifier
local qual = mw.text.trim(args[2])
local values = p.claim{item=id, property=prop, qualifier=qual, formatting='raw', separator='/·/'}
if values then
num = mw.text.split(values, '/·/')
end
else
num = mw.wikibase.getBestStatements(id, prop)
end
return #num
end
-- Returns true if property datavalue is found excluding novalue/somevalue
function p.validProperty(frame)
local propertyargs = mw.text.trim(frame.args[1]) or frame -- via invoke or require
local itempargs = getEntityId(frame.args and frame:getParent().args or {}
local item = getEntityId(args, pargs)
if item == nil then return end
local propertiesproperty = mw.wikibasetext.getBestStatementstrim(item, propertyargs[1])
local prop_data = getSnak(mw.wikibase.getBestStatements(item, property), {1, "mainsnak", "datavalue"})
if #properties == 0 then return end
return properties[1].mainsnak.datavalueprop_data and true or nil
end
 
function p.editAtWikidata(frame)
local args = frame.args or frame -- via invoke or require
local pargs = frame.args and frame:getParent().args or {}
local value = isSet(args[1])
if value then return end
local param = {}
param.id = getEntityId(args, pargs)
param.property = args.property
param.lang = findLang(args.lang)
param.editicon = setEditIcon(args.editicon)
return addEditIcon(param)
end