Modulo:Wikidata: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
m commento non aggiornato |
m inverto logica del parametro per retrocompatibilità |
||
(40 versioni intermedie di 7 utenti non mostrate) | |||
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}}.
Riga 9:
]]
-- =============================================================================
-- 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('strict')
local getArgs = require('Module:Arguments').getArgs
local mConvert = require('Module:Conversione')
local mLanguages = require('Module:
-- Categoria per le pagine con errori
local errorCategory = '[[Categoria:Voci con errori del modulo Wikidata]]'
-- Messaggi
local i18n = {
[
[
[
[
[
[
[
[
[
['unknown-output-format'] = 'Formato di output sconosciuto'
},
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 p = {}
-------------------------------------------------------------------------------
Riga 57 ⟶ 80:
if success and uri.protocol and protocols[uri.protocol] then
local dest = tostring(uri)
return string.format('<
else
return url
Riga 64 ⟶ 87:
local function formatEntityId(entityId)
local label = mw.wikibase.
local
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
end
return ret
end
Riga 83 ⟶ 112:
ret = value.text
if args.showlang then
ret = mLanguages.lingue(
end
end
Riga 143 ⟶ 172:
ret = value.globe
else
ret =
end
return ret
Riga 175 ⟶ 204:
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
local space = ret == '°' and '' or ' '
if ret and args.showunitlink then
local link = mw.wikibase.
if link then
ret = string.format('[[%s|%s]]', link, ret)
Riga 203 ⟶ 240:
showunitlink = args.showunitlink,
formatnum = args.formatnum,
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
ret = args.rounding and round(ret, args.rounding) or ret
if args.formatnum then
Riga 222 ⟶ 259:
ret = mConvert._main(ret, unitId, 'second')
ret = ret and mw.language.getContentLanguage()
:formatDuration(tonumber(ret), { 'days', 'hours', 'minutes', 'seconds' }
end
Riga 234 ⟶ 271:
local entityId = getEntityIdFromValue(datavalue.value)
if args.showprop then
ret = p._getProperty(
elseif args.formatting then
local formatting = args.formatting:lower()
ret = (formatting == 'raw' or formatting == 'id') and entityId or
formatting == 'label' and mw.wikibase.getLabel(entityId) or
formatting == 'title' and (mw.wikibase.getSitelink(entityId) or '') or
error(i18n.errors['unknown-output-format'])
else
ret =
end
elseif datavalue.type == 'string' then
Riga 278 ⟶ 321:
-- È al plurale perché anche i qualifier possono avere più di un valore
-- (si ottiene inserendo due volte lo stesso qualifier)
local function formatQualifiers(claim,
local formattedQualifiers = retTable or {}
if claim.qualifiers and claim.qualifiers[
local qualifiers = claim.qualifiers[
-- con args.nq seleziona solo l'n-esimo qualifier
if args.nq then
Riga 288 ⟶ 331:
qualifiers = (n and n <= #qualifiers) and { qualifiers[n] } or {}
end
-- qualifier filtrati per snaktype, default "value"
args.snaktype = args.snaktype or 'value'
for _, qualifier in ipairs(qualifiers) do
if formattedQualifier ~= '' then
if args.pattern then
formattedQualifier = formatFromPattern(formattedQualifier, args)
if formattedQualifier ~= '' then
table.insert(formattedQualifiers, formattedQualifier)
end
else
table.insert(formattedQualifiers, formattedQualifier)
end
end
end
end
Riga 309 ⟶ 360:
local function appendQualifiers(statement, text, args)
local formattedQualifiers = {}
local
for _,
if statement.qualifiers[
local formattedQualifier = formatQualifiers(statement,
table.insert(formattedQualifiers, formattedQualifier)
end
Riga 339 ⟶ 390:
local formattedStatements = {}
for
local formattedStatement = formatStatement(claim, args)
if formattedStatement ~= '' then
Riga 345 ⟶ 396:
if args.pattern then
formattedStatement = formatFromPattern(formattedStatement, args)
if formattedStatement ~= '' then
table.insert(formattedStatements, formattedStatement)
end
else
table.insert(formattedStatements, formattedStatement)
end
end
end
Riga 362 ⟶ 417:
-------------------------------------------------------------------------------
--
local function hasQualifierValue(statement, qualifierId, qualifierValue)
local ret = false
for
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
Riga 377 ⟶ 435:
end
--
local function filterRankValue(claims, rank)
local ret = {}
for
if claim.rank == rank then
table.insert(ret, claim)
Riga 388 ⟶ 446:
end
--
--
-- ("rank", "qualifier", "qualifiertype", "noqualifier", ...).
-- Restituisce nil solo se la pagina non è collegata a un elemento Wikidata e non è indicato il from.
local function getClaims(
local
entityId = args.from or mw.wikibase.getEntityIdForCurrentPage()
if not entityId then
return nil
end
-- il default rank è 'best'
args.rank = args.rank or 'best'
if args.rank == 'best' then
claims = mw.wikibase.getBestStatements(entityId, propertyId)
else
-- statements filtrati per rank
claims = mw.wikibase.getAllStatements(entityId, propertyId)
claims = filterRankValue(claims, args.rank)
end
-- statements filtrati per
args.
if args.
filteredClaims =
for _, claim in ipairs(claims) do
if claim.mainsnak.snaktype == args.snaktype then
table.insert(filteredClaims, claim)
end
end
claims = filteredClaims
end
-- statements filtrati per qualifier
if args.qualifier then
filteredClaims = {}
for
if claim.qualifiers and claim.qualifiers[args.qualifier] then
if args.qualifiervalue then
Riga 440 ⟶ 500:
if args.noqualifier then
filteredClaims = {}
for
if not (claim.qualifiers and claim.qualifiers[args.noqualifier]) then
table.insert(filteredClaims, claim)
Riga 451 ⟶ 511:
if args.qualifieroptnovalue and args.qualifiervalue then
filteredClaims = {}
for
if claim.qualifiers and claim.qualifiers[args.qualifieroptnovalue] then
if not hasQualifierValue(claim, args.qualifieroptnovalue, args.qualifiervalue) then
Riga 463 ⟶ 523:
end
-- con args.qualifiertype=latest
if args.qualifier and args.qualifiertype == 'latest' then
local latest, latestTime
for
if claim.qualifiers and claim.qualifiers[args.qualifier] then
for
if qualifier.datavalue.type == 'time' then
if not latestTime or qualifier.datavalue.value.time > latestTime then
Riga 478 ⟶ 538:
end
end
claims = latest and { latest } or {}
end
-- con args.n
if args.n then
local n = tonumber(args.n)
Riga 491 ⟶ 551:
-------------------------------------------------------------------------------
-- Funzioni esportate per altri
-------------------------------------------------------------------------------
function p._getClaims(
return getClaims(
end
Riga 502 ⟶ 562:
end
function p._formatQualifiers(claim,
return formatQualifiers(claim,
end
--
-- la proprietà non esistono, o se per parametri di selezione gli statement sono zero.
function p._getProperty(args, rawTable)
local
-- parametri posizionali
if not
error(i18n.errors['property-param-not-provided'], 2)
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(
ret = (claims and #claims > 0) and formatStatements(claims, args, rawTable) or nil
end
Riga 530 ⟶ 590:
end
--
-- 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
-- parametri posizionali
if not
error(i18n.errors['property-param-not-provided'], 2)
end
if not
error(i18n.errors['qualifier-param-not-provided'], 2)
end
Riga 549 ⟶ 609:
ret = formatUserValue(value, args)
elseif args.wd ~= 'no' then
claims = getClaims(
if claims and #claims > 0 then
local formattedQualifiers = {}
for _, claim in
formattedQualifiers = formatQualifiers(claim,
end
ret = #formattedQualifiers > 0 and
Riga 563 ⟶ 623:
end
--
function p._indexOf(args)
local ret,
-- parametri posizionali
if not
error(i18n.errors['property-param-not-provided'], 2)
end
Riga 577 ⟶ 637:
end
claims = getClaims(
if claims and #claims > 0 then
args.formatting = 'raw'
for i, claim in
if formatStatement(claim, args) == value then
ret = i
Riga 591 ⟶ 651:
end
--
function p._N(args)
local
-- parametri posizionali
if not
error(i18n.errors['property-param-not-provided'], 2)
end
-- get claims
claims = getClaims(
return claims and #claims or 0
end
--
-- 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
Riga 614 ⟶ 675:
if statement == entityId then
return true
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
args.recursion = recursion
end
end
Riga 619 ⟶ 712:
end
return false, args.loadedEntities
end
-- Restituisce true se la proprietà P31 (instance of) ha come valore almeno uno tra gli entityId specificati
function p.
return p._propertyHasEntity('P31', args)
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
-- 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
ret = mw.wikibase.getLabel(entityId)
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
--
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)
Riga 647 ⟶ 755:
end
--
function p._getDatatype(args)
local
-- parametri posizionali
if not
error(i18n.errors['property-param-not-provided'], 2)
end
entity = mw.wikibase.getEntity(
if not entity then
error(i18n.errors['entity-not-found'], 2)
end
error(i18n.errors['unknown-datavalue-type'], 2)
end
return
end
--
-- (nota: se il parametro followRedirects è valorizzato con "no", segue i redirect fermandosi al primo redirect collegato a un elemento)
function p._getId(args)
local ret
local followRedirects = not args.followRedirects or args.followRedirects ~= "no"
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 = followRedirects and title.redirectTarget or nil
end
end
else
ret = mw.wikibase.getEntityIdForCurrentPage()
end
return ret
end
-------------------------------------------------------------------------------
-- Funzioni esportate per i template
-------------------------------------------------------------------------------
-- Funzione per il template {{Wikidata}}
function p.getProperty(frame)
return select(2, xpcall(function()
return p._getProperty(getArgs(frame, { parentOnly = true }))
end, errhandler))
end
--
function p.getQualifier(frame)
return select(2, xpcall(function()
return p._getQualifier(getArgs(frame, { parentOnly = true }))
end, errhandler))
end
--
function p.indexOf(frame)
return select(2, xpcall(function()
return p._indexOf(getArgs(frame, { parentOnly = true }))
end, errhandler))
end
--
function p.N(frame)
return select(2, xpcall(function()
return p._N(getArgs(frame, { parentOnly = true }))
end, errhandler))
end
--
function p.getLabel(frame)
return select(2, xpcall(function()
return p._getLabel(getArgs(frame, { parentOnly = true }))
end, errhandler))
end
--
function p.getDescription(frame)
return select(2, xpcall(function()
return p._getDescription(getArgs(frame, { parentOnly = true }))
end, errhandler))
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
--
function p.instanceOf(frame)
return select(2, xpcall(function()
return p._instanceOf(getArgs(frame, { parentOnly = true })) and 1 or ''
end, errhandler))
end
--
function p.getDatatype(frame)
return select(2, xpcall(function()
return p._getDatatype(getArgs(frame, { parentOnly = true }))
end, errhandler))
end
--
function p.getId(frame)
return select(2, xpcall(function()
return p._getId(getArgs(frame, { parentOnly = true }))
end, errhandler))
end
-- Funzione per il template {{WikidataValido}}
function p.checkProperty(frame)
return select(2, xpcall(function()
return p._N(getArgs(frame, { parentOnly = true })) > 0 and 1 or ''
end, errhandler))
end
-- Funzione per il template {{WikidataClasse}}
function p.propertyHasEntity(frame)
local args = getArgs(frame)
local propertyId = args[1]
return select(2, xpcall(function()
return p._propertyHasEntity(propertyId, args) and 1 or ''
end, errhandler))
end
|