Módulo:Wikidata
[editar] [ ]
Documentación del módulo
Uso
Este módulo devuelve el valor o valores con o sin formato específico a una propiedad de Wikidata.
Funciones
claim
: Devuelve el valor (o los valores) de una declaración o de un calificador con un formato por defecto según el tipo de dato.badge
: Devuelve el valor de la insígnia (badge) de una obra enlazada en Wikidata.
Función claim
Devuelve el valor (o los valores) de una declaración o de un calificador con un formato por defecto según el tipo de dato. Por defecto está referido al ítem de Wikidata (Qid) asociado a la página actual.
Sintaxis completa:
{{#invoke:Wikidata|claim|item= |lang= |property= |qualifier= |list= |formatting= }}
Parámetros generales
item=
(opcional) Permite indicar un ítem (Qid) diferente al ítem asociado a la página actual. Ha de usarse con moderación por su alto consumo de recursos.
lang=
(opcional) Permite indicar el código de un idioma determinado.
property=
(obligatorio) Identificador de la propiedad de la declaración (Pid). Por ejemplo "P50".
qualifier=
(opcional) Calificador (Pid) del valor de la propiedad.
list=
(opcional):list=true
(por defecto): Muestra una lista de todos los valores, separados con un "separador" por defecto y una "conjunción" predefinida.list=false
: sólo recuperará un valor, generalmente el de mayor rango o el más antiguo.
formatting=
(opcional): tipo de formato. Depende del valor de la entidad (ver código fuente). Ejemplos habituales: "raw", "label", "sitelink"...
Ejemplos
Wikidata.claim{item=Q107297266, property="P50", lang="es", list=true}
devuelve los autores (propiedad P50) del ítem Q107297266 (edición de 1864 de El Robinson suizo).
Función badge
Devuelve la insignia (badge) de una obra enlazada en Wikidata a partir de su identificador o del valor correspondiente en el índice. Valores devueltos posibles: (no corregido), (corregida), (validada), o (problemática). Ha de existir la página y la insignia debe corresponder a uno de estas cuatro (si no, el valor devuelto es nulo).
{{#invoke:Wikidata|badge|qid=|indicator=|ws=}}
qid=
es el identificador de la obra en Wikidata.indicator=
si tiene cualquier valor, envuelve la insignia en la etiqueta<indicator>
y la muestra en la parte superior de la página (no funciona en móviles, solo escritorio).ws=
devuelve la insignia correspondiente según el valor del parámetro "progreso" en los índices.C
= no corregido,V
= corregido,T
= validado,E
= problemática.
{{#invoke:Wikidata|badge|qid=Q30097675}}
= («Q30097675» corresponde al identificador de Lecciones Matemáticas).Esta documentación está transcluida desde Módulo:Wikidata/doc.
Los editores pueden experimentar en la zona de pruebas
Por favor, añade las categorías a la subpágina de documentación.
(subpáginas - enlaces)
Los editores pueden experimentar en la zona de pruebas
Por favor, añade las categorías a la subpágina de documentación.
(subpáginas - enlaces)
--[[*********************************************************************************
* Nombre: Módulo:Wikidata
*
* Descripción: Este módulo devuelve el valor o valores con o sin formato
* específico a una propiedad de Wikidata.
*
* Fecha última revisión: 2 de mayo de 2019.
*
* Estado: En uso.
*
*********************************************************************************`-- ]]
local p = {}
local datequalifiers = {'P585', 'P571', 'P580', 'P582'}
local es = mw.language.new('es')
local primera = true
--local marco Ojo. marco no debe definirse como local pues si se hace así puede fallar.
--[[ =========================================================================
Mensajes de error
========================================================================= `-- ]]
local avisos = {
["errores"] = {
["property-param-not-provided"] = "Parámetro de la propiedad no proporcionado.",
["entity-not-found"] = "Entrada no encontrada.",
["unknown-claim-type"] = "Tipo de notificación desconocida.",
["unknown-snak-type"] = "Tipo de dato desconocido.",
["unknown-datavalue-type"] = "Formato de dato desconocido.",
["unknown-entity-type"] = "Tipo de entrada desconocido.",
["unknown-value-module"] = "Debe ajustar ambos parámetros de valor y el valor del módulo de funciones.",
["value-module-not-found"] = "No se ha encontrado el módulo apuntado por valor-módulo.",
["value-function-not-found"] = "No se ha encontrado la función apuntada por valor-función.",
["qualifier-not-found"] = "Qualifier not found.",
["other entity"] = "Enlaces a elementos diferentes desactivado."
},
["somevalue"] = "''valor desconocido''",
["novalue"] = ""
}
-- Módulos y funciones utilizadas
local elementoTabla = require('Módulo:Tablas').elemento
--
-- Módulos en los que están definidos los tipos de datos más habituales si son
-- diferentes de Wikidata/Formatos
--
local modulosTipos = {
['altura'] = 'Módulo:Wikidata/Formato magnitud',
['área'] = 'Módulo:Wikidata/Formato magnitud',
['educado en'] = 'Módulo:Wikidata/Formatos educación',
['imagen'] = 'Módulo:Wikidata/Formato imagen',
['lugar'] = 'Módulo:Wikidata/Formato lugar',
['formatoLugar']= 'Módulo:Wikidata/Formato lugar',
['magnitud'] = 'Módulo:Wikidata/Formato magnitud',
['movimiento'] = 'Módulo:Wikidata/Formato movimiento',
['periodicidad']= 'Módulo:Wikidata/Formato magnitud',
['premio'] = 'Módulo:Wikidata/Formato premio',
}
--[[ =========================================================================
Función para pasar el frame cuando se usa en otros módulos.
========================================================================= `-- ]]
function p:setFrame(frame)
marco = frame
end
--[[ =========================================================================
Función para identificar el ítem correspondiente a la página o otro dado.
Esto último aún no funciona.
========================================================================= `-- ]]
function SelecionEntidadPorId( id )
if id and id ~= '' then
return mw.wikibase.getEntityObject( id )
else
return mw.wikibase.getEntityObject()
end
end
--[[ =========================================================================
Función que identifica si el valor devuelto es un ítem o una propiedad
y en función de eso añade el prefijo correspondiente
========================================================================= `-- ]]
function SelecionEntidadPorValor( valor )
local prefijo = ''
if valor['entity-type'] == 'item' then
prefijo = 'q' -- Prefijo de ítem
elseif valor['entity-type'] == 'property' then
prefijo = 'p' -- Prefijo de propiedad
else
return formatoError( 'unknown-entity-type' )
end
return prefijo .. valor['numeric-id'] -- Se concatena el prefijo y el código numérico
end
--[[ =========================================================================
Función auxiliar para dar formato a los mensajes de error
========================================================================= `-- ]]
function formatoError( clave )
return '<span class="error">' .. avisos.errores[clave] .. '</span>'
end
--[[ =========================================================================
Función para determinar el rango
========================================================================= `-- ]]
function getRango(tablaDeclaraciones)
local rank = 'deprecated'
for indice, declaracion in pairs(tablaDeclaraciones) do
if declaracion.rank == 'preferred' then
return 'preferred'
elseif declaracion.rank == 'normal' then
rank = 'normal'
end
end
return rank
end
--[[ =========================================================================
Función para determinar la declaracion o declaraciones de mayor rango
========================================================================= `-- ]]
function filtrarDeclaracionPorRango(tablaDeclaraciones)
local rango = getRango(tablaDeclaraciones)
local tablaAuxiliar = tablaDeclaraciones
tablaDeclaraciones = {}
for indice, declaracion in pairs(tablaAuxiliar) do
if declaracion.rank == rango then
table.insert(tablaDeclaraciones, declaracion)
end
end
return tablaDeclaraciones
end
--[[ =========================================================================
Función para seleccionar el tipo de declaración: Referencia, valor principal
o calificador
========================================================================= `-- ]]
function seleccionDeclaracion(declaracion, opciones)
local fuente = {}
local propiedadFuente = {}
local calificador = opciones.formatoCalificador ~= '()' and opciones.calificador
if calificador ~= '' and calificador and declaracion['qualifiers'] then
if declaracion['qualifiers'][mw.ustring.upper(calificador)] then
return declaracion.qualifiers[mw.ustring.upper(calificador)][1] -- devuelve el calificador (solo devolverá el primer valor)
else
return "" --Para que no lance excepción si no existe el calificador
end
elseif opciones.dato == 'fuente' and declaracion['references'] then
fuente = declaracion.references[1]['snaks']
for k,v in pairs(fuente) do
propiedadFuente = k
end
return declaracion.references[1]['snaks'][propiedadFuente][1] -- devuelve la fuente (queda que se itinere la tabla)
elseif (calificador == '' or not calificador) and (opciones.dato ~= 'fuente') then
return declaracion.mainsnak -- devuelve el valor principal
else
return ''
end
end
--[[ =========================================================================
Función para recopilar las declaraciones
========================================================================= `-- ]]
function p.getDeclaraciones(entityId)
-- == Comprobamos que existe un ítem enlazado a la página en Wikidata ==
if not pcall (SelecionEntidadPorId, entityId ) then
return false
end
local entidad = SelecionEntidadPorId(entityId)
if not entidad then
return '' -- Si la página no está enlazada a un ítem no devuelve nada
end
-- == Comprobamos que el ítem tiene declaraciones (claims) ==
if not entidad.claims then
return '' -- Si el ítem no tiene declaraciones no devuelve nada
end
-- == Declaración de formato y concatenado limpio ==
return entidad.claims
end
--[[ =========================================================================
Función para crear la cadena que devolverá la declaración
========================================================================= `-- ]]
local function valinQualif(claim, qualifs)
local claimqualifs = claim.qualifiers
local i,qualif
local vals, vals1, datavalue, value
if not claimqualifs then
return nil
end
for i, qualif in pairs(qualifs) do
vals = claimqualifs[qualif]
if vals then
vals1 = vals[1]
if vals1 then
datavalue=vals1.datavalue
if datavalue then
value = datavalue.value
if value then
return value.time
end
end
end
end
end
end
function p.getPropiedad(opciones, declaracion)
local propiedad = {}
local tablaOrdenada = {}
if opciones.propiedad == 'precisión' or opciones.propiedad == 'latitud' or opciones.propiedad == 'longitud' then
propiedad = 'P625' -- Si damos el valor latitud, longitud o precisión equivaldrá a dar p625
else
propiedad = opciones.propiedad -- En el resto de casos se lee lo dado
end
if not propiedad then -- Comprobamos si existe la propiedad dada y en caso contrario se devuelve un error
return formatoError( 'property-param-not-provided' )
end
if declaracion then
tablaOrdenada = declaracion
elseif not p.getDeclaraciones(opciones.entityId) then
return formatoError( 'other entity' )
elseif p.getDeclaraciones(opciones.entityId)[mw.ustring.upper(propiedad)] then
tablaOrdenada = p.getDeclaraciones(opciones.entityId)[mw.ustring.upper(propiedad)]
else
return ''
end
-- Evitar que pete cuando se haga el find en opciones['formatoTexto'] si vale nil
if not opciones['formatoTexto'] then
opciones['formatoTexto'] = ''
end
--Dejar en su caso los valores de mayor rango
if (opciones.rangoMayor == 'sí') then
tablaOrdenada = filtrarDeclaracionPorRango(tablaOrdenada)
end
--Ordenar en su caso por fecha. Ver la función chronosort de :fr:Module:Wikidata/Récup
if opciones.ordenar == 'por fecha' then
require('Módulo:Tablas').ordenar(tablaOrdenada,
function(elemento1,elemento2)
local fecha1 = valinQualif(elemento1, datequalifiers) or '' -- elemento1.qualifiers.P580[1].datavalue.value.time or ''
local fecha2 = valinQualif(elemento2, datequalifiers) or '' -- elemento2.qualifiers.P580[1].datavalue.value.time or ''
return fecha1 < fecha2
end
)
end
if not tablaOrdenada[1] then
return
end
-- == Si solo se desea que devuelva un valor ==
-- Pendiente eliminar el parámetro y sustituirlo por un nuevo valor del parámetro lista=no que haría lo mismo que opciones.uno = sí
if opciones.uno == 'sí' then -- Para que devuelva el valor de índice 1
tablaOrdenada = {tablaOrdenada[1]}
elseif opciones.uno == 'último' then -- Para que devuelva la última entrada de la tabla
tablaOrdenada = {tablaOrdenada[#tablaOrdenada]}
end
-- == Creamos una tabla con los valores que devolverá ==
local formatoDeclaraciones = {}
local hayDeclaraciones
for indice, declaracion in pairs(tablaOrdenada) do
declaracionFormateada = p.formatoDeclaracion(declaracion, opciones)
if declaracionFormateada and declaracionFormateada ~= '' then
table.insert(formatoDeclaraciones, declaracionFormateada)
hayDeclaraciones = true
end
end
primera = true
if not hayDeclaraciones then
return
end
-- Aplicar el formato a la lista de valores según el tipo de lista de las
-- opciones
local listaDeclaraciones = mw.text.listToText( formatoDeclaraciones, '</li><li>', '</li><li>' )
-- Añadir en su caso un lápiz
if opciones.linkback == 'sí' then
listaDeclaraciones = p.addLinkback( listaDeclaraciones, opciones.entityId, opciones.propiedad )
end
if opciones['lista'] == 'no ordenada' then
return '<ul><li>' .. listaDeclaraciones .. '</li></ul>'
elseif opciones['lista'] == 'ordenada' then
return '<ol><li>' .. listaDeclaraciones .. '</li></ol>'
elseif opciones['lista'] == 'nobullet' then
return '<ul style="list-style-type:none;list-style-image:none;margin-left:0;"><li>' .. listaDeclaraciones .. '</li></ul>'
else
-- valores separados por coma o por el separador y la
-- conjunción de las opciones
local separador, conjuncion
if opciones['conjunción'] == 'null' then
conjuncion = nil
else
conjuncion = opciones['conjunción']
end
if opciones['separador'] == 'null' then
separador = nil
else
separador = opciones['separador']
end
if table.getn(formatoDeclaraciones) > 1 then
if not conjuncion then
conjuncion = 'y'
end
if marco and conjuncion == 'y' then
conjuncion = ' ' .. string.sub(marco:preprocess('{{y-e|{{Desvincular|' .. formatoDeclaraciones[#formatoDeclaraciones] .. '}}}}'), 1, 1) .. ' '
elseif conjuncion == 'y' or conjuncion == 'o' then
conjuncion = ' ' .. conjuncion .. ' '
end
end
-- Añadir en su caso un lápiz
if opciones.linkback == 'sí' then
return p.addLinkback(mw.text.listToText( formatoDeclaraciones, separador,conjuncion ), opciones.entityId, opciones.propiedad)
else
return mw.text.listToText( formatoDeclaraciones, separador, conjuncion )
end
end
end
-- Función que sirve para comprobar si una entidad tiene una propiedad con un
-- valor específico
-- Parámetros:
-- · entidad: tabla de la entidad de Wikidata
-- · propiedad: identificador de Wikidata para la propiedad
-- · valor: valor de la propiedad en Wikidata
function p.tieneValorPropiedad(entidad, propiedad, valor)
if entidad and entidad.claims and entidad.claims[propiedad] then
local mainsnak
for key,value in ipairs(entidad.claims[propiedad]) do
if value and value.mainsnak then
mainsnak = value.mainsnak
if mainsnak.datatype == 'wikibase-item' and
mainsnak.snaktype == 'value' and
mainsnak.datavalue.value.id == valor then
return true
end
end
end
end
return false
end
-- Función que sirve para devolver la leyenda (P2096) de una imagen (P18) en Wikidata en un determinado idioma
-- La función se llama así: {{#invoke:Wikidata |getLeyendaImagen | <PARÁMETRO> | lang=<ISO-639code> |id=<QID>}}
-- Devuelve PARÁMETRO, a menos que sea igual a "FETCH_WIKIDATA", del objeto QID (llamada que consume recursos)
-- Si se omite QID o está vacio, se utiliza el artículo actual (llamada que NO consume recursos)
-- Si se omite lang se utiliza por defecto el idioma local de la wiki, en caso contrario el idioma del código ISO-639
-- ISO-639 está documentado aquí: https://docs.oracle.com/cd/E13214_01/wli/docs92/xref/xqisocodes.html#wp1252447
-- El ranking es: 'preferred' > 'normal' y devuelve la etiqueta de la primera imágen con ranking 'preferred'
-- O la etiqueta de la primera imagen with ranking 'normal' si no hay ningún 'preferred'
-- Ranks: https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua
p.getLeyendaImagen = function(frame)
-- busca un un elemento concreto en Wikidata (QID), en caso contrario que sea nil
local id = frame.args.id
if id and (#id == 0) then
id = nil
end
-- busca el parámetro del idioma que debería contender un código ISO-639 de dos dígitos
-- si no se declara, toma por defecto el idioma local de la wiki (es)
local lang = frame.args.lang
if (not lang) or (#lang < 2) then
lang = mw.language.getContentLanguage().code
end
-- el primer parámetro sin nombrar es el parámetro local, si se declara
local input_parm = mw.text.trim(frame.args[1] or "")
if input_parm == "FETCH_WIKIDATA" or input_parm == "" or input_parm == nil then
local ent = mw.wikibase.getEntityObject(id)
local imgs
if ent and ent.claims then
imgs = ent.claims.P18
end
local imglbl
if imgs then
-- busca una imagen con ranking 'preferred'
for k1, v1 in pairs(imgs) do
if v1.rank == "preferred" and v1.qualifiers and v1.qualifiers.P2096 then
local imglbls = v1.qualifiers.P2096
for k2, v2 in pairs(imglbls) do
if v2.datavalue.value.language == lang then
imglbl = v2.datavalue.value.text
break
end
end
end
end
-- si no hay ninguna, busca una con ranking 'normal'
if (not imglbl) then
for k1, v1 in pairs(imgs) do
if v1.rank == "normal" and v1.qualifiers and v1.qualifiers.P2096 then
local imglbls = v1.qualifiers.P2096
for k2, v2 in pairs(imglbls) do
if v2.datavalue.value.language == lang then
imglbl = v2.datavalue.value.text
break
end
end
end
end
end
end
return imglbl
else
return input_parm
end
end
-- devuelve el ID de la página en Wikidata (Q...), o nada si la página no está conectada a Wikidata
function p.pageId(frame)
local entity = mw.wikibase.getEntityObject()
if not entity then return nil else return entity.id end
end
function p.categorizar(opciones, declaracion)
-- Evitar que pete cuando se haga el find en opciones['formatoTexto'] si vale nil
if not opciones['formatoTexto'] then
opciones['formatoTexto'] = ''
end
local categoriaOpciones=opciones['categoría']
if not categoriaOpciones then
return ''
end
opciones['enlace'] = 'no'
-- Crear una tabla con los valores de la propiedad.
local valoresDeclaracion = {}
if declaracion then
valoresDeclaracion = declaracion
elseif opciones.propiedad then
local propiedad = {}
if opciones.propiedad == 'precisión' or opciones.propiedad == 'latitud' or opciones.propiedad == 'longitud' then
propiedad = 'P625' -- Si damos el valor latitud, longitud o precisión equivaldrá a dar p625
else
propiedad = opciones.propiedad -- En el resto de casos se lee lo dado
end
if not p.getDeclaraciones(opciones.entityId) then
return formatoError( 'other entity' )
elseif p.getDeclaraciones(opciones.entityId)[mw.ustring.upper(propiedad)] then
valoresDeclaracion = p.getDeclaraciones(opciones.entityId)[mw.ustring.upper(propiedad)]
else
return ''
end
else
return ''
end
-- Creamos una tabla con cada categoría a partir de cada valor de la declaración
local categorias = {}
local hayCategorias
if type(categoriaOpciones) == 'string' then
local ModuloPaginas = require('Módulo:Páginas')
for indice, valor in pairs(valoresDeclaracion) do
valorFormateado = p.formatoDeclaracion(valor, opciones)
if valorFormateado ~= '' then
categoria = ModuloPaginas.existeCategoria(categoriaOpciones:gsub('$1',valorFormateado))
if categoria then
table.insert(categorias, categoria)
hayCategorias = true
end
end
end
elseif type(categoriaOpciones) == 'table' then
for indice, valor in pairs(valoresDeclaracion) do
categoria = categoriaOpciones[elementoTabla(valor, 'mainsnak', 'datavalue', 'value', 'numeric-id')]
if categoria then
table.insert(categorias, 'Categoría:' .. categoria)
hayCategorias = true
end
end
end
if hayCategorias then
return '[[' .. mw.text.listToText( categorias, ']][[',']][[') .. ']]'
end
return ''
end
--[[ =========================================================================
Función que comprueba si la página está enlazada a Wikidata
en caso de estarlo pasa el valor como a argumento a la función formatSnak()
========================================================================= `-- ]]
function p.formatoDeclaracion( declaracion, opciones)
if not declaracion.type or declaracion.type ~= 'statement' then -- Se comprueba que tiene valor de tipo y que este sea statement (declaración) lo cual pasa siempre que existe la propiedad
return formatoError( 'unknown-claim-type' ) -- Si no se cumple devuelve error
end
-- En el caso de que haya calificador se devuelve a la derecha del valor de la
-- declaración entre paréntesis.
local calificativo = opciones.calificativo or opciones.calificador
if calificativo and declaracion.qualifiers then
-- De momento los calificativos, normalmente años, no se enlazan
local opcionesCalificativo = {['formatoTexto']='', enlace='no', ['formatoFecha']='año'} -- Pendiente
local wValorCalificativo
local wValorCalificativoFormateado
local funcionCalificativo, mensajeError = obtenerFuncion(calificativo, opciones['módulo calificativo'])
if mensajeError then
return mensajeError
elseif funcionCalificativo then
-- Utilizar la función recibida sobre todos los calificativos
wValorCalificativo = declaracion.qualifiers
wValorCalificativoFormateado = funcionCalificativo(wValorCalificativo, opcionesCalificativo)
elseif opciones.formatoCalificador and opciones.formatoCalificador == '()' then
wValorCalificativo = declaracion.qualifiers[mw.ustring.upper(calificativo)]
if wValorCalificativo and wValorCalificativo[1] then
wValorCalificativoFormateado = p.formatoDato(wValorCalificativo[1], opcionesCalificativo)
end
elseif opciones.formatoCalificador and table.getn(mw.text.split(opciones.formatoCalificador, '%.')) == 2 then
moduloFormatoCalificador = mw.text.split(opciones.formatoCalificador, '%.')
formateado = require ('Módulo:' .. moduloFormatoCalificador[1])
if not formateado then
return formatoError( 'value-module-not-found' )
end
fun = formateado[moduloFormatoCalificador[2]]
if not fun then
return formatoError( 'value-function-not-found' )
end
if mw.ustring.find(opciones['formatoTexto'],'mayúscula', plain ) and
(primera or (opciones['separador'] and opciones['separador'] ~= 'null') or
(opciones['lista'] and opciones['lista'] ~= '')) then
opciones['mayúscula'] = 'sí'
primera = false
end
if mw.ustring.find(opciones['formatoTexto'],'cursivas', plain ) then
opcionesEntidad.cursivas = 'sí'
end
wValorCalificativoFormateado = fun( declaracion.qualifiers, opciones, marco)
--return require('Módulo:Tablas').tostring(declaracion)
else
-- Utilizar el primer valor del calificativo de la propiedad recibida
wValorCalificativo = declaracion.qualifiers[mw.ustring.upper(calificativo)]
if wValorCalificativo and wValorCalificativo[1] then
wValorCalificativoFormateado = p.formatoDato(wValorCalificativo[1], opcionesCalificativo)
end
end
if opciones.separadorcalificador then separador = opciones.separadorcalificador else separador = ' ' end
if wValorCalificativoFormateado then
datoFormateado = p.formatoDato(declaracion.mainsnak, opciones)
return (datoFormateado and datoFormateado .. ' <small>(' .. wValorCalificativoFormateado .. ')</small>') or nil
end
end
-- Si no hay calificativo.
return p.formatoDato(seleccionDeclaracion(declaracion, opciones), opciones, declaracion.qualifiers)
end
--[[ =========================================================================
Función que comprueba el tipo de dato (snaktype)
si es value pasa el valor como argumento a la función formatoValorDato()
========================================================================= `-- ]]
function p.formatoDato( dato, opciones, calificativos)
if not dato or dato == '' then
return ''
end
if dato.snaktype == 'somevalue' then
-- Fecha más temprana
if calificativos then
if calificativos['P1319'] and calificativos['P1319'][1] and
calificativos['P1319'][1].datavalue and
calificativos['P1319'][1].datavalue.type=='time' then
local opcionesFecha={['formatoFecha']=opciones['formatoFecha'],enlace=opciones.enlace}
return 'post. ' .. require('Módulo:Wikidata/Fecha').FormateaFechaHora(calificativos['P1319'][1].datavalue.value, opcionesFecha)
end
end
-- Si no tiene un calificativo válido
return avisos['somevalue'] -- Valor desconocido
elseif dato.snaktype == 'novalue' then
return avisos['novalue'] -- Sin valor
elseif dato.snaktype == 'value' then
return formatoValorDato( dato.datavalue, opciones, calificativos) -- Si tiene el tipo de dato se pasa el valor a la función formatDatavalue()
else
return formatoError( 'unknown-snak-type' ) -- Tipo de dato desconocido
end
end
--[[ =========================================================================
Función que establece el tipo de formato en función del tipo de valor
(valorDato.type) y en caso de solicitarse un formato complemetario asocia
el módulo donde se establece el formato y la función de este que lo establece
========================================================================= `-- ]]
function formatoValorDato( valorDato, opciones, calificativos)
local funcion, mensajeError = obtenerFuncion(opciones['valor-función'] or opciones['value-function'] or opciones['funcion'], opciones['valor-módulo'] or opciones['modulo'])
if mensajeError then
return mensajeError
elseif funcion then
local opcionesEntidad = {}
for k, v in pairs(opciones) do
opcionesEntidad[k] = v
end
if mw.ustring.find(opciones['formatoTexto'],'mayúscula', plain ) and
(primera or (opciones['separador'] and opciones['separador'] ~= 'null') or
(opciones['lista'] and opciones['lista'] ~= '')) then
opcionesEntidad['mayúscula'] = 'sí'
primera = false
end
if mw.ustring.find(opciones['formatoTexto'],'cursivas', plain ) then
opcionesEntidad.cursivas = 'sí'
end
return funcion(valorDato.value, opcionesEntidad, marco, calificativos)
end
-- == Formatos por defecto en función del tipo de valor ==
-- * Para tipo coordenadas cuando se da como valor de propiedad: latitud, longitud o precisión
if opciones.propiedad == 'latitud' then
return valorDato.value['latitude']
elseif opciones.propiedad == 'longitud' then
return valorDato.value['longitude']
elseif opciones.propiedad == 'precisión' then
return valorDato.value['precision']
-- * Con el resto de valores en propiedad
elseif valorDato.type == 'wikibase-entityid' then -- Tipo: Número de entidad que puede ser un ítem o propiedad
local opcionesEntidad = {}
if mw.ustring.find(opciones['formatoTexto'],'mayúscula', plain ) and
(primera or (opciones['separador'] and opciones['separador'] ~= 'null') or
(opciones['lista'] and opciones['lista'] ~= '')) then
opcionesEntidad['mayúscula'] = 'sí'
primera = false
end
opcionesEntidad.enlace = opciones.enlace
opcionesEntidad.etiqueta = opciones.etiqueta
opcionesEntidad['debeExistir'] = opciones['debeExistir']
if mw.ustring.find(opciones['formatoTexto'],'cursivas', plain ) then
opcionesEntidad.cursivas = 'sí'
end
return p.formatoIdEntidad( SelecionEntidadPorValor( valorDato.value ), opcionesEntidad)
elseif valorDato.type == 'string' then -- Tipo: Cadena de texto (string)
return valorDato.value
elseif valorDato.type == 'url' then --Tipo URL (dirección web)
return value.url
elseif valorDato.type == 'time' then -- Tipo: Fecha/hora
local opcionesFecha={['formatoFecha']=opciones['formatoFecha'],enlace=opciones.enlace}
if mw.ustring.find(opciones['formatoTexto'] or '','mayúscula', plain ) and primera then
opcionesFecha['mayúscula']='sí'
end
return require('Módulo:Wikidata/Fecha').FormateaFechaHora(valorDato.value, opcionesFecha, calificativos)
elseif valorDato.type == 'monolingualtext' then -- Tipo: monoligüe
if valorDato.value then
if opciones.idioma then
for k, v in pairs(valorDato) do
if v.language == opciones.idioma then
return v.text
end
end
else
return valorDato.value.text
end
else
return ''
end
elseif valorDato.type == 'quantity' then -- Tipo: Cantidad
return require('Módulo:Wikidata/Formatos').formatoUnidad(valorDato, opciones)
elseif valorDato.value['latitude'] and valorDato.value['longitude'] then -- Tipo: Coordenadas
local globo = require('Módulo:Wikidata/Globos')[valorDato.value.globe]
--Concatenamos los valores de latitud y longitud dentro de la plantilla Coord
if globo ~= 'earth' then
return marco:preprocess('{{coord|' .. valorDato.value['latitude'] .. '|' ..
valorDato.value['longitude'] .. '|globe:' .. globo .. '_type:' .. opciones.tipo .. '|display=' ..
opciones.display ..'|formato=' .. opciones.formato..'}}')
else
return marco:preprocess('{{coord|' .. valorDato.value['latitude'] .. '|' ..
valorDato.value['longitude'] .. '|type:' .. opciones.tipo .. '|display=' ..
opciones.display ..'|formato=' .. opciones.formato..'}}')
end
else
return formatoError( 'unknown-datavalue-type' ) -- Si no es de ninguno de estos tipos devolverá error valor desconocido
end
end
--[[ =========================================================================
Damos formato a los enlaces internos
========================================================================= `-- ]]
-- Opciones:
-- - enlace: Valores posibles 'sí' o 'no'
-- - mayúscula: Valores posibles 'sí' o 'no'
-- - cursivas: Valores posibles 'sí' o 'no'
function p.formatoIdEntidad(idEntidad, opciones)
local enlace = mw.wikibase.sitelink(idEntidad)
local etiqueta = mw.wikibase.label(idEntidad)
return require('Módulo:Wikidata/Formatos').enlazar(enlace, etiqueta, idEntidad, opciones)
end
--[[ =========================================================================
Función principal
========================================================================= `-- ]]
function p.Wikidata( frame )
marco = frame
local args = frame.args
if args.valor == 'no' then
return
end
local parentArgs = frame:getParent().args
-- Copiar los argumentos
local argumentos = {}
for k, v in pairs(args) do
argumentos[k] = v
end
for k, v in pairs(parentArgs) do
if not argumentos[k] then
argumentos[k] = v
end
end
--if true then return require('Módulo:Tablas').tostring(argumentos) end
-- No generar el valor de Wikidata si se ha facilitado un valor local y
-- el valor local es prioritario.
local valorWikidata;
if (args.prioridad ~= 'sí' or (args.importar and args.importar == 'no')) and args.valor and args.valor ~= '' then
valorWikidata = '';
else
valorWikidata = p.getPropiedad(argumentos, nil);
end
local categorias = '';
local namespace = frame:preprocess('{{NAMESPACENUMBER}}');
if (namespace == '0' and (not args.categorias or args.categorias ~= 'no') and
args.propiedad and string.upper(args.propiedad) ~= 'P18' -- P18: imagen de Commons
and string.upper(args.propiedad) ~= 'P41' -- P41: imagen de la bandera
and string.upper(args.propiedad) ~= 'P94' -- P94: imagen del escudo de armas
and string.upper(args.propiedad) ~= 'P109' -- P109: firma de persona
and string.upper(args.propiedad) ~= 'P154') then -- P154: logotipo
if valorWikidata ~= '' and args.valor and args.valor ~= '' then
categorias = '[[Categoría:Wikipedia:Artículos con datos locales]]'
elseif valorWikidata and valorWikidata == '' and args.valor and args.valor ~= '' and
(not args.calificador or args.calificador == '') and
(not args.dato or args.dato == '' or args.dato ~= 'fuente')then
categorias = '[[Categoría:Wikipedia:Artículos con datos por trasladar a Wikidata]]'
end
end
if args.prioridad == 'sí' and valorWikidata ~= '' then -- Si se da el valor sí a prioridad tendrá preferencia el valor de Wikidata
if args.importar and args.importar == 'no' and args.valor and args.valor ~= '' then
return args.valor .. categorias
elseif valorWikidata then
return valorWikidata .. categorias -- valor que sustituye al valor de Wikidata parámetro 2
else
return categorias
end
elseif args.valor and args.valor ~= '' then
return args.valor .. categorias
elseif args.importar and args.importar == 'no' then
return ''
elseif valorWikidata then -- Si el valor es nil salta una excepcion al concatenar
return valorWikidata .. categorias
else
return ''
end
end
function obtenerFuncion(funcion, nombreModulo)
if not funcion then
return
elseif type(funcion) == 'function' then -- Uso desde LUA
return funcion
elseif funcion == '' or not nombreModulo or nombreModulo == '' then
return
else -- Uso desde una plantilla
local modulo
if not nombreModulo or nombreModulo == '' or nombreModulo == 'Wikidata/Formatos' then
modulo = require(modulosTipos[funcion] or 'Módulo:Wikidata/Formatos')
else
modulo = require ('Módulo:' .. nombreModulo)
end
if not modulo then
return nil, formatoError( 'value-module-not-found' )
elseif not modulo[funcion] then
return nil, formatoError( 'value-function-not-found' )
else
return modulo[funcion]
end
end
end
function p.addLinkback(valorPropiedad, idEntidad, idPropiedad)
local lidEntidad
if valorPropiedad and idPropiedad then
lidEntidad= (idEntidad ~='' and idEntidad) or mw.wikibase.getEntityIdForCurrentPage()
end
if lidEntidad then
return valorPropiedad .. '<span class=\"wikidata-link noprint\"> [[Archivo:Blue_pencil.svg|Ver y modificar los datos en Wikidata|10px|baseline|alt=Ver y modificar los datos en Wikidata|enlace=https://www.wikidata.org/wiki/' .. lidEntidad .. '?uselang=es#' .. idPropiedad ..
']]</span>'
else
return valorPropiedad
end
end
--------------------------------------------------------------------
-- A continuación, función p.claim y funciones locales necesarias --
-- Adaptado de https://ca.wikisource.org/wiki/Module:Wikidata --
--------------------------------------------------------------------
local wiki = {
langcode = mw.language.getContentLanguage().code
}
local _ -- variable for unused returned values, avoiding globals
-- Table of language codes: requested or default and its fallbacks
local function findLang(langcode)
if mw.language.isKnownLanguageTag(langcode or '') == false then
local cframe = mw.getCurrentFrame()
local pframe = cframe:getParent()
langcode = pframe and pframe.args.lang
if mw.language.isKnownLanguageTag(langcode or '') == false then
if not mw.title.getCurrentTitle().isContentPage then
langcode = cframe:preprocess('{{int:lang}}')
end
if mw.language.isKnownLanguageTag(langcode or '') == false then
langcode = wiki.langcode
end
end
end
local languages = mw.language.getFallbacksFor(langcode)
table.insert(languages, 1, langcode)
if langcode == wiki.langcode then
for _, l in ipairs({}) do
table.insert(languages, l)
end
end
return languages
end
-- Argument is 'set' when it exists (not nil) or when it is not an empty string.
local function isSet(var)
return not (var == nil or (type(var) == 'string' and mw.text.trim(var) == ''))
end
-- get safely a serialized snak
local function getSnak(statement, snaks)
local ret = statement
for i, v in ipairs(snaks) do
if not ret then return end
ret = ret[v]
end
return ret
end
-- mw.wikibase.getLabelWithLang or getLabelByLang with a table of languages
local function getLabelByLangs(id, languages)
local label
local lang
for _, l in ipairs(languages) do
if l == wiki.langcode then
-- using getLabelWithLang when possible instead of getLabelByLang
label, l = mw.wikibase.getLabelWithLang(id)
else
label = mw.wikibase.getLabelByLang(id, l)
end
if label then
lang = l
break
end
end
return label, lang
end
-- format data value wikibase-entityid: types wikibase-item, wikibase-property
local function printDatatypeEntity(data, parameters)
local entity_id = data['id']
if parameters.formatting == 'raw' then
return entity_id, entity_id
end
local label, lang = getLabelByLangs(entity_id, parameters.lang)
local sitelink = mw.wikibase.getSitelink(entity_id)
local labelcase = label or sitelink
local entity_page = 'Special:EntityPage/' .. entity_id
local ret1
if parameters.formatting == 'label' then
ret1 = labelcase or entity_id
else
if sitelink then
ret1 = '[[' .. sitelink .. '|' .. labelcase .. ']]'
elseif label and string.match(parameter or '', 'internallink$') and not mw.wikibase.getEntityIdForTitle(label) then
ret1 = '[[' .. label .. '|' .. labelcase .. ']]'
else --si no existe la pág. en WS, crea enlace a WD
ret1 = '[[d:' .. entity_page .. '|<span style="color:#5f9cbb;">' .. (labelcase or entity_id) .. '</span>]]'
end
end
return ret1
end
local function getSnakValue(snak, parameters)
if snak.snaktype == 'value' then
-- see Special:ListDatatypes
if snak.datatype == 'wikibase-item' or snak.datatype == 'wikibase-property' then
return printDatatypeEntity(snak.datavalue.value, parameters)
end
end
return mw.wikibase.renderSnak(snak)
end
local function getQualifierSnak(claim, qualifierId, parameters)
-- a "snak" is Wikidata terminology for a typed key/value pair
-- a claim consists of a main snak holding the main information of this claim,
-- as well as a list of attribute snaks and a list of references snaks
if qualifierId then
-- search the attribute snak with the given qualifier as key
if claim.qualifiers then
local qualifier = claim.qualifiers[qualifierId]
if qualifier then
if qualifier[1].datatype == "monolingualtext" then
-- iterate over monolingualtext qualifiers to get local language
for idx in pairs(qualifier) do
if getSnak(qualifier[idx], {"datavalue", "value", "language"}) == parameters.lang[1] then
return qualifier[idx]
end
end
elseif parameters.list then
return qualifier
else
return qualifier[1]
end
end
end
return nil, formatoError("qualifier-not-found")
else
return claim.mainsnak
end
end
local function getValueOfClaim(claim, qualifierId, parameters)
local snak, error = getQualifierSnak(claim, qualifierId, parameters)
if not snak then
return nil, nil, error
elseif snak[1] then -- a multi qualifier
local result = {}
for idx in pairs(snak) do
result[#result + 1] = getSnakValue(snak[idx], parameters)
end
return mw.text.listToText(result), nil
else -- a property or a qualifier (lo habitual)
return getSnakValue(snak, parameters)
end
end
local function getEntityId(args, pargs, unnamed)
pargs = pargs or {}
local id = args.item or args.from or (unnamed and mw.text.trim(args[1] or '') or nil)
if not isSet(id) then
id = pargs.item or pargs.from or (unnamed and mw.text.trim(pargs[1] or '') or nil)
end
if not isSet(id) then
id = mw.wikibase.getEntityIdForCurrentPage()
end
return id
end
local function getArg(value, default, aliases)
if type(value) == 'boolean' then return value
elseif value == "false" or value == "no" then return false
elseif value == "true" or value == "yes" then return true
elseif value and aliases and aliases[value] then return aliases[value]
elseif isSet(value) then return value
elseif default then return default
else return nil
end
end
-- Main function claim ---------------------------------------------
-- on debug console use: =p.claim{item="Q...", property="P...", ...}
function p.claim(frame)
local args = frame.args or frame -- via invoke or require
local pargs = frame.args and frame:getParent().args or {}
-- arguments
local parameters = {}
parameters.id = getEntityId(args, pargs)
if parameters.id == nil then return end
parameters.property = string.upper(args.property or "")
local qualifierId = {}
qualifierId[1] = getArg(string.upper(args.qualifier or ""))
local i = 2
while isSet(args["qualifier" .. i]) do
qualifierId[i] = string.upper(args["qualifier" .. i])
i = i + 1
end
parameters.formatting = getArg(args.formatting)
parameters.list = getArg(args.list, true, {firstrank='bestrank'})
local default = args.default
parameters.lang = findLang(args.lang)
-- fetch property
local claims = {}
claims = mw.wikibase.getBestStatements(parameters.id, parameters.property)
if #claims == 0 then
return default
end
-- defaults for table
local preformat, postformat = "", ""
-- get initial sort indices
local sortindices = {}
for idx in pairs(claims) do
sortindices[#sortindices + 1] = idx
end
local result
if parameters.list then
parameters.separator = mw.message.new('Comma-separator'):inLanguage(parameters.lang[1]):plain()
parameters.conjunction = (mw.message.new('And'):inLanguage(parameters.lang[1]):plain() .. mw.message.new('Word-separator'):inLanguage(parameters.lang[1]):plain())
-- iterate over all elements and return their value (if existing)
local value
result = {}
local values = {}
for idx in pairs(claims) do
local claim = claims[sortindices[idx]]
value = getValueOfClaim(claim, qualifierId[1], parameters)
values[#values + 1] = {}
if value then
values[#values]["col0"] = value
result[#values] = value
end
end
result = preformat .. mw.text.listToText(result, parameters.separator, parameters.conjunction) .. postformat
else
-- return first element
local claim = claims[sortindices[1]]
result = getValueOfClaim(claim, qualifierId[1], parameters)
end
if not isSet(result) then
result = default
end
return result or ''
end
--------------------------------------------------------------------------------
-- Get an Item based on what's passed in the 'wikidata' or 'page' parameters of
-- the args, or the current page's ID otherwise.
local function getItem( args )
local id = nil
-- If args is a table with an appropriate element, use it.
if type( args ) == 'table' then
if args.wikidata ~= '' and args.wikidata ~= nil then
id = args.wikidata
elseif args.wikidata_id ~= '' and args.wikidata_id ~= nil then
id = args.wikidata_id
elseif args.page ~= '' and args.page ~= nil then
local title = mw.title.new( args.page )
id = mw.wikibase.getEntityIdForTitle( title.nsText .. title.text )
-- If no entity for this page, maybe it's a subpage and we should look for the root page's entity.
if id == nil then
id = mw.wikibase.getEntityIdForTitle( title.nsText .. title.rootText )
end
end
end
if type( args ) == 'string' and args ~= '' then
id = args
end
return mw.wikibase.getEntity( id )
end
--------------------------------------------------------------------------------
-- Exported method. Get wikitext for displaying an edition's badges from Wikidata.
-- Test: =p.badge({args={qid='Q30097675'}})
function p.badge( frame )
local args = frame.args or frame -- via invoke or require
local item = getItem( args ) --por defecto, id de la página
local badges = {}
if args.qid ~= nil then --pero si pasamos un qid, id pasado
item = mw.wikibase.getEntity(args.qid)
end
local status = args.ws
-- status en el índice a badge
if status == 'C' or status == 'P' then
status = "Q20748091"
elseif status == 'V' then
status = "Q20748092"
elseif status == 'T' then
status = "Q20748093"
elseif status == 'E' or status == 'L' then
status = "Q20748094"
end
if not ( item and item.sitelinks and item.sitelinks.eswikisource and #item.sitelinks.eswikisource.badges > 0) and not (status) then
return ''
end
-- alguno con más prioridad que el otro? TODO: hacer algo en caso de discrepancia
local badges = {}
if status then
badges = {status}
end
if ( item and item.sitelinks and item.sitelinks.eswikisource and #item.sitelinks.eswikisource.badges > 0) then
badges = {unpack(badges), unpack(item.sitelinks.eswikisource.badges)}
end
local out = ''
for _, badge in pairs( badges ) do
local badgeOut = ''
local badgeItem = mw.wikibase.getEntity( badge )
local wikisourceBadgeClass = 'Q75042035'
local badgeName = ''
if badgeItem.claims.P31[1].mainsnak.datavalue.value.id == wikisourceBadgeClass and badgeItem.claims.P18 ~= nil then
local imageName = badgeItem.claims.P18[1].mainsnak.datavalue.value
if mw.wikibase.getLabel( badge ) ~= nil then
badgeName = mw.wikibase.getLabel( badge )
end
-- TODO: Crear una página de ayuda apropiada para el nivel de los *textos*
badgeOut = '<span class="indicator-badge">[[File:' .. imageName .. '|16px|link=Ayuda:Nivel de las páginas|' .. badgeName .. ']]</span>'
if args.indicator ~= nil then
badgeOut = '<indicator name="wikisource-badge-' .. badgeName .. '">' .. badgeOut .. '</indicator>'
end
--[=[if args.category ~= nil and badgeItem.claims.P910 ~= nil then
local categoryQid = badgeItem.claims.P910[1].mainsnak.datavalue.value.id
local category = mw.wikibase.getEntity( categoryQid )
badgeOut = badgeOut .. '[[' .. category.sitelinks.enwikisource.title .. ']]'
end ]=]--
out = out .. badgeOut
end
end
return mw.getCurrentFrame():preprocess(out)
end
return p