3 862
contributi
(p.isRedirect) |
m (una versione importata) |
||
Riga 1: | Riga 1: | ||
-- | --[[ | ||
* Modulo per implementare le funzionalità dei template: | |||
* {{Wikidata}}, {{WikidataQ}}, {{WikidataIdx}}, {{WikidataN}}, {{WikidataLabel}}, {{WikidataDescription}} | |||
* {{WikidataLink}}, {{WikidataId}}, {{WikidataTipo}} e {{WikidataIstanza}}. | |||
* Permette di accedere a Wikidata in modo più avanzato rispetto a {{#property}}. | |||
* Per la maggior parte riscritto e ampliato a partire dalla versione iniziale a: | |||
* http://test2.wikipedia.org/w/index.php?title=Module:Wikidata&oldid=52322 | |||
]] | |||
-- ============================================================================= | |||
-- | -- Non utilizzare mai mw.wikibase.getEntity, per esempio un solo utilizzo di | ||
-- mw.wikibase.getEntity('Q183') fa aumentare di 7 MB l'utilizzo di memoria | |||
-- per Lua ed è molto lenta se ripetuta (unico utilizzo in getDatatype, | |||
-- solo per proprietà, non essendoci alternative). | |||
-- ============================================================================= | |||
require('Module:No globals') | |||
local | local getArgs = require('Module:Arguments').getArgs | ||
local mConvert = require('Module:Conversione') | |||
local mLanguages = require('Module:Linguaggi') | |||
local | -- Categoria per le pagine con errori | ||
local errorCategory = '[[Categoria:Voci con errori del modulo Wikidata]]' | |||
local | -- Messaggi | ||
local i18n = { | |||
errors = { | |||
['entityid-param-not-provided'] = "Parametro ''entityid'' non fornito", | |||
['property-param-not-provided'] = "Parametro ''property'' non fornito", | |||
['qualifier-param-not-provided'] = "Parametro ''qualifier'' non fornito", | |||
['value-param-not-provided'] = "Parametro ''valore'' da ricercare non fornito", | |||
['entity-not-found'] = 'Entità non trovata', | |||
['unknown-claim-type'] = 'Tipo asserzione sconosciuta', | |||
['unknown-snak-type'] = 'Tipo di snak sconosciuto', | |||
['unknown-datavalue-type'] = 'Tipo di dato sconosciuto', | |||
['unknown-entity-type'] = 'Tipo di entità sconosciuta' | |||
}, | |||
somevalue = "''valore sconosciuto''", | |||
novalue = "''nessun valore''", | |||
datatypes = { | |||
['commonsMedia'] = 'file multimediale su Commons', | |||
['external-id'] = 'identificativo esterno', | |||
['geo-shape'] = 'forma geografica', | |||
['globe-coordinate'] = 'coordinate geografiche', | |||
['math'] = 'espressione matematica', | |||
['monolingualtext'] = 'testo monolingua', | |||
['quantity'] = 'quantità', | |||
['string'] = 'stringa', | |||
['tabular-data'] = 'tabular data', | |||
['time'] = 'data e ora', | |||
['url'] = 'URL', | |||
['wikibase-item'] = 'elemento', | |||
['wikibase-property'] = 'proprietà' | |||
} | |||
} | |||
local | local p = {} | ||
------------------------------------------------------------------------------- | |||
-- Formatters | |||
------------------------------------------------------------------------------- | |||
local function | local function errhandler(msg) | ||
return | local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or '' | ||
return string.format('<span class="error">%s</span>%s', msg, cat) | |||
end | end | ||
local function | local function formatList(values, ordered) | ||
return | local fmt = ordered and '<ol><li>%s</li></ol>' or '<ul><li>%s</li></ul>' | ||
return #values > 0 and string.format(fmt, mw.text.listToText(values, '</li><li>', '</li><li>')) or '' | |||
end | end | ||
local function | local function formatExtLink(url) | ||
local protocols = { ftp = true, http = true, https = true } | |||
local | local success, uri = pcall(function() return mw.uri.new(url) end) | ||
if success and uri.protocol and protocols[uri.protocol] then | |||
local dest = tostring(uri) | |||
return string.format('<span style="word-break: break-all;">[%s %s]</span>', dest, dest:gsub(uri.protocol .. '://', '')) | |||
local | |||
else | else | ||
return | return url | ||
end | end | ||
end | end | ||
function | local function formatEntityId(entityId) | ||
if | local label = mw.wikibase.getLabel(entityId) | ||
local siteLink = mw.wikibase.getSitelink(entityId) | |||
local ret | |||
if entityId == mw.wikibase.getEntityIdForCurrentPage() then | |||
ret = siteLink | |||
elseif siteLink and label then | |||
ret = mw.getContentLanguage():ucfirst(label) == siteLink and | |||
string.format('[[%s]]', label) or | |||
string.format('[[%s|%s]]', siteLink, label) | |||
elseif siteLink then | |||
ret = string.format('[[%s]]', siteLink) | |||
elseif label then | |||
ret = label | |||
else | |||
ret = '' | |||
end | end | ||
return | return ret | ||
end | end | ||
local function formatMonolingualtext(value, args) | |||
local function | local ret = '' | ||
local | if not args.includelang or args.includelang:match('%f[a-z]' .. value.language .. '%f[^a-z]') then | ||
if not args.excludelang or not args.excludelang:match('%f[a-z]' .. value.language .. '%f[^a-z]') then | |||
ret = value.text | |||
if args.showlang then | |||
ret = mLanguages.lingue({ value.language }) .. ' ' .. ret | |||
end | |||
end | |||
end | end | ||
return ret | |||
return | |||
end | end | ||
local function | local function formatTimeWithPrecision(time, precision) | ||
local | local months = { | ||
if | 'gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno', | ||
'luglio', 'agosto', 'settembre', 'ottobre', 'novembre', 'dicembre' | |||
elseif | } | ||
local ret, year, month, day | |||
year, month, day = time:match('(%d+)%-(%d%d)%-(%d%d).+') | |||
year, month, day = tonumber(year), tonumber(month), tonumber(day) | |||
if precision == 9 then | |||
ret = year | |||
elseif precision == 10 then | |||
ret = months[month] .. ' ' .. year | |||
elseif precision == 11 then | |||
ret = day .. ' ' .. months[month] .. ' ' .. year | |||
ret = ret:gsub('^1%s', '1º ') | |||
end | end | ||
if precision >= 9 and precision <= 11 then | |||
ret = ret .. (time:sub(1, 1) == '-' and ' a.C.' or '') | |||
end | |||
return ret | |||
end | end | ||
local function | local function formatTime(value, args) | ||
if not | local ret | ||
if args.time == 'precision' then | |||
ret = value.precision | |||
elseif args.time == 'calendarmodel' then | |||
ret = value.calendarmodel | |||
elseif args.time == 'year' and value.precision >= 9 then | |||
ret = formatTimeWithPrecision(value.time, 9) | |||
elseif args.time == 'month' and value.precision >= 10 then | |||
ret = formatTimeWithPrecision(value.time, 10) | |||
elseif args.time == 'day' and value.precision >= 11 then | |||
ret = formatTimeWithPrecision(value.time, 11) | |||
elseif not args.time then | |||
ret = formatTimeWithPrecision(value.time, value.precision) | |||
end | end | ||
return ret or '' | |||
end | end | ||
local function | local function formatGlobecoordinate(value, args) | ||
local ret | |||
if args.coord == 'latitude' then | |||
ret = value.latitude | |||
local | elseif args.coord == 'longitude' then | ||
ret = value.longitude | |||
elseif args.coord == 'globe' then | |||
ret = value.globe | |||
else | |||
elseif | ret = string.format('%s, %s', value.latitude, value.longitude) | ||
elseif | |||
end | end | ||
return | return ret | ||
end | end | ||
local function | local function formatFromPattern(str, args) | ||
local | local pattern = args.pattern | ||
pattern = mw.ustring.gsub(pattern, '\\{', '{') | |||
return | pattern = mw.ustring.gsub(pattern, '\\}', '}') | ||
return mw.getCurrentFrame():preprocess(mw.message.newRawMessage(pattern, str):plain()) | |||
end | end | ||
local function | local function formatUserValue(value, args) | ||
if | if args.extlink then | ||
value = formatExtLink(value) | |||
end | end | ||
return | return args.pattern and formatFromPattern(value, args) or value | ||
end | end | ||
local function | local function getEntityIdFromValue(value) | ||
local prefix = '' | |||
if value['entity-type'] == 'item' then | |||
prefix = 'Q' | |||
elseif value['entity-type'] == 'property' then | |||
prefix = 'P' | |||
else | |||
error(i18n.errors['unknown-entity-type']) | |||
end | end | ||
return | return prefix .. value['numeric-id'] | ||
end | end | ||
function | local function formatUnitSymbol(entityId, args) | ||
local ret | |||
for _, lang in ipairs({ 'mul', 'it', 'en' }) do | |||
ret = p._getProperty({ 'P5061', includelang = lang, from = entityId }) | |||
if ret and ret ~= '' then | |||
break | |||
else | |||
ret = nil | |||
end | |||
end | end | ||
local space = ret == '°' and '' or ' ' | |||
if ret and args.showunitlink then | |||
local link = mw.wikibase.getSitelink(entityId) | |||
if link then | |||
ret = string.format('[[%s|%s]]', link, ret) | |||
end | |||
end | end | ||
return ret and (space .. ret) or '' | |||
end | |||
-- http://lua-users.org/wiki/SimpleRound | |||
local function round(num, idp) | |||
local mult = 10 ^ (idp or 0) | |||
return math.floor(num * mult + 0.5) / mult | |||
end | |||
local function formatQuantity(value, args) | |||
local | local ret = tonumber(value.amount) | ||
if (args.unit or args.showunit) and value.unit ~= '1' then | |||
local unitId = mw.ustring.match(value.unit, 'Q%d+') | |||
if args.unit then | |||
local opts = { | |||
showunit = args.showunit, | |||
showunitlink = args.showunitlink, | |||
formatnum = args.formatnum, | |||
if | rounding = args.rounding | ||
} | |||
ret = mConvert._main(ret, unitId, args.unit, opts) | |||
else | |||
-- se è richiesto solo il simbolo dell'unità | |||
-- senza la conversione lo ottiene da P5061 | |||
ret = args.rounding and round(ret, args.rounding) or ret | |||
if args.formatnum then | |||
ret = mw.language.getContentLanguage():formatNum(ret) | |||
end | |||
ret = ret .. formatUnitSymbol(unitId, args) | |||
end | end | ||
elseif args.formatnum then | |||
ret = args.rounding and round(ret, args.rounding) or ret | |||
ret = mw.language.getContentLanguage():formatNum(ret) | |||
elseif args.formatduration and value.unit ~= '1' then | |||
local unitId = mw.ustring.match(value.unit, 'Q%d+') | |||
ret = mConvert._main(ret, unitId, 'second') | |||
ret = ret and mw.language.getContentLanguage() | |||
:formatDuration(tonumber(ret), { 'days', 'hours', 'minutes', 'seconds' }) | |||
end | end | ||
return ret | |||
return | |||
end | end | ||
local function | local function formatDatavalue(datavalue, snakdatatype, args) | ||
local ret | |||
local | if datavalue.type == 'wikibase-entityid' then | ||
if | local entityId = getEntityIdFromValue(datavalue.value) | ||
if args.showprop then | |||
ret = p._getProperty({ args.showprop, n = 1, from = entityId }) or '' | |||
else | |||
ret = args.formatting == 'raw' and entityId or formatEntityId(entityId) | |||
end | |||
elseif datavalue.type == 'string' then | |||
ret = datavalue.value | |||
if args.extlink and snakdatatype == 'url' then | |||
ret = formatExtLink(ret) | |||
elseif args.urlencode then | |||
ret = mw.uri.encode(ret) | |||
end | |||
elseif datavalue.type == 'monolingualtext' then | |||
ret = formatMonolingualtext(datavalue.value, args) | |||
elseif datavalue.type == 'time' then | |||
if args.formatting == 'raw' then | |||
ret = datavalue.value.time | |||
else | |||
ret = formatTime(datavalue.value, args) | |||
end | |||
elseif datavalue.type == 'globecoordinate' then | |||
ret = formatGlobecoordinate(datavalue.value, args) | |||
elseif datavalue.type == 'quantity' then | |||
ret = formatQuantity(datavalue.value, args) | |||
else | else | ||
error(i18n.errors['unknown-datavalue-type']) | |||
end | end | ||
return ret | |||
end | end | ||
local function | local function formatSnak(snak, args) | ||
if | if snak.snaktype == 'somevalue' then | ||
return | return i18n['somevalue'] | ||
elseif snak.snaktype == 'novalue' then | |||
return i18n['novalue'] | |||
elseif snak.snaktype == 'value' then | |||
return formatDatavalue(snak.datavalue, snak.datatype, args) | |||
else | else | ||
error(i18n.errors['unknown-snak-type']) | |||
end | end | ||
end | end | ||
local function | -- È al plurale perché anche i qualifier possono avere più di un valore | ||
-- (si ottiene inserendo due volte lo stesso qualifier) | |||
local function formatQualifiers(claim, qualifierId, args, rawTable, retTable) | |||
local formattedQualifiers = retTable or {} | |||
if claim.qualifiers and claim.qualifiers[qualifierId] then | |||
if | local qualifiers = claim.qualifiers[qualifierId] | ||
-- con args.nq seleziona solo l'n-esimo qualifier | |||
if args.nq then | |||
local n = tonumber(args.nq) | |||
qualifiers = (n and n <= #qualifiers) and { qualifiers[n] } or {} | |||
end | end | ||
-- qualifier filtrati per snaktype, default "value" | |||
args.snaktype = args.snaktype or 'value' | |||
for _, qualifier in ipairs(qualifiers) do | |||
if qualifier.snaktype == args.snaktype or args.snaktype == 'all' then | |||
local formattedQualifier = formatSnak(qualifier, args) | |||
if formattedQualifier ~= '' then | |||
if args.pattern then | |||
formattedQualifier = formatFromPattern(formattedQualifier, args) | |||
if formattedQualifier ~= '' then | |||
table.insert(formattedQualifiers, formattedQualifier) | |||
if | |||
if | |||
if | |||
end | end | ||
else | |||
table.insert(formattedQualifiers, formattedQualifier) | |||
end | end | ||
end | end | ||
Riga 320: | Riga 342: | ||
end | end | ||
end | end | ||
if rawTable then | |||
if | return formattedQualifiers | ||
return | |||
end | end | ||
return #formattedQualifiers > 0 and | |||
return | mw.text.listToText(formattedQualifiers, args.separator, args.conjunction) or nil | ||
end | end | ||
local function | local function appendQualifiers(statement, text, args) | ||
local | local formattedQualifiers = {} | ||
if | local qualifierIds = mw.text.split(args.showqualifiers, ',') | ||
for _, qualifierId in ipairs(qualifierIds) do | |||
if statement.qualifiers[qualifierId] then | |||
local formattedQualifier = formatQualifiers(statement, qualifierId, args) | |||
table.insert(formattedQualifiers, formattedQualifier) | |||
end | |||
end | end | ||
if #formattedQualifiers > 0 then | |||
text = string.format('%s (%s)', text, mw.text.listToText(formattedQualifiers, ', ', ', ')) | |||
end | end | ||
return | return text | ||
end | end | ||
local function | local function formatStatement(statement, args) | ||
if not statement.type or statement.type ~= 'statement' then | |||
if type | error(i18n.errors['unknown-claim-type']) | ||
end | end | ||
if | |||
local ret = formatSnak(statement.mainsnak, args) | |||
-- eventuale showqualifiers | |||
if args.showqualifiers and statement.qualifiers then | |||
ret = appendQualifiers(statement, ret, args) | |||
end | end | ||
return | |||
return ret | |||
end | end | ||
local function | local function formatStatements(claims, args, rawTable) | ||
local formattedStatements = {} | |||
if | |||
if | for _, claim in ipairs(claims) do | ||
local formattedStatement = formatStatement(claim, args) | |||
if formattedStatement ~= '' then | |||
-- eventuale pattern | |||
if args.pattern then | |||
formattedStatement = formatFromPattern(formattedStatement, args) | |||
if formattedStatement ~= '' then | |||
table.insert(formattedStatements, formattedStatement) | |||
end | |||
else | else | ||
table.insert(formattedStatements, formattedStatement) | |||
end | end | ||
end | end | ||
end | |||
if rawTable then | |||
return formattedStatements | |||
end | |||
return ((args.list or args.orderedlist) and #formattedStatements > 1) and | |||
formatList(formattedStatements, args.orderedlist ~= nil) or | |||
mw.text.listToText(formattedStatements, args.separator, args.conjunction) | |||
end | |||
------------------------------------------------------------------------------- | |||
-- Lettura e selezione statement | |||
------------------------------------------------------------------------------- | |||
-- Restituisce true se lo statement contiene il qualifier richiesto con un dato valore (o uno tra più valori separati da virgola) | |||
local function hasQualifierValue(statement, qualifierId, qualifierValue) | |||
local ret = false | |||
if | for _, qualifier in ipairs(statement.qualifiers[qualifierId]) do | ||
local isItem = qualifier.snaktype == 'value' and | |||
qualifier.datavalue.type == 'wikibase-entityid' | |||
local qualifierValues = mw.text.split(qualifierValue, ',') | |||
for _, qualifierHas in ipairs(qualifierValues) do | |||
-- per le proprietà di tipo item il confronto è eseguito sull'id | |||
if formatSnak(qualifier, isItem and { formatting = 'raw' } or {}) == qualifierHas then | |||
ret = true | |||
break | |||
end | end | ||
end | end | ||
end | end | ||
return | return ret | ||
end | end | ||
function | -- Restituisce i claim con il rank richiesto | ||
local function filterRankValue(claims, rank) | |||
local ret = {} | |||
for _, claim in ipairs(claims) do | |||
if | if claim.rank == rank then | ||
table.insert(ret, claim) | |||
end | end | ||
end | end | ||
return | return ret | ||
end | end | ||
-- Restituisce una sequence Lua contenente gli statement per la property richiesta, | |||
-- anche vuota se la proprietà non esiste, o non ci sono valori che soddisfano i criteri | |||
-- ("rank", "qualifier", "qualifiertype", "noqualifier", ...). | |||
-- Restituisce nil solo se la pagina non è collegata a un elemento Wikidata e non è indicato il from. | |||
local function getClaims(propertyId, args) | |||
if not | local entityId, claims, filteredClaims | ||
entityId = args.from or mw.wikibase.getEntityIdForCurrentPage() | |||
if not entityId then | |||
return nil | return nil | ||
end | end | ||
if | -- il default rank è 'best' | ||
args.rank = args.rank or 'best' | |||
if args.rank == 'best' then | |||
claims = mw.wikibase.getBestStatements(entityId, propertyId) | |||
else | else | ||
-- statements filtrati per rank | |||
claims = mw.wikibase.getAllStatements(entityId, propertyId) | |||
claims = filterRankValue(claims, args.rank) | |||
end | end | ||
-- statements filtrati per snaktype, default "value" | |||
args.snaktype = args.snaktype or 'value' | |||
if args.snaktype and args.snaktype ~= 'all' then | |||
filteredClaims = {} | |||
for _, claim in ipairs(claims) do | |||
if claim.mainsnak.snaktype == args.snaktype then | |||
table.insert(filteredClaims, claim) | |||
end | |||
end | |||
claims = filteredClaims | |||
end | end | ||
if | -- statements filtrati per qualifier | ||
if args.qualifier then | |||
filteredClaims = {} | |||
for _, claim in ipairs(claims) do | |||
if claim.qualifiers and claim.qualifiers[args.qualifier] then | |||
if args.qualifiervalue then | |||
if hasQualifierValue(claim, args.qualifier, args.qualifiervalue) then | |||
table.insert(filteredClaims, claim) | |||
end | |||
else | |||
table.insert(filteredClaims, claim) | |||
end | end | ||
end | end | ||
end | end | ||
claims = filteredClaims | |||
end | |||
-- statements filtrati per essere senza un qualifier | |||
if args.noqualifier then | |||
filteredClaims = {} | |||
for _, claim in ipairs(claims) do | |||
if not (claim.qualifiers and claim.qualifiers[args.noqualifier]) then | |||
table.insert(filteredClaims, claim) | |||
end | |||
end | end | ||
claims = filteredClaims | |||
end | |||
-- statements filtrati per non avere un certo valore a un certo qualifier opzionale | |||
if args.qualifieroptnovalue and args.qualifiervalue then | |||
filteredClaims = {} | |||
for _, claim in ipairs(claims) do | |||
if claim.qualifiers and claim.qualifiers[args.qualifieroptnovalue] then | |||
if not hasQualifierValue(claim, args.qualifieroptnovalue, args.qualifiervalue) then | |||
table.insert(filteredClaims, claim) | |||
end | |||
else | |||
table.insert(filteredClaims, claim) | |||
end | end | ||
end | end | ||
claims = filteredClaims | |||
end | end | ||
-- con args.qualifiertype=latest restituisce solo il più recente | |||
if args.qualifier and args.qualifiertype == 'latest' then | |||
local latest, latestTime | |||
for _, claim in ipairs(claims) do | |||
if claim.qualifiers and claim.qualifiers[args.qualifier] then | |||
for _, qualifier in ipairs(claim.qualifiers[args.qualifier]) do | |||
if qualifier.datavalue.type == 'time' then | |||
if not latestTime or qualifier.datavalue.value.time > latestTime then | |||
latest = claim | |||
latestTime = qualifier.datavalue.value.time | |||
end | |||
end | |||
end | |||
end | end | ||
end | end | ||
claims = latest and { latest } or {} | |||
end | end | ||
-- con args.n restituisce solo l'n-esimo elemento | |||
if args.n then | |||
local n = tonumber(args.n) | |||
claims = (n and n <= #claims) and { claims[n] } or {} | |||
( | |||
end | end | ||
return claims | return claims | ||
end | end | ||
function p. | ------------------------------------------------------------------------------- | ||
-- Funzioni esportate per altri moduli | |||
------------------------------------------------------------------------------- | |||
function p._getClaims(propertyId, args) | |||
return getClaims(propertyId, args or {}) | |||
end | end | ||
function p. | function p._formatStatement(statement, args) | ||
return formatStatement(statement, args or {}) | |||
return | |||
end | end | ||
function p._formatQualifiers(claim, qualifierId, args, rawTable, retTable) | |||
return formatQualifiers(claim, qualifierId, args or {}, rawTable, retTable) | |||
end | end | ||
function p. | -- Restituisce il valore di una proprietà di Wikidata oppure nil se l'entity o | ||
-- la proprietà non esistono, o se per parametri di selezione gli statement sono zero. | |||
function p._getProperty(args, rawTable) | |||
if not | local propertyId, value, claims, ret | ||
-- parametri posizionali | |||
propertyId = args[1] and string.upper(args[1]) | |||
if not propertyId then | |||
error(i18n.errors['property-param-not-provided'], 2) | |||
end | end | ||
value = args[2] | |||
-- fix uppercase | |||
args.qualifier = args.qualifier and string.upper(args.qualifier) | |||
if value then | |||
ret = formatUserValue(value, args) | |||
elseif args.wd ~= 'no' then | |||
claims = getClaims(propertyId, args) | |||
ret = (claims and #claims > 0) and formatStatements(claims, args, rawTable) or nil | |||
end | end | ||
return | |||
return ret | |||
end | end | ||
function p. | -- Restituisce il valore di un qualifier di una proprietà di Wikidata, | ||
if not | -- o nil se l'entity o la proprietà non esistono, o se per parametri di selezione non ci sono risultati. | ||
function p._getQualifier(args) | |||
local propertyId, qualifierId, value, claims, ret | |||
-- parametri posizionali | |||
propertyId = args[1] and string.upper(args[1]) | |||
if not propertyId then | |||
error(i18n.errors['property-param-not-provided'], 2) | |||
end | end | ||
qualifierId = args[2] and string.upper(args[2]) | |||
if not qualifierId then | |||
error(i18n.errors['qualifier-param-not-provided'], 2) | |||
if | |||
end | end | ||
value = args[3] | |||
if value then | |||
if | ret = formatUserValue(value, args) | ||
elseif args.wd ~= 'no' then | |||
claims = getClaims(propertyId, args) | |||
if claims and #claims > 0 then | |||
local formattedQualifiers = {} | |||
if | for _, claim in ipairs(claims) do | ||
formattedQualifiers = formatQualifiers(claim, qualifierId, args, true, formattedQualifiers) | |||
end | end | ||
ret = #formattedQualifiers > 0 and | |||
mw.text.listToText(formattedQualifiers, args.separator, args.conjunction) or nil | |||
end | end | ||
end | end | ||
return ret | |||
end | |||
-- Restituisce l'indice dello statement con il valore richiesto, o nil se non trovato. | |||
function p._indexOf(args) | |||
local ret, propertyId, value, claims | |||
-- parametri posizionali | |||
propertyId = args[1] and string.upper(args[1]) | |||
if not propertyId then | |||
error(i18n.errors['property-param-not-provided'], 2) | |||
end | |||
value = args[2] | |||
if not value then | |||
error(i18n.errors['value-param-not-provided'], 2) | |||
end | end | ||
if | claims = getClaims(propertyId, args) | ||
if claims and #claims > 0 then | |||
args.formatting = 'raw' | |||
for i, claim in ipairs(claims) do | |||
if formatStatement(claim, args) == value then | |||
for | ret = i | ||
if | break | ||
end | end | ||
end | end | ||
end | end | ||
return | |||
return ret | |||
end | end | ||
function p. | -- Restituisce il numero di statement di una proprietà di Wikidata. | ||
function p._N(args) | |||
local propertyId, claims | |||
-- parametri posizionali | |||
-- | propertyId = args[1] and string.upper(args[1]) | ||
if not propertyId then | |||
error(i18n.errors['property-param-not-provided'], 2) | |||
end | end | ||
-- get claims | |||
claims = getClaims(propertyId, args) | |||
return claims and #claims or 0 | |||
end | end | ||
function p. | -- Restituisce true se la propriertà specificata ha come valore | ||
-- almeno uno tra gli entityId passati come argomento. | |||
function p._propertyHasEntity(propertyId, args) | |||
local statements = p._getProperty({ propertyId, from = args.from, formatting = 'raw' }, true) | |||
if statements then | |||
for _, statement in ipairs(statements) do | |||
for _, entityId in ipairs(args) do | |||
if statement == entityId then | |||
return true | |||
if | |||
return | |||
end | end | ||
end | end | ||
end | end | ||
-- Se non è stato trovato alcun valore, controlla se questo sia ereditato | |||
-- tramite la proprietà "sottoclasse di" (P279) scavando in profondità | |||
-- fino all'esaurirsi del numero specificato in args.recursion. | |||
--[[ TODO: Valutare se sia opportuna una ricerca ricorsiva potenzialmente infinita. | |||
Per farlo si può aggiungere un parametro (opzionale) maxDepth | |||
che svolga l'attuale funzione di recursion e cambiare quest'ultimo | |||
in un parametro booleano. | |||
]] | |||
args.recursion = tonumber(args.recursion) or 0 | |||
if args.recursion > 0 then | |||
local recursion = args.recursion | |||
if type(args.loadedEntities) ~= 'table' then | |||
args.loadedEntities = setmetatable({}, { | |||
__newindex = function(t, k, v) | |||
rawset(t, k, v) | |||
rawset(t, #t+1, k) | |||
end }) | |||
args.loadedEntities[args.from or mw.wikibase.getEntityIdForCurrentPage()] = true | |||
end | |||
for _, statement in ipairs(statements) do | |||
if not args.loadedEntities[statement] then | |||
args.loadedEntities[statement] = true | |||
args.recursion = args.recursion - 1 | |||
args.from = statement | |||
if p._propertyHasEntity('P279', args) then | |||
return true, args.loadedEntities | |||
end | end | ||
args.recursion = recursion | |||
end | end | ||
end | end | ||
end | end | ||
end | end | ||
return | |||
return false, args.loadedEntities | |||
end | |||
-- Restituisce true se la proprietà P31 (instance of) ha come valore almeno uno tra gli entityId specificati | |||
function p._instanceOf(args) | |||
return p._propertyHasEntity('P31', args) | |||
end | end | ||
-- Restituisce true se la proprietà P279 (subclass of) ha come valore almeno uno tra gli entityId specificati | |||
function p._subclassOf(args) | |||
return p._propertyHasEntity('P279', args) | |||
end | |||
if | -- Restituisce l'etichetta di un item o di una proprietà Wikidata. | ||
function p._getLabel(args) | |||
local entityId = args[1] and string.upper(args[1]) | |||
local ret | |||
if args[2] then | |||
ret = mw.wikibase.getLabelByLang(entityId, args[2]) | |||
else | else | ||
ret = mw.wikibase.getLabel(entityId) | |||
end | end | ||
return ret | |||
end | |||
-- Restituisce la descrizione di un item o di una proprietà Wikidata. | |||
function p._getDescription(args) | |||
local entityId = args[1] and string.upper(args[1]) | |||
local ret = mw.wikibase.getDescription(entityId) | |||
return ret | |||
end | end | ||
function p. | -- Restituisce il titolo della pagina collegata a un dato item Wikidata. | ||
if not | function p._getLink(args) | ||
-- parametri posizionali | |||
local entityId = args[1] and string.upper(args[1]) | |||
if not entityId then | |||
error(i18n.errors['entityid-param-not-provided'], 2) | |||
end | end | ||
if not | |||
return entityId:sub(1, 1) == 'Q' and formatEntityId(entityId) or nil | |||
end | |||
-- Restituisce il datatype di una proprietà Wikidata. | |||
function p._getDatatype(args) | |||
local propertyId, entity | |||
-- parametri posizionali | |||
propertyId = args[1] and string.upper(args[1]) | |||
if not propertyId then | |||
error(i18n.errors['property-param-not-provided'], 2) | |||
end | end | ||
entity = mw.wikibase.getEntity(propertyId) | |||
if not entity then | if not entity then | ||
error(i18n.errors['entity-not-found'], 2) | |||
end | end | ||
if | if not i18n.datatypes[entity.datatype] then | ||
error(i18n.errors['unknown-datavalue-type'], 2) | |||
end | end | ||
return i18n.datatypes[entity.datatype] | |||
end | |||
-- Restituisce l'ID dell'item Wikidata collegato alla pagina corrente o a una pagina specificata | |||
-- (nota: segue i redirect fermandosi al primo redirect collegato a un elemento) | |||
function p._getId(args) | |||
local ret | |||
if args[1] then | |||
local title = mw.title.new(args[1]) | |||
while title do | |||
local id = mw.wikibase.getEntityIdForTitle(title.prefixedText) | |||
if id then | |||
ret = id | |||
break | |||
else | |||
title = title.redirectTarget | |||
end | |||
end | end | ||
else | else | ||
ret = mw.wikibase.getEntityIdForCurrentPage() | |||
end | end | ||
return ret | |||
end | end | ||
------------------------------------------------------------------------------- | |||
-- Funzioni esportate per i template | |||
------------------------------------------------------------------------------- | |||
-- Funzione per il template {{Wikidata}} | |||
function p.getProperty(frame) | |||
return | return select(2, xpcall(function() | ||
return p._getProperty(getArgs(frame, { parentOnly = true })) | |||
end, errhandler)) | |||
end | end | ||
function p. | -- Funzione per il template {{WikidataQ}} | ||
function p.getQualifier(frame) | |||
return select(2, xpcall(function() | |||
return p._getQualifier(getArgs(frame, { parentOnly = true })) | |||
end, errhandler)) | |||
return | |||
end | |||
end | end | ||
function p. | -- Funzione per il template {{WikidataIdx}} | ||
function p.indexOf(frame) | |||
return select(2, xpcall(function() | |||
return | return p._indexOf(getArgs(frame, { parentOnly = true })) | ||
end | end, errhandler)) | ||
end | end | ||
function p. | -- Funzione per il template {{WikidataN}} | ||
function p.N(frame) | |||
return select(2, xpcall(function() | |||
return p._N(getArgs(frame, { parentOnly = true })) | |||
end, errhandler)) | |||
end | |||
end | end | ||
-- | |||
function p. | -- Funzione per il template {{WikidataLabel}} | ||
return p. | function p.getLabel(frame) | ||
return select(2, xpcall(function() | |||
return p._getLabel(getArgs(frame, { parentOnly = true })) | |||
end, errhandler)) | |||
end | end | ||
function p. | -- Funzione per il template {{WikidataDescription}} | ||
return p. | function p.getDescription(frame) | ||
return select(2, xpcall(function() | |||
return p._getDescription(getArgs(frame, { parentOnly = true })) | |||
end, errhandler)) | |||
end | end | ||
-- Funzione per il template {{WikidataLink}} | |||
function p.getLink(frame) | |||
return select(2, xpcall(function() | |||
return p._getLink(getArgs(frame, { parentOnly = true })) | |||
end, errhandler)) | |||
end | end | ||
function p. | -- Funzione per il template {{WikidataIstanza}} | ||
return p. | function p.instanceOf(frame) | ||
return select(2, xpcall(function() | |||
return p._instanceOf(getArgs(frame, { parentOnly = true })) and 1 or '' | |||
end, errhandler)) | |||
end | end | ||
function p. | -- Funzione per il template {{WikidataTipo}} | ||
function p.getDatatype(frame) | |||
return select(2, xpcall(function() | |||
return p._getDatatype(getArgs(frame, { parentOnly = true })) | |||
end, errhandler)) | |||
end | |||
end | end | ||
function p. | -- Funzione per il template {{WikidataId}} | ||
function p.getId(frame) | |||
return select(2, xpcall(function() | |||
return p._getId(getArgs(frame, { parentOnly = true })) | |||
end, errhandler)) | |||
end | |||
end | end | ||
function p. | -- Funzione per il template {{WikidataValido}} | ||
return p. | function p.checkProperty(frame) | ||
return select(2, xpcall(function() | |||
return p._N(getArgs(frame, { parentOnly = true })) > 0 and 1 or '' | |||
end, errhandler)) | |||
end | end | ||
-- | -- Funzione per il template {{WikidataClasse}} | ||
function p.propertyHasEntity(frame) | |||
function p. | local args = getArgs(frame, { parentOnly = true }) | ||
local propertyId = args[1] | |||
args.recursion = tonumber(args.prof) or 8 | |||
return select(2, xpcall(function() | |||
return p._propertyHasEntity(propertyId, args) and 1 or '' | |||
end, errhandler)) | |||
end | end | ||
return p | return p |