Aller au contenu

Module:Wikidata/sandbox

Une page de Wikipédia, l'encyclopédie libre.
Ceci est une version archivée de cette page, en date du 19 juin 2019 à 02:32 et modifiée en dernier par Speltdecca (discuter | contributions) (copie de https://it.wikipedia.org/wiki/Modulo:Wikidata/sandbox car wp.fr n'a pas de fonction qui permet de renvoyer qu'une seule langue au choix entre plusieurs disponibles dans wd). Elle peut contenir des erreurs, des inexactitudes ou des contenus vandalisés non présents dans la version actuelle.
(diff) ← Version précédente | Version actuelle (diff) | Version suivante → (diff)

 Documentation[créer] [purger]
--[[
* 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').getArgs
local mConvert = require('Module:Conversion2')
local mLanguages = require('Module:Langue')

-- Categoria per le pagine con errori
local errorCategory = '[[Categoria:Voci con errori del modulo Wikidata]]'

-- 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 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)
end

local 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 ''
end

local 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] then
        local dest = tostring(uri)
        return string.format('<div style="word-break: break-all;">[%s %s]</div>', dest, dest:gsub(uri.protocol .. '://', ''))    
    else
        return url
    end
end

local function formatEntityId(entityId)
    local label = mw.wikibase.getLabel(entityId)
    local siteLink = mw.wikibase.getSitelink(entityId)
    local ret
    if 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
    return ret
end

local function formatMonolingualtext(value, args)
    local ret = ''
    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 }) .. '&nbsp;' .. ret
            end
        end
    end
    return ret
end

local 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 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
    if precision >= 9 and precision <= 11 then
        ret = ret .. (time:sub(1, 1) == '-' and ' a.C.' or '')
    end

    return ret
end

local function formatTime(value, args)
    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

    return ret or ''
end

local function formatGlobecoordinate(value, args)
    local ret
    if args.coord == 'latitude' then
        ret = value.latitude
    elseif args.coord == 'longitude' then
        ret = value.longitude
    elseif args.coord == 'globe' then
        ret = value.globe
    else
        ret = string.format('%s, %s', value.latitude, value.longitude)
    end
    return ret
end

local function formatFromPattern(str, args)
    local pattern = args.pattern
    pattern = mw.ustring.gsub(pattern, '\\{', '{')
    pattern = mw.ustring.gsub(pattern, '\\}', '}')
    return mw.getCurrentFrame():preprocess(mw.message.newRawMessage(pattern, str):plain())
end

local function formatUserValue(value, args)
    if args.extlink then
        value = formatExtLink(value)
    end
    return args.pattern and formatFromPattern(value, args) or value
end

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
    return prefix .. value['numeric-id']
end

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.getSitelink(entityId)
        if link then
            ret = string.format('[[%s|%s]]', link, ret)
        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 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,
                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
    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

    return ret
end

local function formatDatavalue(datavalue, snakdatatype, args)
    local ret

    if datavalue.type == 'wikibase-entityid' then
        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
        error(i18n.errors['unknown-datavalue-type'])
    end

    return ret
end

local function formatSnak(snak, args)
    if snak.snaktype == 'somevalue' then
        return i18n['somevalue']
    elseif snak.snaktype == 'novalue' then
        return i18n['novalue']
    elseif snak.snaktype == 'value' then
        return formatDatavalue(snak.datavalue, snak.datatype, args)
    else
        error(i18n.errors['unknown-snak-type'])
    end
end

-- È 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
        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
        -- qualifiers 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)
                        end
                    else
                        table.insert(formattedQualifiers, formattedQualifier)
                    end
                end
            end
        end
    end

    if rawTable then
        return formattedQualifiers
    end

    return #formattedQualifiers > 0 and
           mw.text.listToText(formattedQualifiers, args.separator, args.conjunction) or nil
end

local function appendQualifiers(statement, text, args)
    local formattedQualifiers = {}
    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
    if #formattedQualifiers > 0 then
        text = string.format('%s (%s)', text, mw.text.listToText(formattedQualifiers, ', ', ', '))
    end
    return text
end

local function formatStatement(statement, args)
    if not statement.type or statement.type ~= 'statement' then
        error(i18n.errors['unknown-claim-type'])
    end
 
    local ret = formatSnak(statement.mainsnak, args)
    -- eventuale showqualifiers
    if args.showqualifiers and statement.qualifiers then
        ret = appendQualifiers(statement, ret, args)
    end

    return ret
end

local function formatStatements(claims, args, rawTable)
    local formattedStatements = {}

    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
                table.insert(formattedStatements, formattedStatement)
            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
local function hasQualifierValue(statement, qualifierId, qualifierValue)
    local ret = false
    for _, qualifier in ipairs(statement.qualifiers[qualifierId]) do
        local isItem = qualifier.snaktype == 'value' and
                       qualifier.datavalue.type == 'wikibase-entityid'
        -- per le proprietà di tipo item il confronto è eseguito sull'id
        if formatSnak(qualifier, isItem and { formatting = 'raw' } or {}) == qualifierValue then
            ret = true
            break
        end
    end
    return ret
end

-- Restituisce i claim con il rank richiesto
local function filterRankValue(claims, rank)
    local ret = {}
    for _, claim in ipairs(claims) do
        if claim.rank == rank then
            table.insert(ret, claim)
        end
    end
    return ret
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)
    local entityId, claims, filteredClaims
    
    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 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

    -- 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
        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
        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
        claims = filteredClaims
    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
        claims = latest and { latest } or {}
    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

    return claims
end

-------------------------------------------------------------------------------
--                  Funzioni esportate per altri moduli
-------------------------------------------------------------------------------

function p._getClaims(propertyId, args)
    return getClaims(propertyId, args or {})
end

function p._formatStatement(statement, args)
    return formatStatement(statement, args or {})
end

function 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 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]
    -- 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

    return ret
end

-- 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 posizionali
    propertyId = args[1] and string.upper(args[1])
    if not propertyId then
        error(i18n.errors['property-param-not-provided'], 2)
    end
    qualifierId = args[2] and string.upper(args[2])
    if not qualifierId then
        error(i18n.errors['qualifier-param-not-provided'], 2)
    end
    value = args[3]

    if value then
        ret = formatUserValue(value, args)
    elseif args.wd ~= 'no' then
        claims = getClaims(propertyId, args)
        if claims and #claims > 0 then
            local formattedQualifiers = {}
            for _, claim in ipairs(claims) do
                formattedQualifiers = formatQualifiers(claim, qualifierId, args, true, formattedQualifiers)
            end
            ret = #formattedQualifiers > 0 and
                  mw.text.listToText(formattedQualifiers, args.separator, args.conjunction) or nil
        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

    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
                ret = i
                break
            end
        end
    end

    return ret
end

-- 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
    -- get claims
    claims = getClaims(propertyId, args)

    return claims and #claims or 0
end

-- 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
                end
            end
        end
    end

    return false
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

-- 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 il titolo della pagina collegata a un dato item Wikidata.
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
    
    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

    entity = mw.wikibase.getEntity(propertyId)
    if not entity then
        error(i18n.errors['entity-not-found'], 2)
    end

    if not i18n.datatypes[entity.datatype] then
        error(i18n.errors['unknown-datavalue-type'], 2)
    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
    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

-- 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))
end

return p