Modulo:Wikidata

Da Wikisource.
Jump to navigation Jump to search

Il modulo Wikidata serve per leggere il valore delle proprietà di Wikidata, relative alla pagina corrente, cioè la pagina in cui è utilizzato il modulo. Sarà in futuro possibile leggere le proprietà anche di pagine diverse da quella corrente. Il modulo fornisce un utilizzo più avanzato, a volte senza alternativa, rispetto a quello che si può ottenere con la magic word: {{#property:NumProprietà}}.

Utilizzo

Il modulo ha tre funzioni:

  • formatStatements: restituisce il valore di una proprietà di Wikidata. Nel caso una proprietà ha più di un valore (statement) li può restituire tutti, separandoli con una virgola e inserendo la congiunzione "e" prima dell'ultimo, oppure filtrarli se si specifica un rank, un qualifier o un indice. Permette di formattare l'output attraverso delle opzioni (da qui il nome formatStatements). Se la pagina non ha un elemento su Wikidata, oppure non ha la proprietà specificata, oppure il valore della proprietà è a sua volta un elemento che non ha un'etichetta in italiano, non restituisce nulla. Se possibile, i valori delle proprietà sono restituiti con wikilink, compresa eventuale disambiguazione nascosta con la barra verticale (es. [[Savoia (dipartimento)|Savoia]]). Il nome italiano della voce viene ricavato dall'interlink del rispettivo elemento su Wikidata; se il soggetto non è presente su Wikidata, il valore viene restituito senza wikilink.
  • getQualifier: restituisce il valore di un qualifier di una proprietà di Wikidata. Se la proprietà ha più statement e il qualifier è presente in più statement, oppure se il qualifier ha più valori, li può restituire tutti, oppure si possono filtrare in base a rank e indice (dello statement) come per la formatStatements.
  • N: ritorna il numero di statement della proprietà richiesta

Parametri di formatStatements

La funzione formatStatements ha i seguenti parametri, l'unico obbligatorio è property. Gli esempi utilizzati fanno riferimento alla voce Dante Alighieri (le cui proprietà su Wikidata sono queste: d:Q1067).

Parametri di selezione:

  • property: il codice della proprietà
    • esempio: {{#invoke:Wikidata|formatStatements|property=p19}} ritornerà: Firenze (d:P39 è il luogo di nascita)
  • rank: se valorizzato, il modulo ritorna solo gli statement che hanno un certo rank. I rank disponibili sono i tre definiti da Wikidata: deprecated, normal e preferred, più il tipo best. Con quest'ultimo vengono ritornati gli statement a partire dal rank più alto: i preferred se presenti altrimenti i normal.
  • qualifier: codice di un qualifier di una proprietà. Verranno ritornati solo gli statement che posseggono quel qualifier.
  • qualifiervalue: valore del qualifier specificato con il parametro qualifier. Verranno ritornati solo gli statement che posseggono quel qualifier e con il valore specificato con qualifiervalue.
  • qualifiertype: ulteriore filtro sul qualifier specificato. Ha attualmente un unico valore accettato, qualifiertype=latest: se il qualifier contiene un valore di tipo "time", verrà ritornato solo lo statement che possiede quel qualifier e con il valore più recente.
  • n: se la proprietà ha più statement ritorna l'n-esimo
    • esempio: {{#invoke:Wikidata|formatStatements|property=p106|n=1}} ritornerà: poeta (d:P106 è l'occupazione), mentre con n=2 avrebbe ritornato scrittore, con n=3 politico
  • value: se valorizzato, il modulo ritorna il valore di questo parametro invece di quello su Wikidata, formattandolo eventualmente secondo il pattern se specificato. Serve quando si usa il modulo da un template, per dare la precedenza al valore passato al template rispetto a quello su Wikidata.
    • esempio: {{#invoke:Wikidata|formatStatements|property=p19|value={{{LuogoNascita|}}}}} ritornerà: il valore di LuogoNascita se valorizzato, altrimenti quello della proprietà p19 su Wikidata
  • entityId: per ora NON FUNZIONANTE, quando sarà attivato permetterà di specificare un'entity di Wikidata relativa a una pagina diversa da quella in cui ci si trova

Parametri per la formattazione del risultato:

  • separator: separatore tra valori multipli, se diverso da virgola_spazio
  • conjunction: separatore tra gli ultimi due valori, se diverso da spazio_e_spazio
    • esempio: {{#invoke:Wikidata|formatStatements|property=p106|separator=/|conjunction=/}} ritornerà: scrittore/politico/poeta
  • pattern: pattern utilizzato per ogni statement, sia per le proprietà che per il parametro "value" quando presente. La stringa "$1" verrà rimpiazzata dal valore ritornato per ogni sua occorrenza.
    • esempio: {{#invoke:Wikidata|formatStatements|property=p18|pattern=[[File:$1|thumb|Il nome del file è $1]]}} ritornerà: [[File:Portrait de Dante.jpg|thumb|Il nome del file è Portrait de Dante.jpg]] (d:P18 è l'immagine)
    • esempio con value: {{#invoke:Wikidata|formatStatements|property=p18|value={{{Immagine|}}}|pattern=[[File:$1|thumb|Il nome del file è $1]]}} In un template, se il parametro Immagine fosse valorizzato a "Test.png" allora ritornerebbe [[File:Test.png|thumb|Il nome del file è Test.png]], altrimenti se Immagine non fosse valorizzato, lo stesso risultato dell'esempio precedente.
  • list: formatta il risultato ritornato come lista non ordinata, si deve assegnargli un valore qualunque, es: "list=sì". Eventuali parametri separator e conjunction vengono ignorati.
    • esempio: {{#invoke:Wikidata|formatStatements|property=p106|list=1}}
  • orderedlist: formatta il risultato ritornato come lista ordinata, si deve assegnargli un valore qualunque, es: "orderedlist=sì". Eventuali parametri separator e conjunction vengono ignorati. Se sono presenti entrambi i parametri list e orderedlist viene creata una lista non ordinata
    • esempio: {{#invoke:Wikidata|formatStatements|property=p106|orderedlist=1}}
  • formatting: esegue formattazioni speciali, attulmente i valori consentiti sono: formatting=latitude e formatting=longitude per ritornare solo latitudine o longitudine in caso di proprietà di tipo coordinata
  • value-module: nome di un modulo che effettua una formattazione speciale
  • value-function: funzione nel modulo value-module

Parametri di getQualifier

Parametri di selezione:

  • gli stessi di formatStatements, con in più la differenza che i parametri obbligatori sono, oltre "property", anche "qualifier".

Parametri per la formattazione del risultato:

  • gli stessi di formatStatements, ad eccezione di list e orderedlist.

Parametri di N

La funzione N ha un unico parametro (ordinale) per specificare la proprietà.

  • esempio: {{#invoke:Wikidata|N|p40}} ritornerà: 2 (d:P40 è "figli")

Voci correlate


local i18n = {
    ["errors"] = {
        ["property-param-not-provided"] = "Parametro ''property'' 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.",
        ["unknown-value-module"] = "Devi impostare entrambi i parametri: ''value-module'' e ''value-function''.",
        ["value-module-not-found"] = "Modulo indicato da ''value-module'' non trovato.",
        ["value-function-not-found"] = "Funzione indicata da ''value-function'' non trovata."
    },
    ["somevalue"] = "''valore sconosciuto''",
    ["novalue"] = "''nessun valore''"
}
 
function getEntityFromId( id )
    if id then
        return mw.wikibase.getEntityObject( id )
    end
    return mw.wikibase.getEntityObject()
end
 
function getEntityIdFromValue( value )
    local prefix = ''
    if value['entity-type'] == 'item' then
        prefix = 'Q'
    elseif value['entity-type'] == 'property' then
        prefix = 'P'
    else
        return formatError( 'unknown-entity-type' )
    end
    return prefix .. value['numeric-id']
end
 
function formatError( key )
    return '<span class="error">' .. i18n.errors[key] .. '</span>'
end
 
 
function formatStatements( options )
    if not options.property then
        return formatError( 'property-param-not-provided' )
    end
 
    --Get entity
    local entity = getEntityFromId( options.entityId )
    if not entity then
        return -- formatError( 'entity-not-found' )
    end
 
    if (entity.claims == nil) or (not entity.claims[string.lower(options.property)]) then
        return '' --TODO error?
    end
 
    --Format statement and concat them cleanly
    local formattedStatements = {}
    local list_end
    if options.list or options.orderedlist then
        if options.list then 
            formattedStatements[1] = '<ul><li>'
            list_end = '</li></ul>'
        else
            formattedStatements[1] = '<ol><li>'
            list_end = '</li></ol>'
        end
        options.separator = '</li><li>'
        options.conjunction = options.separator
    end

    if options.n then
        local n = tonumber(options.n)
        if n then
            local statement = entity.claims[string.lower(options.property)][n - 1]
            if statement then
                table.insert( formattedStatements, formatStatement( statement, options ) )
            end
        end
    else
        for i, statement in pairs( entity.claims[string.lower(options.property)] ) do
            table.insert( formattedStatements, formatStatement( statement, options ) )
        end
    end
    if list_end then table.insert(formattedStatements, list_end) end
    return mw.text.listToText( formattedStatements, options.separator, options.conjunction )
end
 
function formatStatement( statement, options )
    if not statement.type or statement.type ~= 'statement' then
        return formatError( 'unknown-claim-type' )
    end
 
    if options.qualifier then
        return (statement.qualifiers and statement.qualifiers[options.qualifier]) and
               formatDatavalue( statement.qualifiers[options.qualifier][0].datavalue, options ) or ''
    else
        return formatSnak( statement.mainsnak, options )
    end
    --TODO reference
end

function formatSnak( snak, options )
    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, options )
    else
        return formatError( 'unknown-snak-type' )
    end
end

function formatDatavalue( datavalue, options )
    local ret

    --Use the customize handler if provided
    if options['value-module'] or options['value-function'] then
        if not options['value-module'] or not options['value-function'] then
            return formatError( 'unknown-value-module' )
        end
        local formatter = require ('Module:' .. options['value-module'])
        if formatter == nil then
            return formatError( 'value-module-not-found' )
        end
        local fun = formatter[options['value-function']]
        if fun == nil then
            return formatError( 'value-function-not-found' )
        end
        return fun( datavalue.value, options )
    end
 
    --Default formatters
    if datavalue.type == 'wikibase-entityid' then
        ret = formatEntityId( getEntityIdFromValue( datavalue.value ), options )
    elseif datavalue.type == 'string' then
        ret = datavalue.value
    elseif datavalue.type == 'time' then
        ret = formatTime( datavalue.value, options )
    elseif datavalue.type == 'globecoordinate' then
        ret = formatGlobecoordinate( datavalue.value, options )
    end

    -- Optional pattern
    if ret then
        return options.pattern and formatFromPattern( ret, options ) or ret
    else
        return formatError( 'unknown-datavalue-type' )
    end
end
 
function formatEntityId( entityId, options )
    local label = mw.wikibase.label( entityId )
    local link = mw.wikibase.sitelink( entityId )
    if link then
        if label then
            return '[[' .. link .. '|' .. label .. ']]'
        else
            return '[[' .. link .. ']]'
        end
    else
        return label --TODO what if no links and label + fallback language?
    end
end

function formatTime( value, options )
    local year, month, day
    local ret = ''
 
    year, month, day = value.time:match('.+(%d%d%d%d%d)%-(%d%d)%-(%d%d).+')
    if value.precision == 9 then
        ret = tonumber(year)
    elseif value.precision == 11 then
        ret = mw.getLanguage('it'):formatDate('j F Y', tonumber(year) .. '-' .. month .. '-' .. day)
    end
    if value.precision == 9 or value.precision == 11 then
        ret = ret .. (value.time:sub(1, 1) == '-' and ' a.C.' or '')
    end

    return ret
end

function formatGlobecoordinate( value, options )
    return value.globe == 'http://www.wikidata.org/entity/Q2' and
           (value.latitude .. ', ' .. value.longitude) or ''
end

function formatFromPattern( str, options )
    -- la parentesi () extra serve per non ritornare anche il gsub.count 
    return ( mw.ustring.gsub( options.pattern, '$1', str ) )
end

-- Ritorna gli argomenti passati al modulo, scartando quelli valorizzati a stringhe vuote
local function getArgs(frame)
    local args = {}
 
    for k, v in pairs(frame.args) do
        if v ~= '' then
            args[k] = v
        end
    end
 
    return args
end

local p = {}
 
function p.formatStatements( frame )
    local args, value

    --value è l'unico parametro che può anche essere una stringa vuota
    value = frame.args.value
    args = getArgs(frame)
 
    --If a value is already set, use it
    if value and value ~= '' then
        return args.pattern and formatFromPattern( value, args ) or value
    end

    return formatStatements( args )
end
 
function p.N(frame) 
    local count = 0

    property = string.upper(frame.args[1])
    entity = mw.wikibase.getEntityObject()
    if entity and entity.claims and entity.claims[property] then
        for _ in pairs(entity.claims[property]) do count = count + 1 end
    end

    return count
end
 
return p