Modulo:Wikidata/sandbox: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
m fix apice
Nessun oggetto della modifica
 
(47 versioni intermedie di 4 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:
]]
 
-- =============================================================================
require('Module:No globals')
-- 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:LinguaggiLingue')
local mCitation = require('Module:Citazione')
 
-- Categoria per le pagine con errori
Line 35 ⟶ 43:
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',
['external-id'] = 'identificativo esterno',
['wikibase-item'] = 'elemento',
['wikibase-property'] = 'proprietà',
['math'] = 'espressione matematica'
}
}
Line 70 ⟶ 80:
if success and uri.protocol and protocols[uri.protocol] then
local dest = tostring(uri)
return string.format('<divspan style="word-break: break-all;">[%s %s]</divspan>', dest, dest:gsub(uri.protocol .. '://', ''))
else
return url
Line 77 ⟶ 87:
 
local function formatEntityId(entityId)
local label = mw.wikibase.labelgetLabel(entityId)
local linksiteLink = mw.wikibase.sitelinkgetSitelink(entityId)
local ret
if entityId == mw.wikibase.getEntityIdForCurrentPage() then
if link then
ret = (label and label ~= link) andsiteLink
elseif siteLink and label then
string.format('[[%s|%s]]', link, label) or
ret = mw.getContentLanguage():ucfirst(label) == siteLink and
string.format('[[%s]]', link)
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 = label or ''
end
return ret
Line 161 ⟶ 177:
end
 
local function formatFromPattern(str, args, refs)
local pattern = args.pattern
pattern = mw.ustring.gsub(pattern, '\\{', '{')
pattern = mw.ustring.gsub(pattern, '\\}', '}')
return mw.getCurrentFrame():preprocess(mw.message.newRawMessage(pattern, str, refs or ''):plain())
end
 
Line 188 ⟶ 204:
 
local function formatUnitSymbol(entityId, args)
local ret
local ret = p._getProperty({ 'P558', n = 1, from = entityId })
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.sitelinkgetSitelink(entityId)
if link then
ret = string.format('[[%s|%s]]', link, ret)
Line 221 ⟶ 245:
else
-- se è richiesto solo il simbolo dell'unità
-- senza la conversione lo ottiene da P558P5061
ret = args.rounding and round(ret, args.rounding) or ret
if args.formatnum then
Line 291 ⟶ 315:
-- È al plurale perché anche i qualifier possono avere più di un valore
-- (si ottiene inserendo due volte lo stesso qualifier)
local function formatQualifiers(claim, qualifierqualifierId, args, rawTable, retTable)
local formattedQualifiers = retTable or {}
 
