16,599
edits
(Created page with "-- Original module located at en:Module:Wd and en:Module:Wd/i18n. local p = {} local arg = ... local i18n local function loadI18n(aliasesP, frame) local title i...") |
Ajay Kumar (talk | contribs) (Trying to fix some issues.) |
||
(7 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
-- Original module located at [[:en:Module:Wd]] and [[:en:Module:Wd/i18n]]. | -- Original module located at [[:en:Module:Wd]] and [[:en:Module:Wd/i18n]]. | ||
require("strict") | |||
local p = {} | local p = {} | ||
local arg = ... | local arg = ... | ||
Line 72: | Line 73: | ||
image = "P18", | image = "P18", | ||
author = "P50", | author = "P50", | ||
authorNameString = "P2093", | |||
publisher = "P123", | publisher = "P123", | ||
importedFrom = "P143", | importedFrom = "P143", | ||
wikimediaImportURL = "P4656", | |||
statedIn = "P248", | statedIn = "P248", | ||
pages = "P304", | pages = "P304", | ||
Line 94: | Line 97: | ||
inferredFrom = "P3452", | inferredFrom = "P3452", | ||
typeOfReference = "P3865", | typeOfReference = "P3865", | ||
column = "P3903" | column = "P3903", | ||
subjectNamedAs = "P1810", | |||
wikidataProperty = "P1687", | |||
publishedIn = "P1433" | |||
} | } | ||
Line 148: | Line 154: | ||
} | } | ||
local | local function replaceAlias(id) | ||
if aliasesP[id] then | |||
id = aliasesP[id] | |||
end | |||
return id | |||
end | |||
local function errorText(code, param) | |||
function | local text = i18n["errors"][code] | ||
local | if param then text = mw.ustring.gsub(text, "$1", param) end | ||
return text | |||
end | |||
local function throwError(errorMessage, param) | |||
error(errorText(errorMessage, param)) | |||
end | |||
local function replaceDecimalMark(num) | |||
return mw.ustring.gsub(num, "[.]", i18n['numeric']['decimal-mark'], 1) | |||
end | |||
local function padZeros(num, numDigits) | |||
local numZeros | |||
local negative = false | |||
if num < 0 then | |||
negative = true | |||
num = num * -1 | |||
end | |||
num = tostring(num) | |||
numZeros = numDigits - num:len() | |||
for _ = 1, numZeros do | |||
num = "0"..num | |||
end | |||
if negative then | |||
num = "-"..num | |||
end | |||
return num | |||
end | |||
local function replaceSpecialChar(chr) | |||
if chr == '_' then | |||
-- replace underscores with spaces | |||
return ' ' | |||
else | |||
return chr | |||
end | |||
end | end | ||
local | local function replaceSpecialChars(str) | ||
local chr | |||
local esc = false | |||
local strOut = "" | |||
for i = 1, #str do | |||
chr = str:sub(i,i) | |||
if not esc then | |||
if chr == '\\' then | |||
esc = true | |||
else | |||
strOut = strOut .. replaceSpecialChar(chr) | |||
end | |||
else | |||
strOut = strOut .. chr | |||
esc = false | |||
end | |||
end | |||
return strOut | |||
end | |||
local function buildWikilink(target, label) | |||
if not label or target == label then | |||
return "[[" .. target .. "]]" | |||
else | |||
return "[[" .. target .. "|" .. label .. "]]" | |||
end | |||
end | |||
-- used to make frame.args mutable, to replace #frame.args (which is always 0) | |||
-- with the actual amount and to simply copy tables | |||
local function copyTable(tIn) | |||
if not tIn then | |||
return nil | |||
end | |||
local tOut = {} | |||
for i, v in pairs(tIn) do | |||
tOut[i] = v | |||
end | end | ||
return | return tOut | ||
end | end | ||
local function | -- used to merge output arrays together; | ||
-- note that it currently mutates the first input array | |||
local function mergeArrays(a1, a2) | |||
for i = 1, #a2 do | |||
end | a1[#a1 + 1] = a2[i] | ||
end | |||
return a1 | |||
end | end | ||
local function | local function split(str, del) | ||
local out = {} | |||
local i, j = str:find(del) | |||
if i and j then | |||
out[1] = str:sub(1, i - 1) | |||
out[2] = str:sub(j + 1) | |||
else | |||
out[1] = str | |||
end | |||
return out | |||
end | |||
local function parseWikidataURL(url) | |||
local id | |||
if url:match('^http[s]?://') then | |||
id = split(url, "Q") | |||
if id[2] then | |||
return "Q" .. id[2] | |||
end | |||
end | end | ||
return | return nil | ||
end | end | ||
local function | local function parseDate(dateStr, precision) | ||
precision = precision or "d" | |||
local i, j, index, ptr | |||
local parts = {nil, nil, nil} | |||
local | |||
local | |||
if dateStr == nil then | |||
return parts[1], parts[2], parts[3] -- year, month, day | |||
end | end | ||
-- 'T' for snak values, '/' for outputs with '/Julian' attached | |||
i, j = dateStr:find("[T/]") | |||
if i then | |||
if | dateStr = dateStr:sub(1, i-1) | ||
end | end | ||
local from = 1 | |||
-- | |||
if dateStr:sub(1,1) == "-" then | |||
-- this is a negative number, look further ahead | |||
from = 2 | |||
end | end | ||
index = 1 | |||
ptr = 1 | |||
i, j = dateStr:find("-", from) | |||
if i then | |||
-- year | |||
parts[index] = tonumber(dateStr:sub(ptr, i-1), 10) -- explicitly give base 10 to prevent error | |||
- | if parts[index] == -0 then | ||
-- | parts[index] = tonumber("0") -- for some reason, 'parts[index] = 0' may actually store '-0', so parse from string instead | ||
end | |||
if precision == "y" then | |||
end | -- we're done | ||
return parts[1], parts[2], parts[3] -- year, month, day | |||
end | |||
index = index + 1 | |||
ptr = i + 1 | |||
i, j = dateStr:find("-", ptr) | |||
if i then | |||
-- month | |||
parts[index] = tonumber(dateStr:sub(ptr, i-1), 10) | |||
if precision == "m" then | |||
-- we're done | |||
return parts[1], parts[2], parts[3] -- year, month, day | |||
end | |||
index = index + 1 | |||
ptr = i + 1 | |||
end | |||
end | |||
if | if dateStr:sub(ptr) ~= "" then | ||
-- day if we have month, month if we have year, or year | |||
parts[index] = tonumber(dateStr:sub(ptr), 10) | |||
end | end | ||
return | return parts[1], parts[2], parts[3] -- year, month, day | ||
end | end | ||
function | local function datePrecedesDate(aY, aM, aD, bY, bM, bD) | ||
if aY == nil or bY == nil then | |||
return nil | |||
end | |||
aM = aM or 1 | |||
aD = aD or 1 | |||
bM = bM or 1 | |||
bD = bD or 1 | |||
if aY < bY then | |||
return true | |||
end | |||
if | if aY > bY then | ||
return | return false | ||
end | end | ||
if aM < bM then | |||
return true | |||
end | |||
if | if aM > bM then | ||
return false | |||
end | end | ||
if aD < bD then | |||
return true | |||
if | |||
end | end | ||
return false | |||
end | |||
local function getHookName(param, index) | |||
if hookNames[param] then | |||
return hookNames[param][index] | |||
elseif param:len() > 2 then | |||
return hookNames[param:sub(1, 2).."\\d"][index] | |||
else | |||
return nil | |||
end | |||
end | |||
local function alwaysTrue() | |||
return true | |||
end | |||
-- The following function parses a format string. | |||
-- | |||
-- The example below shows how a parsed string is structured in memory. | |||
-- Variables other than 'str' and 'child' are left out for clarity's sake. | |||
-- | |||
-- Example: | |||
-- "A %p B [%s[%q1]] C [%r] D" | |||
-- | |||
-- Structure: | |||
-- [ | |||
-- { | |||
-- str = "A " | |||
-- }, | |||
-- { | |||
-- str = "%p" | |||
-- }, | |||
-- { | |||
-- str = " B ", | |||
-- child = | |||
-- [ | |||
-- { | |||
-- str = "%s", | |||
-- child = | |||
-- [ | |||
-- { | |||
-- str = "%q1" | |||
-- } | |||
-- ] | |||
-- } | |||
-- ] | |||
-- }, | |||
-- { | |||
-- str = " C ", | |||
-- child = | |||
-- [ | |||
-- { | |||
-- str = "%r" | |||
-- } | |||
-- ] | |||
-- }, | |||
-- { | |||
-- str = " D" | |||
-- } | |||
-- ] | |||
-- | |||
local function parseFormat(str) | |||
local chr, esc, param, root, cur, prev, new | |||
local params = {} | |||
local function newObject(array) | |||
local obj = {} -- new object | |||
obj.str = "" | |||
array[#array + 1] = obj -- array{object} | |||
obj.parent = array | |||
return obj | |||
end | end | ||
local function endParam() | |||
if param > 0 then | |||
if cur.str ~= "" then | |||
cur.str = "%"..cur.str | |||
cur.param = true | |||
params[cur.str] = true | |||
cur.parent.req[cur.str] = true | |||
prev = cur | |||
cur = newObject(cur.parent) | |||
end | |||
param = 0 | |||
end | |||
end | end | ||
root = {} -- array | |||
root.req = {} | |||
cur = newObject(root) | |||
prev = nil | |||
esc = false | |||
param = 0 | |||
for i = 1, #str do | |||
chr = str:sub(i,i) | |||
if not esc then | |||
if chr == '\\' then | |||
endParam() | |||
esc = true | |||
elseif chr == '%' then | |||
endParam() | |||
if cur.str ~= "" then | |||
cur = newObject(cur.parent) | |||
end | |||
param = 2 | |||
elseif chr == '[' then | |||
endParam() | |||
if prev and cur.str == "" then | |||
table.remove(cur.parent) | |||
cur = prev | |||
end | |||
cur.child = {} -- new array | |||
cur.child.req = {} | |||
cur.child.parent = cur | |||
cur = newObject(cur.child) | |||
elseif chr == ']' then | |||
endParam() | |||
if cur.parent.parent then | |||
new = newObject(cur.parent.parent.parent) | |||
if cur.str == "" then | |||
table.remove(cur.parent) | |||
end | |||
cur = new | |||
end | |||
else | |||
if param > 1 then | |||
param = param - 1 | |||
elseif param == 1 then | |||
if not chr:match('%d') then | |||
endParam() | |||
end | |||
end | |||
cur.str = cur.str .. replaceSpecialChar(chr) | |||
end | |||
else | |||
cur.str = cur.str .. chr | |||
esc = false | |||
end | |||
prev = nil | |||
end | end | ||
endParam() | |||
end | |||
-- make sure that at least one required parameter has been defined | |||
if not next(root.req) then | |||
throwError("missing-required-parameter") | |||
end | |||
-- make sure that the separator parameter "%s" is not amongst the required parameters | |||
if | if root.req[parameters.separator] then | ||
throwError("extra-required-parameter", parameters.separator) | |||
end | end | ||
return root, params | |||
return | |||
end | end | ||
local function sortOnRank(claims) | |||
local rankPos | |||
local ranks = {{}, {}, {}, {}} -- preferred, normal, deprecated, (default) | |||
local sorted = {} | |||
for _, v in ipairs(claims) do | |||
rankPos = rankTable[v.rank] or 4 | |||
ranks[rankPos][#ranks[rankPos] + 1] = v | |||
end | |||
sorted = ranks[1] | |||
sorted = mergeArrays(sorted, ranks[2]) | |||
sorted = mergeArrays(sorted, ranks[3]) | |||
return sorted | |||
end | |||
local Config = {} | |||
-- | |||
-- allows for recursive calls | |||
function Config:new() | |||
local cfg = {} | |||
setmetatable(cfg, self) | |||
self.__index = self | |||
cfg.separators = { | |||
-- single value objects wrapped in arrays so that we can pass by reference | |||
["sep"] = {copyTable(defaultSeparators["sep"])}, | |||
["sep%s"] = {copyTable(defaultSeparators["sep%s"])}, | |||
["sep%q"] = {copyTable(defaultSeparators["sep%q"])}, | |||
["sep%r"] = {copyTable(defaultSeparators["sep%r"])}, | |||
["punc"] = {copyTable(defaultSeparators["punc"])} | |||
} | |||
cfg.entity = nil | |||
cfg.entityID = nil | |||
cfg.propertyID = nil | |||
cfg.propertyValue = nil | |||
cfg.qualifierIDs = {} | |||
cfg.qualifierIDsAndValues = {} | |||
cfg.bestRank = true | |||
cfg.ranks = {true, true, false} -- preferred = true, normal = true, deprecated = false | |||
cfg.foundRank = #cfg.ranks | |||
cfg.flagBest = false | |||
cfg.flagRank = false | |||
cfg.periods = {true, true, true} -- future = true, current = true, former = true | |||
cfg.flagPeriod = false | |||
cfg.atDate = {parseDate(os.date('!%Y-%m-%d'))} -- today as {year, month, day} | |||
cfg.mdyDate = false | |||
cfg.singleClaim = false | |||
cfg.sourcedOnly = false | |||
cfg.editable = false | |||
cfg.editAtEnd = false | |||
cfg.inSitelinks = false | |||
cfg.langCode = mw.language.getContentLanguage().code | |||
cfg.langName = mw.language.fetchLanguageName(cfg.langCode, cfg.langCode) | |||
cfg.langObj = mw.language.new(cfg.langCode) | |||
cfg.siteID = mw.wikibase.getGlobalSiteId() | |||
cfg.states = {} | |||
cfg.states.qualifiersCount = 0 | |||
cfg.curState = nil | |||
cfg.prefetchedRefs = nil | |||
return cfg | |||
end | |||
local State = {} | |||
function State:new(cfg, type) | |||
local stt = {} | |||
setmetatable(stt, self) | |||
self.__index = self | |||
stt.conf = cfg | |||
stt.type = type | |||
stt.results = {} | |||
stt.parsedFormat = {} | |||
stt.separator = {} | |||
stt.movSeparator = {} | |||
stt.puncMark = {} | |||
stt.linked = false | |||
stt.rawValue = false | |||
stt.shortName = false | |||
stt.anyLanguage = false | |||
stt.unitOnly = false | |||
stt.singleValue = false | |||
return | return stt | ||
end | end | ||
-- if id == nil then item connected to current page is used | |||
local | function Config:getLabel(id, raw, link, short) | ||
local | local label = nil | ||
local prefix, title= "", nil | |||
if not id then | |||
id = mw.wikibase.getEntityIdForCurrentPage() | |||
if not id then | |||
if not id then | |||
return "" | return "" | ||
end | end | ||
Line 670: | Line 675: | ||
if mw.wikibase.isValidEntityId(id) and mw.wikibase.entityExists(id) then | if mw.wikibase.isValidEntityId(id) and mw.wikibase.entityExists(id) then | ||
label = id | label = id | ||
end | end | ||
prefix = "d:" | prefix, title = "d:Special:EntityPage/", label -- may be nil | ||
else | else | ||
-- try short name first if requested | -- try short name first if requested | ||
Line 691: | Line 690: | ||
-- get label | -- get label | ||
if not label then | if not label then | ||
label = mw.wikibase.getLabelByLang(id, self.langCode) | label = mw.wikibase.getLabelByLang(id, self.langCode) -- XXX: should use fallback labels? | ||
end | end | ||
end | end | ||
Line 704: | Line 703: | ||
elseif id:sub(1,1) == "P" then | elseif id:sub(1,1) == "P" then | ||
-- properties have no sitelink, link to Wikidata instead | -- properties have no sitelink, link to Wikidata instead | ||
title | prefix, title = "d:Special:EntityPage/", id | ||
end | end | ||
end | end | ||
label = mw.text.nowiki(label) -- escape raw label text so it cannot be wikitext markup | |||
if title then | if title then | ||
label = buildWikilink(prefix .. title, label) | label = buildWikilink(prefix .. title, label) | ||
Line 745: | Line 744: | ||
value = value .. "#" .. self.propertyID | value = value .. "#" .. self.propertyID | ||
elseif self.inSitelinks then | elseif self.inSitelinks then | ||
value = value .. "#sitelinks- | value = value .. "#sitelinks-bharatpedia" | ||
end | end | ||
Line 877: | Line 876: | ||
if not unitOnly then | if not unitOnly then | ||
-- get value and strip + signs from front | -- get value and strip + signs from front | ||
value = mw.ustring.gsub(datavalue['amount'], "^ | value = mw.ustring.gsub(datavalue['amount'], "^%+(.+)$", "%1") | ||
if raw then | if raw then | ||
Line 1,289: | Line 1,288: | ||
lonLink = table.concat({lonDegrees, lonMinutes, lonSeconds}, "_") | lonLink = table.concat({lonDegrees, lonMinutes, lonSeconds}, "_") | ||
value = "[https:// | value = "[https://geohack.toolforge.org/geohack.php?language="..self.langCode.."¶ms="..latLink.."_"..latDirectionEN.."_"..lonLink.."_"..lonDirectionEN.."_globe:"..globe.." "..value.."]" | ||
end | end | ||
Line 1,811: | Line 1,810: | ||
local value = "" | local value = "" | ||
local ref = {} | local ref = {} | ||
local referenceEmpty = true -- will be set to false if at least one parameter is left unremoved | |||
local numAuthorParameters = 0 | |||
local numAuthorNameStringParameters = 0 | |||
local tempLink | |||
local additionalRefProperties = {} -- will hold properties of the reference which are not in statement.snaks, namely backup title from "subject named as" and URL from an external ID | |||
local wikidataPropertiesOfSource -- will contain "Wikidata property" properties of the item in stated in, if any | |||
local version = | local version = 4 -- increment this each time the below logic is changed to avoid conflict errors | ||
if statement.snaks then | if statement.snaks then | ||
Line 1,818: | Line 1,823: | ||
if statement.snaks[aliasesP.importedFrom] then | if statement.snaks[aliasesP.importedFrom] then | ||
statement.snaks[aliasesP.importedFrom] = nil | statement.snaks[aliasesP.importedFrom] = nil | ||
end | |||
-- don't include "Wikimedia import URL" | |||
if statement.snaks[aliasesP.wikimediaImportURL] then | |||
statement.snaks[aliasesP.wikimediaImportURL] = nil | |||
-- don't include "retrieved" if no "referenceURL" is present, | |||
-- as "retrieved" probably belongs to "Wikimedia import URL" | |||
if statement.snaks[aliasesP.retrieved] and not statement.snaks[aliasesP.referenceURL] then | |||
statement.snaks[aliasesP.retrieved] = nil | |||
end | |||
end | end | ||
Line 1,839: | Line 1,854: | ||
statement.snaks[aliasesP.language] = nil | statement.snaks[aliasesP.language] = nil | ||
end | end | ||
if statement.snaks[aliasesP.statedIn] and not statement.snaks[aliasesP.referenceURL] then | |||
-- "stated in" was given but "reference URL" was not. | |||
-- get "Wikidata property" properties from the item in "stated in" | |||
-- if any of the returned properties of the external-id datatype is in statement.snaks, generate a URL from it and use the URL in the reference | |||
-- find the "Wikidata property" properties in the item from "stated in" | |||
wikidataPropertiesOfSource = mw.text.split(p._properties{p.flags.raw, aliasesP.wikidataProperty, [p.args.eid] = self.conf:getValue(statement.snaks[aliasesP.statedIn][1], true, false)}, ", ", true) | |||
for i, wikidataPropertyOfSource in pairs(wikidataPropertiesOfSource) do | |||
if statement.snaks[wikidataPropertyOfSource] and statement.snaks[wikidataPropertyOfSource][1].datatype == "external-id" then | |||
tempLink = self.conf:getValue(statement.snaks[wikidataPropertyOfSource][1], false, true) -- not raw, linked | |||
if mw.ustring.match(tempLink, "^%[%Z- %Z+%]$") then -- getValue returned a URL. | |||
additionalRefProperties[aliasesP.referenceURL] = mw.ustring.gsub(tempLink, "^%[(%Z-) %Z+%]$", "%1") -- the URL is in wiki markup, so strip the square brackets and the display text | |||
statement.snaks[wikidataPropertyOfSource] = nil | |||
break | |||
end | |||
end | |||
end | |||
end | |||
-- don't include "subject named as", but use it as the title when "title" is not present but a URL is | |||
if statement.snaks[aliasesP.subjectNamedAs] then | |||
if not statement.snaks[aliasesP.title] and (statement.snaks[aliasesP.referenceURL] or additionalRefProperties[aliasesP.referenceURL]) then | |||
additionalRefProperties[aliasesP.title] = statement.snaks[aliasesP.subjectNamedAs][1].datavalue.value | |||
end | |||
statement.snaks[aliasesP.subjectNamedAs] = nil | |||
end | |||
-- retrieve all the parameters | -- retrieve all the parameters | ||
Line 1,845: | Line 1,887: | ||
-- multiple authors may be given | -- multiple authors may be given | ||
if i == aliasesP.author then | if i == aliasesP.author or i == aliasesP.authorNameString then | ||
params[i] = self:getReferenceDetails(statement.snaks, i, false, self.linked, true) -- link = true/false, anyLang = true | params[i] = self:getReferenceDetails(statement.snaks, i, false, self.linked, true) -- link = true/false, anyLang = true | ||
else | else | ||
Line 1,854: | Line 1,896: | ||
params[i] = nil | params[i] = nil | ||
else | else | ||
referenceEmpty = false | |||
if statement.snaks[i][1].datatype == 'external-id' then | if statement.snaks[i][1].datatype == 'external-id' then | ||
key = "external-id" | key = "external-id" | ||
Line 1,873: | Line 1,917: | ||
-- continue if an option is available in the corresponding cite template | -- continue if an option is available in the corresponding cite template | ||
if i18n['cite'][j][key] ~= "" then | if i18n['cite'][j][key] ~= "" then | ||
-- handle non-author properties (and author properties ("author" and "author name string"), if they don't use the same template parameter) | |||
if (i ~= aliasesP.author and i ~= aliasesP.authorNameString) or (i18n['cite'][j][aliasesP.author] ~= i18n['cite'][j][aliasesP.authorNameString]) then | |||
citeParams[j][i18n['cite'][j][key]] = label .. params[i][1] | |||
-- to avoid problems with non-author multiple parameters (if existent), the following old code is retained | |||
for k=2, #params[i] do | |||
citeParams[j][i18n['cite'][j][key]..k] = label .. params[i][k] | |||
end | |||
-- handle "author" and "author name string" specially if they use the same template parameter | |||
elseif i == aliasesP.author or i == aliasesP.authorNameString then | |||
if params[aliasesP.author] ~= nil then | |||
numAuthorParameters = #params[aliasesP.author] | |||
else | |||
numAuthorParameters = 0 | |||
end | |||
if params[aliasesP.authorNameString] ~= nil then | |||
numAuthorNameStringParameters = #params[aliasesP.authorNameString] | |||
else | |||
numAuthorNameStringParameters = 0 | |||
end | |||
-- execute only if both "author" and "author name string" satisfy this condition: the property is both in params and in statement.snaks or it is neither in params nor in statement.snaks | |||
-- reason: parameters are added to params each iteration of the loop, not before the loop | |||
if ((statement.snaks[aliasesP.author] == nil) == (numAuthorParameters == 0)) and ((statement.snaks[aliasesP.authorNameString] == nil) == (numAuthorNameStringParameters == 0)) then | |||
for k=1, numAuthorParameters + numAuthorNameStringParameters do | |||
if k <= numAuthorParameters then -- now handling the authors from the "author" property | |||
citeParams[j][i18n['cite'][j][aliasesP.author]..k] = label .. params[aliasesP.author][k] | |||
else -- now handling the authors from "author name string" | |||
citeParams[j][i18n['cite'][j][aliasesP.authorNameString]..k] = label .. params[aliasesP.authorNameString][k - numAuthorParameters] | |||
end | |||
end | |||
end | |||
end | |||
end | end | ||
else | else | ||
Line 1,884: | Line 1,955: | ||
end | end | ||
end | end | ||
end | |||
end | |||
end | |||
-- use additional properties | |||
for i in pairs(additionalRefProperties) do | |||
for j in pairs(citeParams) do | |||
if not citeMismatch[j] and i18n["cite"][j][i] then | |||
citeParams[j][i18n["cite"][j][i]] = additionalRefProperties[i] | |||
else | |||
citeMismatch[j] = true | |||
end | end | ||
end | end | ||
Line 1,920: | Line 2,002: | ||
end | end | ||
-- (3) | -- (3) if the citation couldn't be displayed using Cite web or Cite Q, but has properties other than the removed ones, throw an error | ||
elseif not referenceEmpty then | |||
value = "<span style=\"color: crimson\">" .. errorText("malformed-reference") .. "</span>" | |||
end | |||
if value ~= "" then | |||
value = {value} -- create one value object | |||
-- | if not self.rawValue then | ||
-- this should become a <ref> tag, so save the reference's hash for later | |||
value.refHash = "wikidata-" .. statement.hash .. "-v" .. (tonumber(i18n['cite']['version']) + version) | |||
end | end | ||
ref = {value} -- wrap the value object in an array | |||
ref = {value} -- wrap the value object in an array | |||
end | end | ||
end | end | ||
Line 2,507: | Line 2,549: | ||
value = value or "" | value = value or "" | ||
if cfg.editable and value ~= "" then | if cfg.editable and value ~= "" then | ||
-- if desired, add a clickable icon that may be used to edit the returned value on Wikidata | -- if desired, add a clickable icon that may be used to edit the returned value on Wikidata | ||
value = value .. cfg:getEditIcon() | value = value .. cfg:getEditIcon() | ||
end | end | ||
return value | |||
end | |||
-- modules that include this module should call the functions with an underscore prepended, e.g.: p._property(args) | |||
local function establishCommands(commandList, commandFunc) | |||
for _, commandName in pairs(commandList) do | |||
local function wikitextWrapper(frame) | |||
local args = copyTable(frame.args) | |||
args.pointer = 1 | |||
loadI18n(aliasesP, frame) | |||
return commandFunc(args, commandName) | |||
end | |||
p[commandName] = wikitextWrapper | |||
local function luaWrapper(args) | |||
args = copyTable(args) | |||
args.pointer = 1 | |||
loadI18n(aliasesP) | |||
return commandFunc(args, commandName) | |||
end | |||
p["_" .. commandName] = luaWrapper | |||
end | |||
end | |||
establishCommands(p.claimCommands, claimCommand) | |||
establishCommands(p.generalCommands, generalCommand) | |||
-- main function that is supposed to be used by wrapper templates | |||
function p.main(frame) | |||
if not mw.wikibase then return nil end | |||
local f, args | local f, args | ||