Modulo:Wikidata

La documentazione per questo modulo può essere creata in Modulo:Wikidata/man

--[[* Modulo per implementare le funzionalità dei template:* {{Wikidata}}, {{WikidataQ}}, {{WikidataIdx}}, {{WikidataN}}, {{WikidataLabel}},* {{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 getArgs = require('Module:Arguments').getArgslocal mConvert = require('Module:Conversione')local mLanguages = require('Module:Linguaggi')-- Categoria per le pagine con errorilocal errorCategory = '[[Categoria:Voci con errori del modulo Wikidata]]'-- Messaggilocal 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 p = {}---------------------------------------------------------------------------------                             Formatters-------------------------------------------------------------------------------local function errhandler(msg)local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or ''return string.format('<span class="error">%s</span>%s', msg, cat)endlocal function formatList(values, ordered)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 ''endlocal function formatExtLink(url)local protocols = { ftp = true, http = true, https = true }local success, uri = pcall(function() return mw.uri.new(url) end)if success and uri.protocol and protocols[uri.protocol] thenlocal dest = tostring(uri)return string.format('<div style="word-break: break-all;">[%s %s]</div>', dest, dest:gsub(uri.protocol .. '://', ''))elsereturn urlendendlocal function formatEntityId(entityId)local label = mw.wikibase.getLabel(entityId)local siteLink = mw.wikibase.getSitelink(entityId)local retif entityId == mw.wikibase.getEntityIdForCurrentPage() thenret = siteLinkelseif siteLink and label thenret = mw.getContentLanguage():ucfirst(label) == siteLink and  string.format('[[%s]]', label) or  string.format('[[%s|%s]]', siteLink, label)elseif siteLink thenret = string.format('[[%s]]', siteLink)elseif label thenret = labelelseret = ''endreturn retendlocal function formatMonolingualtext(value, args)local ret = ''if not args.includelang or args.includelang:match('%f[a-z]' .. value.language .. '%f[^a-z]') thenif not args.excludelang or not args.excludelang:match('%f[a-z]' .. value.language .. '%f[^a-z]') thenret = value.textif args.showlang thenret = mLanguages.lingue({ value.language }) .. '&nbsp;' .. retendendendreturn retendlocal function formatTimeWithPrecision(time, precision)local months = {'gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno','luglio', 'agosto', 'settembre', 'ottobre', 'novembre', 'dicembre'}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 thenret = yearelseif precision == 10 thenret = months[month] .. ' ' .. yearelseif precision == 11 thenret = day .. ' ' .. months[month] .. ' ' .. yearret = ret:gsub('^1%s', '1º ')endif precision >= 9 and precision <= 11 thenret = ret .. (time:sub(1, 1) == '-' and ' a.C.' or '')endreturn retendlocal function formatTime(value, args)local ret if args.time == 'precision' thenret = value.precisionelseif args.time == 'calendarmodel' thenret = value.calendarmodelelseif args.time == 'year' and value.precision >= 9 thenret = formatTimeWithPrecision(value.time, 9)elseif args.time == 'month' and value.precision >= 10 thenret = formatTimeWithPrecision(value.time, 10)elseif args.time == 'day' and value.precision >= 11 thenret = formatTimeWithPrecision(value.time, 11)elseif not args.time thenret = formatTimeWithPrecision(value.time, value.precision)endreturn ret or ''endlocal function formatGlobecoordinate(value, args)local retif args.coord == 'latitude' thenret = value.latitudeelseif args.coord == 'longitude' thenret = value.longitudeelseif args.coord == 'globe' thenret = value.globeelseret = string.format('%s, %s', value.latitude, value.longitude)endreturn retendlocal function formatFromPattern(str, args)local pattern = args.patternpattern = mw.ustring.gsub(pattern, '\\{', '{')pattern = mw.ustring.gsub(pattern, '\\}', '}')return mw.getCurrentFrame():preprocess(mw.message.newRawMessage(pattern, str):plain())endlocal function formatUserValue(value, args)if args.extlink thenvalue = formatExtLink(value)endreturn args.pattern and formatFromPattern(value, args) or valueendlocal function getEntityIdFromValue(value)local prefix = ''if value['entity-type'] == 'item' thenprefix = 'Q'elseif value['entity-type'] == 'property' thenprefix = 'P'elseerror(i18n.errors['unknown-entity-type'])endreturn prefix .. value['numeric-id']endlocal function formatUnitSymbol(entityId, args)local retfor _, lang in ipairs({ 'mul', 'it', 'en' }) doret = p._getProperty({ 'P5061', includelang = lang, from = entityId })if ret and ret ~= '' thenbreakelseret = nilendendlocal space = ret == '°' and '' or ' 'if ret and args.showunitlink thenlocal link = mw.wikibase.getSitelink(entityId)if link thenret = string.format('[[%s|%s]]', link, ret)endendreturn ret and (space .. ret) or ''end-- http://lua-users.org/wiki/SimpleRoundlocal function round(num, idp)local mult = 10 ^ (idp or 0)return math.floor(num * mult + 0.5) / multendlocal function formatQuantity(value, args)local ret = tonumber(value.amount)if (args.unit or args.showunit) and value.unit ~= '1' thenlocal unitId = mw.ustring.match(value.unit, 'Q%d+')if args.unit thenlocal opts = {showunit = args.showunit,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 P5061ret = args.rounding and round(ret, args.rounding) or retif args.formatnum thenret = mw.language.getContentLanguage():formatNum(ret)endret = ret .. formatUnitSymbol(unitId, args)endelseif args.formatnum thenret = args.rounding and round(ret, args.rounding) or retret = mw.language.getContentLanguage():formatNum(ret)elseif args.formatduration and value.unit ~= '1' thenlocal 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' })endreturn retendlocal function formatDatavalue(datavalue, snakdatatype, args)local retif datavalue.type == 'wikibase-entityid' thenlocal entityId = getEntityIdFromValue(datavalue.value)if args.showprop thenret = p._getProperty({ args.showprop, n = 1, from = entityId }) or ''elseret = args.formatting == 'raw' and entityId or formatEntityId(entityId)endelseif datavalue.type == 'string' thenret = datavalue.valueif args.extlink and snakdatatype == 'url' thenret = formatExtLink(ret)elseif args.urlencode thenret = mw.uri.encode(ret)endelseif datavalue.type == 'monolingualtext' thenret = formatMonolingualtext(datavalue.value, args)elseif datavalue.type == 'time' thenif args.formatting == 'raw' thenret = datavalue.value.timeelseret = formatTime(datavalue.value, args)endelseif datavalue.type == 'globecoordinate' thenret = formatGlobecoordinate(datavalue.value, args)elseif datavalue.type == 'quantity' thenret = formatQuantity(datavalue.value, args)elseerror(i18n.errors['unknown-datavalue-type'])endreturn retendlocal function formatSnak(snak, args)if snak.snaktype == 'somevalue' thenreturn i18n['somevalue']elseif snak.snaktype == 'novalue' thenreturn i18n['novalue']elseif snak.snaktype == 'value' thenreturn formatDatavalue(snak.datavalue, snak.datatype, args)elseerror(i18n.errors['unknown-snak-type'])endend-- È 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] thenlocal qualifiers = claim.qualifiers[qualifierId]-- con args.nq seleziona solo l'n-esimo qualifierif args.nq thenlocal n = tonumber(args.nq)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) doif qualifier.snaktype == args.snaktype or args.snaktype == 'all' thenlocal formattedQualifier = formatSnak(qualifier, args)if formattedQualifier ~= '' thenif args.pattern thenformattedQualifier = formatFromPattern(formattedQualifier, args)if formattedQualifier ~= '' thentable.insert(formattedQualifiers, formattedQualifier)endelsetable.insert(formattedQualifiers, formattedQualifier)endendendendendif rawTable thenreturn formattedQualifiersendreturn #formattedQualifiers > 0 and   mw.text.listToText(formattedQualifiers, args.separator, args.conjunction) or nilendlocal function appendQualifiers(statement, text, args)local formattedQualifiers = {}local qualifierIds = mw.text.split(args.showqualifiers, ',')for _, qualifierId in ipairs(qualifierIds) doif statement.qualifiers[qualifierId] thenlocal formattedQualifier = formatQualifiers(statement, qualifierId, args)table.insert(formattedQualifiers, formattedQualifier)endendif #formattedQualifiers > 0 thentext = string.format('%s (%s)', text, mw.text.listToText(formattedQualifiers, ', ', ', '))endreturn textendlocal function formatStatement(statement, args)if not statement.type or statement.type ~= 'statement' thenerror(i18n.errors['unknown-claim-type'])end local ret = formatSnak(statement.mainsnak, args)-- eventuale showqualifiersif args.showqualifiers and statement.qualifiers thenret = appendQualifiers(statement, ret, args)endreturn retendlocal function formatStatements(claims, args, rawTable)local formattedStatements = {}for _, claim in ipairs(claims) dolocal formattedStatement = formatStatement(claim, args)if formattedStatement ~= '' then-- eventuale patternif args.pattern thenformattedStatement = formatFromPattern(formattedStatement, args)if formattedStatement ~= '' thentable.insert(formattedStatements, formattedStatement)endelsetable.insert(formattedStatements, formattedStatement)endendendif rawTable thenreturn formattedStatementsendreturn ((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 valorelocal function hasQualifierValue(statement, qualifierId, qualifierValue)local ret = falsefor _, qualifier in ipairs(statement.qualifiers[qualifierId]) dolocal isItem = qualifier.snaktype == 'value' and   qualifier.datavalue.type == 'wikibase-entityid'-- per le proprietà di tipo item il confronto è eseguito sull'idif formatSnak(qualifier, isItem and { formatting = 'raw' } or {}) == qualifierValue thenret = truebreakendendreturn retend-- Restituisce i claim con il rank richiestolocal function filterRankValue(claims, rank)local ret = {}for _, claim in ipairs(claims) doif claim.rank == rank thentable.insert(ret, claim)endendreturn retend-- 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)local entityId, claims, filteredClaimsentityId = args.from or mw.wikibase.getEntityIdForCurrentPage()if not entityId thenreturn nilend-- il default rank è 'best'args.rank = args.rank or 'best'if args.rank == 'best' thenclaims = mw.wikibase.getBestStatements(entityId, propertyId)else-- statements filtrati per rankclaims = mw.wikibase.getAllStatements(entityId, propertyId)claims = filterRankValue(claims, args.rank)end-- statements filtrati per snaktype, default "value"args.snaktype = args.snaktype or 'value'if args.snaktype and args.snaktype ~= 'all' thenfilteredClaims = {}for _, claim in ipairs(claims) doif claim.mainsnak.snaktype == args.snaktype thentable.insert(filteredClaims, claim)endendclaims = filteredClaimsend-- statements filtrati per qualifierif args.qualifier thenfilteredClaims = {}for _, claim in ipairs(claims) doif claim.qualifiers and claim.qualifiers[args.qualifier] thenif args.qualifiervalue thenif hasQualifierValue(claim, args.qualifier, args.qualifiervalue) thentable.insert(filteredClaims, claim)endelsetable.insert(filteredClaims, claim)endendendclaims = filteredClaimsend-- statements filtrati per essere senza un qualifierif args.noqualifier thenfilteredClaims = {}for _, claim in ipairs(claims) doif not (claim.qualifiers and claim.qualifiers[args.noqualifier]) thentable.insert(filteredClaims, claim)endendclaims = filteredClaimsend-- statements filtrati per non avere un certo valore a un certo qualifier opzionaleif args.qualifieroptnovalue and args.qualifiervalue thenfilteredClaims = {}for _, claim in ipairs(claims) doif claim.qualifiers and claim.qualifiers[args.qualifieroptnovalue] thenif not hasQualifierValue(claim, args.qualifieroptnovalue, args.qualifiervalue) thentable.insert(filteredClaims, claim)endelsetable.insert(filteredClaims, claim)endendclaims = filteredClaimsend-- con args.qualifiertype=latest restituisce solo il più recenteif args.qualifier and args.qualifiertype == 'latest' thenlocal latest, latestTimefor _, claim in ipairs(claims) doif claim.qualifiers and claim.qualifiers[args.qualifier] thenfor _, qualifier in ipairs(claim.qualifiers[args.qualifier]) doif qualifier.datavalue.type == 'time' thenif not latestTime or qualifier.datavalue.value.time > latestTime thenlatest = claimlatestTime = qualifier.datavalue.value.timeendendendendendclaims = latest and { latest } or {}end-- con args.n restituisce solo l'n-esimo elementoif args.n thenlocal n = tonumber(args.n)claims = (n and n <= #claims) and { claims[n] } or {}endreturn claimsend---------------------------------------------------------------------------------                  Funzioni esportate per altri moduli-------------------------------------------------------------------------------function p._getClaims(propertyId, args)return getClaims(propertyId, args or {})endfunction p._formatStatement(statement, args)return formatStatement(statement, args or {})endfunction p._formatQualifiers(claim, qualifierId, args, rawTable, retTable)return formatQualifiers(claim, qualifierId, args or {}, rawTable, retTable)end-- 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)local propertyId, value, claims, ret-- parametri posizionalipropertyId = args[1] and string.upper(args[1])if not propertyId thenerror(i18n.errors['property-param-not-provided'], 2)endvalue = args[2]-- fix uppercaseargs.qualifier = args.qualifier and string.upper(args.qualifier)if value thenret = formatUserValue(value, args)elseif args.wd ~= 'no' thenclaims = getClaims(propertyId, args)ret = (claims and #claims > 0) and formatStatements(claims, args, rawTable) or nilendreturn retend-- Restituisce il valore di un qualifier di una proprietà di Wikidata,-- 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 posizionalipropertyId = args[1] and string.upper(args[1])if not propertyId thenerror(i18n.errors['property-param-not-provided'], 2)endqualifierId = args[2] and string.upper(args[2])if not qualifierId thenerror(i18n.errors['qualifier-param-not-provided'], 2)endvalue = args[3]if value thenret = formatUserValue(value, args)elseif args.wd ~= 'no' thenclaims = getClaims(propertyId, args)if claims and #claims > 0 thenlocal formattedQualifiers = {}for _, claim in ipairs(claims) doformattedQualifiers = formatQualifiers(claim, qualifierId, args, true, formattedQualifiers)endret = #formattedQualifiers > 0 and  mw.text.listToText(formattedQualifiers, args.separator, args.conjunction) or nilendendreturn retend-- Restituisce l'indice dello statement con il valore richiesto, o nil se non trovato.function p._indexOf(args)local ret, propertyId, value, claims-- parametri posizionalipropertyId = args[1] and string.upper(args[1])if not propertyId thenerror(i18n.errors['property-param-not-provided'], 2)endvalue = args[2]if not value thenerror(i18n.errors['value-param-not-provided'], 2)endclaims = getClaims(propertyId, args)if claims and #claims > 0 thenargs.formatting = 'raw'for i, claim in ipairs(claims) doif formatStatement(claim, args) == value thenret = ibreakendendendreturn retend-- Restituisce il numero di statement di una proprietà di Wikidata.function p._N(args)local propertyId, claims-- parametri posizionalipropertyId = args[1] and string.upper(args[1])if not propertyId thenerror(i18n.errors['property-param-not-provided'], 2)end-- get claimsclaims = getClaims(propertyId, args)return claims and #claims or 0end-- 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 thenfor _, statement in ipairs(statements) dofor _, entityId in ipairs(args) doif statement == entityId thenreturn trueendendend-- 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) maxDepthche svolga l'attuale funzione di recursion e cambiare quest'ultimoin un parametro booleano.]]args.recursion = tonumber(args.recursion) or 0if args.recursion > 0 thenlocal recursion = args.recursionif type(args.loadedEntities) ~= 'table' thenargs.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()] = trueendfor _, statement in ipairs(statements) doif not args.loadedEntities[statement] thenargs.loadedEntities[statement] = trueargs.recursion = args.recursion - 1args.from = statementif p._propertyHasEntity('P279', args) thenreturn true, args.loadedEntitiesendargs.recursion = recursionendendendendreturn false, args.loadedEntitiesend-- Restituisce true se la proprietà P31 (instance of) ha come valore almeno uno tra gli entityId specificatifunction p._instanceOf(args)return p._propertyHasEntity('P31', args)end-- Restituisce true se la proprietà P279 (subclass of) ha come valore almeno uno tra gli entityId specificatifunction 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 retif args[2] thenret = mw.wikibase.getLabelByLang(entityId, args[2])elseret = mw.wikibase.getLabel(entityId)endreturn retend-- Restituisce il titolo della pagina collegata a un dato item Wikidata.function p._getLink(args) -- parametri posizionalilocal entityId = args[1] and string.upper(args[1])if not entityId thenerror(i18n.errors['entityid-param-not-provided'], 2)endreturn entityId:sub(1, 1) == 'Q' and formatEntityId(entityId) or nilend-- Restituisce il datatype di una proprietà Wikidata.function p._getDatatype(args) local propertyId, entity-- parametri posizionalipropertyId = args[1] and string.upper(args[1])if not propertyId thenerror(i18n.errors['property-param-not-provided'], 2)endentity = mw.wikibase.getEntity(propertyId)if not entity thenerror(i18n.errors['entity-not-found'], 2)endif not i18n.datatypes[entity.datatype] thenerror(i18n.errors['unknown-datavalue-type'], 2)endreturn 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 retif args[1] thenlocal title = mw.title.new(args[1])while title dolocal id = mw.wikibase.getEntityIdForTitle(title.prefixedText)if id thenret = idbreakelsetitle = title.redirectTargetendendelseret = mw.wikibase.getEntityIdForCurrentPage()endreturn retend---------------------------------------------------------------------------------                  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-- Funzione per il template {{WikidataQ}}function p.getQualifier(frame)return select(2, xpcall(function()return p._getQualifier(getArgs(frame, { parentOnly = true }))end, errhandler))end-- Funzione per il template {{WikidataIdx}}function p.indexOf(frame)return select(2, xpcall(function()return p._indexOf(getArgs(frame, { parentOnly = true }))end, errhandler))end-- Funzione per il template {{WikidataN}}function p.N(frame)return select(2, xpcall(function()return p._N(getArgs(frame, { parentOnly = true }))end, errhandler))end-- Funzione per il template {{WikidataLabel}}function p.getLabel(frame)return select(2, xpcall(function()return p._getLabel(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-- Funzione per il template {{WikidataIstanza}}function p.instanceOf(frame)return select(2, xpcall(function()return p._instanceOf(getArgs(frame, { parentOnly = true })) and 1 or ''end, errhandler))end-- Funzione per il template {{WikidataTipo}}function p.getDatatype(frame)return select(2, xpcall(function()return p._getDatatype(getArgs(frame, { parentOnly = true }))end, errhandler))end-- Funzione per il template {{WikidataId}}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))endreturn p