if claim.qualifiers and claim.qualifiers[qualifierqualifierId] then
local qualifiers = claim.qualifiers[qualifierqualifierId]
-- con args.nq seleziona solo l'n-esimo qualifier
if args.nq then
Line 301 ⟶ 325:
qualifiers = (n and n <= #qualifiers) and { qualifiers[n] } or {}
end
-- qualifier filtrati per snaktype, default "value"
for _, q in pairs(qualifiers) do
args.snaktype = args.snaktype or 'value'
local formattedQualifier = formatSnak(q, args)
for _, qualifier in ipairs(qualifiers) do
if formattedQualifier ~= '' then
if qualifier.snaktype == args.patternsnaktype or args.snaktype == 'all' then
local formattedQualifier = formatFromPatternformatSnak(formattedQualifierqualifier, args)
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
else
table.insert(formattedQualifiers, formattedQualifier)
end
end
Line 326 ⟶ 354:
local function appendQualifiers(statement, text, args)
local formattedQualifiers = {}
local qualifiersqualifierIds = mw.text.split(args.showqualifiers, ',')
for _, qualifierqualifierId in ipairs(qualifiersqualifierIds) do
if statement.qualifiers[qualifierqualifierId] then
local formattedQualifier = formatQualifiers(statement, qualifierqualifierId, args)
table.insert(formattedQualifiers, formattedQualifier)
end
Line 337 ⟶ 365:
end
return text
end
 
local function formatReferences(references, args)
local formattedReferences = {}
local refArgs = {}
local parameters = {
titolo = 'P1476', data = 'P577', url = 'P854', dataaccesso = 'P813',
editore = 'P123', urlarchivio = 'P1065', dataarchivio = 'P2960'
}
if references[1].snaks.P854 then
local snaks = references[1].snaks
for parameter, property in pairs(parameters) do
if snaks[property] then
refArgs[parameter] = formatSnak(snaks[property][1], args)
end
end
refArgs.titolo = refArgs.titolo or refArgs.url
if snaks.P407 then
local langs = {}
for _, value in ipairs(snaks.P407) do
local lang = formatSnak(value, { formatting = 'raw' })
table.insert(langs, mw.wikibase.getLabel(lang) or lang)
end
refArgs.lingua = table.concat(langs, ',')
end
if refArgs.urlarchivio then refArgs.urlmorto = 'sì' end
local formattedReference = mw.getCurrentFrame():extensionTag{
name = 'ref',
content = mCitation.cita_da_modulo('web', refArgs),
args = { name = references[1].hash }
}
table.insert(formattedReferences, formattedReference)
end
return table.concat(formattedReferences)
end
 
Line 356 ⟶ 418:
local formattedStatements = {}
 
for i_, claim in pairsipairs(claims) do
local formattedStatement = formatStatement(claim, args)
if formattedStatement ~= '' then
local formattedReferences
if args.showreferences and claim.references then
formattedReferences = formatReferences(claim.references, args)
end
-- eventuale pattern
if args.pattern then
formattedStatement = formatFromPattern(formattedStatement, args, formattedReferences)
ifelseif formattedStatement ~= ''formattedReferences then
table.insert(formattedStatements,formattedStatement = formattedStatement) .. formattedReferences
end
if formattedStatement ~= '' then
else
table.insert(formattedStatements, formattedStatement)
end
Line 383 ⟶ 449:
-------------------------------------------------------------------------------
 
-- 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
for i_, qualifier in pairsipairs(statement.qualifiers[qualifierId]) do
local isItem = qualifier.snaktype == 'value' and
qualifier.datavalue.type == 'wikibase-entityid'
local qualifierValues = mw.text.split(qualifierValue, ',')
-- per le proprietà di tipo item il confronto è eseguito sull'id
for _, qualifierHas in ipairs(qualifierValues) do
if formatSnak(qualifier, isItem and { formatting = 'raw' } or {}) == qualifierValue then
-- per le proprietà di tipo item il confronto è eseguito sull'id
ret = true
if formatSnak(qualifier, isItem and { formatting = 'raw' } or {}) == qualifierHas then
break
ret = true
break
end
end
end
Line 401 ⟶ 470:
local function filterRankValue(claims, rank)
local ret = {}
for i_, claim in pairsipairs(claims) do
if claim.rank == rank then
table.insert(ret, claim)
Line 409 ⟶ 478:
end
 
-- Restituisce una tablesequence Lua contenente gli statement per la property richiesta,
-- oppureanche nilvuota se l'entity o la proprietà non esistono.esiste, o non ci sono valori che soddisfano i criteri
-- ("rank", "qualifier", "qualifiertype", "noqualifier", ...).
-- Gli statement restituiti sono eventualmente filtrati in base ai parametri:
-- Restituisce nil solo se la pagina non è collegata a un elemento Wikidata e non è indicato il from.
-- "rank", "qualifier", "qualifiertype" e "n"
local function getClaims(propertypropertyId, args)
local entityentityId, claims, filteredClaims
entityId = args.from or mw.wikibase.getEntityIdForCurrentPage()
-- get entity
if not entityId then
entity = mw.wikibase.getEntity(args.from)
if not entity then
return nil
end
 
-- il default rank è 'best'
if property and entity.claims and entity.claims[property] and
args.rank = args.rank or 'best'
#entity.claims[property] > 0 then
if args.rank == 'best' then
claims = entity.claims[property]
claims = mw.wikibase.getBestStatements(entityId, propertyId)
else
-- statements filtrati per rank
return nil
claims = mw.wikibase.getAllStatements(entityId, propertyId)
claims = filterRankValue(claims, args.rank)
end
 
-- statements filtrati per ranksnaktype, (default 'best')"value"
args.ranksnaktype = args.ranksnaktype or 'bestvalue'
if args.ranksnaktype =and args.snaktype ~= 'bestall' then
filteredClaims = filterRankValue(claims, 'preferred'){}
for _, claim in ipairs(claims) do
if #filteredClaims == 0 then
if claim.mainsnak.snaktype == args.snaktype then
filteredClaims = filterRankValue(claims, 'normal')
table.insert(filteredClaims, claim)
end
end
claims = filteredClaims
else
filteredClaims = filterRankValue(claims, args.rank)
end
claims = filteredClaims
 
-- statements filtrati per qualifier
if args.qualifier then
filteredClaims = {}
for i_, claim in pairsipairs(claims) do
if claim.qualifiers and claim.qualifiers[args.qualifier] then
if args.qualifiervalue then
Line 461 ⟶ 532:
if args.noqualifier then
filteredClaims = {}
for i_, claim in pairsipairs(claims) do
if not (claim.qualifiers and claim.qualifiers[args.noqualifier]) then
table.insert(filteredClaims, claim)
Line 472 ⟶ 543:
if args.qualifieroptnovalue and args.qualifiervalue then
filteredClaims = {}
for i_, claim in pairsipairs(claims) do
if claim.qualifiers and claim.qualifiers[args.qualifieroptnovalue] then
if not hasQualifierValue(claim, args.qualifieroptnovalue, args.qualifiervalue) then
Line 487 ⟶ 558:
if args.qualifier and args.qualifiertype == 'latest' then
local latest, latestTime
for i_, claim in pairsipairs(claims) do
if claim.qualifiers and claim.qualifiers[args.qualifier] then
for j_, qualifier in pairsipairs(claim.qualifiers[args.qualifier]) do
if qualifier.datavalue.type == 'time' then
if not latestTime or qualifier.datavalue.value.time > latestTime then
Line 499 ⟶ 570:
end
end
claims = latest and { latest } or {}
end
 
Line 515 ⟶ 586:
-------------------------------------------------------------------------------
 
function p._getClaims(propertypropertyId, args)
return getClaims(propertypropertyId, args or {})
end
 
Line 523 ⟶ 594:
end
 
function p._formatQualifiers(claim, qualifierqualifierId, args, rawTable, retTable)
return formatQualifiers(claim, qualifierqualifierId, args or {}, rawTable, retTable)
end
 
Line 530 ⟶ 601:
-- la proprietà non esistono, o se per parametri di selezione gli statement sono zero.
function p._getProperty(args, rawTable)
local propertypropertyId, value, claims, ret
 
-- parametri posizionali
propertypropertyId = args[1] and string.upper(args[1])
if not propertypropertyId then
error(i18n.errors['property-param-not-provided'], 2)
end
Line 544 ⟶ 615:
ret = formatUserValue(value, args)
elseif args.wd ~= 'no' then
claims = getClaims(propertypropertyId, args)
ret = (claims and #claims > 0) and formatStatements(claims, args, rawTable) or nil
end
Line 554 ⟶ 625:
-- 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 propertypropertyId, qualifierqualifierId, value, claims, ret
 
-- parametri posizionali
propertypropertyId = args[1] and string.upper(args[1])
if not propertypropertyId then
error(i18n.errors['property-param-not-provided'], 2)
end
qualifierqualifierId = args[2] and string.upper(args[2])
if not qualifierqualifierId then
error(i18n.errors['qualifier-param-not-provided'], 2)
end
Line 570 ⟶ 641:
ret = formatUserValue(value, args)
elseif args.wd ~= 'no' then
claims = getClaims(propertypropertyId, args)
if claims and #claims > 0 then
local formattedQualifiers = {}
for _, claim in pairsipairs(claims) do
formattedQualifiers = formatQualifiers(claim, qualifierqualifierId, args, true, formattedQualifiers)
end
ret = #formattedQualifiers > 0 and
Line 586 ⟶ 657:
-- Restituisce l'indice dello statement con il valore richiesto, o nil se non trovato.
function p._indexOf(args)
local ret, propertypropertyId, value, claims
 
-- parametri posizionali
propertypropertyId = args[1] and string.upper(args[1])
if not propertypropertyId then
error(i18n.errors['property-param-not-provided'], 2)
end
Line 598 ⟶ 669:
end
 
claims = getClaims(propertypropertyId, args)
if claims and #claims > 0 then
args.formatting = 'raw'
for i, claim in pairsipairs(claims) do
if formatStatement(claim, args) == value then
ret = i
Line 613 ⟶ 684:
 
-- Restituisce il numero di statement di una proprietà di Wikidata.
function p._N(args)
local propertypropertyId, claims
 
-- parametri posizionali
propertypropertyId = args[1] and string.upper(args[1])
if not propertypropertyId then
error(i18n.errors['property-param-not-provided'], 2)
end
-- get claims
claims = getClaims(propertypropertyId, args)
 
return claims and #claims or 0
Line 629 ⟶ 700:
-- Restituisce true se la propriertà specificata ha come valore
-- almeno uno tra gli entityId passati come argomento.
function p._propertyHasEntity(propertypropertyId, args)
local statements = p._getProperty({property propertyId, from = args.from, formatting = 'raw' }, true)
if statements then
for _, statement in ipairs(statements) do
Line 636 ⟶ 707:
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
Line 641 ⟶ 744:
end
 
return false, args.loadedEntities
end
 
Line 655 ⟶ 758:
 
-- Restituisce l'etichetta di un item o di una proprietà Wikidata.
function p._getLabel(args)
local entityentityId = mw.wikibase.getEntity(args[1] and string.upper(args[1]))
local ret
return entity and entity:getLabel(args[2])
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
 
Line 673 ⟶ 789:
-- Restituisce il datatype di una proprietà Wikidata.
function p._getDatatype(args)
local propertypropertyId, entity
 
-- parametri posizionali
propertypropertyId = args[1] and string.upper(args[1])
if not propertypropertyId then
error(i18n.errors['property-param-not-provided'], 2)
end
 
entity = mw.wikibase.getEntity(propertypropertyId)
if not entity then
error(i18n.errors['entity-not-found'], 2)
Line 750 ⟶ 866:
return select(2, xpcall(function()
return p._getLabel(getArgs(frame, { parentOnly = true }))
end, errhandler))
end
 
-- Funzione per il template {{WikidataDescription}}
function p.getDescription(frame)
return select(2, xpcall(function()
return p._getDescription(getArgs(frame, { parentOnly = true }))
end, errhandler))
end
Line 778 ⟶ 901:
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 0 or ''
end, errhandler))
end
 
-- Funzione per il template {{WikidataClasse}}
function p.propertyHasEntity(frame)
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