Módulo:Wikidata
Uso[editar código]
Este módulo es un proyecto de declaración para la herramienta de formato Wikidata
Tiene las funciones Wikidata, getDeclaraciones, getPropiedad y setFrame.
Función Wikidata[editar código]
Permite instrucción de formato(s) para una propiedad específica del tema relacionado con la página actual (no podemos acceder a los otros ítems).
Parámetros[editar código]
propiedad
La identificación de la propiedad como "p18". Necesario .
valor
Si se da el valor anula el valor de Wikidata.
prioridad
Si se da prioridad = sí
tendrá prioridad el valor de Wikidata que el valor que se de al parámetro valor
debeExistir
Si se informa con "sí" no se recuperan las entidades de Wikidata sin un enlace a un artículo de Wikipedia.
enlace
Puede tomar los valores enlace = sí
o enlace = no
.
- Si se da
enlace = no
aparecerá solamente la etiqueta del valor sin enlace interno. - Si se utiliza
enlace = sí
se mostrará un enlace a la correspondiente página de la Wikipedia definida en Wikidata si existe, si no se enlazará a la página con nombre igual a la etiqueta de Wikidata (si no existe un artículo con ese nombre) y si no se mostrará un enlace al elemento de Wikidata.
formatoTexto
Si se da formatoTexto = mayúscula
o cursiva
o mayúscula cursiva
(da igual el orden)
- Con el valor
mayúscula
:
la primera letra de la propiedad se pondrá en mayúsculas. Cuando no se da el valor al parámetro separador y por consiguiente los valores aparecen separados por una coma a excepción de último que se separa por una conjunción por defecto y, solo se pondra en mayúscula la inicial del primer valor. En caso de que se dé valor al parámetro enlace todos los valores apareceran con la inicial en mayúscula.
- Con el valor
cursiva
:
el texto de la propiedad se pondrá en cursivas.
formatoFecha
Los valores posibles son:
Parámetros para listas[editar código]
lista
(opcional): tipo de lista. Los valores posibles son:
=no
(por implementar): Solo se devuelve el primer elemento de Wikidata. De momento puede utilizarse el parámetrouno=sí
. Por ejemplo, en el artículo de España, si se escribe {{#invoke:Wikidata|Wikidata|propiedad=p37|uno=sí}} se generaría "Error de Lua en la línea 935: attempt to index field 'wikibase' (a nil value).".=ordenada
: Se devuelve una lista ordenada o numerada. Por ejemplo, en el artículo de España, si se escribe{{#invoke:Wikidata|Wikidata|propiedad=p37|lista=ordenada}}
se generaría:
- Error de Lua en la línea 935: attempt to index field 'wikibase' (a nil value).
=no ordenada
: Se devuelve una lista no ordenada o con viñetas. Por ejemplo, en el artículo de España, si se escribe{{#invoke:Wikidata|Wikidata|propiedad=p37|lista=no ordenada}}
se generaría:
- Error de Lua en la línea 935: attempt to index field 'wikibase' (a nil value).
- Si no se informa el tipo de lista se devuelve una lista de los elementos separados por coma. Por ejemplo, si se escribe
{{#invoke:Wikidata|Wikidata|propiedad=p37}}
se generaría "Error de Lua en la línea 935: attempt to index field 'wikibase' (a nil value)."
- En este último caso se pueden utilizar los parámetros
separador
yconjunción
que permiten separar los primeros valores y el último valor de una propiedad. Si no se especifica se toma por defecto como separador una coma y como conjunción "y" respectivamente. Por ejemplo, en el artículo de España, si se escribe{{#invoke:Wikidata|Wikidata|propiedad=p37|separador=/|conjunción=/}}
se mostraría "Error de Lua en la línea 935: attempt to index field 'wikibase' (a nil value).".
Funciones específicas para el formato[editar código]
valor-función
Nombre de la función Lua que se llama para dar formato al valor. La función acepta como argumentos las siguientes tablas Lua:
- valor: datos obtenidos de Wikidata para la propiedad. El único argumento obligatorio al llamar a la función
- opciones: argumentos con los que se accede a la plantilla
{{propiedad}}
o en el tipo de dato específico - marco o frame:
- calificativos: calificativos de la propiedad en Wikidata
valor-módulo
Nombre del módulo donde está definida la función. Si no se especifica el módulo se intentará buscar la función en el módulo:Wikidata/Formatos y si no se buscará en el módulo definido en la tabla modulosTipos del módulo Wikidata. Algunas de las funciones permitidas son:
Valores devueltos[editar código]
Devuelve la declaración formateada de acuerdo a las opciones.
Función getDeclaraciones[editar código]
Para ser usado en otro módulos.
Valores devueltos[editar código]
Devuelve una tabla con todas las declaraciones del elemento
Función getPropiedad[editar código]
Para ser usado en otros módulos.
Parámetros[editar código]
declaraciones
Una tabla de declaraciones
opciones
Una tabla con las opciones. los elementos de la tabla son los parámetros de la función Wikidata.
Valores devueltos[editar código]
Devuelve la declaración formateada de acuerdo a las opciones.
Función setFrame[editar código]
Para pasar el frame desde otro módulo. Es necesario poner esta función cuando se usa la anterior en casos en que haya que expandir wikitexto como por ejemplo con las coordenadas o los formatos de banderas.
Parámetros[editar código]
frame
Una tabla/objeto que se pasa desde la invocación del módulo.
Valores devueltos[editar código]
Ninguno.
Función addLinkback(texto, identificador de la entidad, identificador de la propiedad)[editar código]
La función añade al texto recibido la imagen de un lápiz que enlaza a la propiedad de la entidad en Wikidata.
Valores devueltos[editar código]
--[[*********************************************************************************
* 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: 30 de junio de 2021.
*
* 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 = mw.loadData('Módulo:Wikidata/mensajes')
-- 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 = mw.loadData('Módulo:Wikidata/modulosTipos')
local modulosTiposComplejos = {
['nacionalidad'] = 'Módulo:Wikidata/Formatos país',
}
--[[ =========================================================================
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 p.filtrarDeclaracionPorRango(tablaDeclaraciones)
local rango = getRango(tablaDeclaraciones)
local tablaAuxiliar = tablaDeclaraciones
tablaDeclaraciones = {}
if rango == 'deprecated' then
return {}
end
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, datatype
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
datatype = datavalue.type
value = datavalue.value
if datatype == 'time' and value then
return value.time
elseif datatype == 'string' and value then
return value
end
end
end
end
end
end
function p.getPropiedad(opciones, declaracion)
local propiedad = {}
-- Resolver alias de propiedad
if opciones.propiedad == 'precisión' or opciones.propiedad == 'latitud' or opciones.propiedad == 'longitud' then --latitud, longitud o precisión
propiedad = '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
local tablaOrdenada
if declaracion then
tablaOrdenada = declaracion
elseif mw.wikibase.isValidEntityId(tostring(opciones.entityId)) and mw.wikibase.isValidEntityId(tostring(propiedad)) then
tablaOrdenada = mw.wikibase.getAllStatements( opciones.entityId, mw.ustring.upper(propiedad) )
if not tablaOrdenada[1] then return '' end
else
return ''
end
-- Función que separa la cadena de texto 'inputstr' utilizando un separador 'sep'
function split(inputstr, sep)
sep=sep or '%s'
local t={}
for field,s in string.gmatch(inputstr, "([^"..sep.."]*)("..sep.."?)") do
table.insert(t,field)
if s=="" then
return t
end
end
end
tablaOrdenada = p.filtroDesconocidos(tablaOrdenada)
-- Aplicar filtro de calificador
if (opciones.filtroCalificador ~= nil and opciones.filtroCalificador ~= '') then
local opts = split(opciones.filtroCalificador, ';')
local negative = false
if (#opts > 2) then
if (opts[3]=='n') then
negative = true
elseif (opts[3]=='p') then
negative = false
end
end
tablaOrdenada = p.filtroCalificadores(tablaOrdenada, opts[1], split(opts[2], ','), negative)
end
-- Aplicar filtro de valor
if (opciones.filtroValor ~= nil and opciones.filtroValor ~= '') then
local opts = split(opciones.filtroValor, ';')
local negative = false
if (#opts > 1) then
if (opts[2]=='n') then
negative = true
elseif (opts[2]=='p') then
negative = false
end
end
tablaOrdenada = p.filtroValores(tablaOrdenada, split(opts[1], ','), negative)
end
-- Aplicar función de formato
local modulo, funcion
funcion = opciones['valor-función'] or opciones['value-function'] or opciones['funcion']
if funcion then
modulo = modulosTiposComplejos[funcion]
if modulo then
return require(modulo)[funcion](tablaOrdenada, opciones)
end
end
-- Evitar que pete cuando se haga el find en opciones['formatoTexto'] si vale nil
if not opciones['formatoTexto'] then
opciones['formatoTexto'] = ''
end
-- Aplicar filtro de mayor rango
if (opciones.rangoMayor == 'sí') then
tablaOrdenada = p.filtrarDeclaracionPorRango(tablaOrdenada)
end
-- Ordenarsegún el calificador "orden dentro de la serie"
if opciones.ordenar == 'sí' then
require('Módulo:Tablas').ordenar(tablaOrdenada,
function(elemento1,elemento2)
local orden1 = valinQualif(elemento1, { 'P1545' }) or '' -- elemento1.qualifiers.P1545[1].datavalue.value or ''
local orden2 = valinQualif(elemento2, { 'P1545' }) or '' -- elemento2.qualifiers.P1545[1].datavalue.value or ''
return orden1 < orden2
end
)
end
--Ordenar según la fecha. [Véase 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
-- Si después de todo no queda nada en la tabla retornar
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
return p.formatoLista(formatoDeclaraciones, opciones)
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
-- Función que devuelve el valor de entidad.claims[idPropiedad][ocurrencia].mainsnak.datavalue.value.text
-- con entidad.claims[idPropiedad][ocurrencia].mainsnak.datavalue.value.language = 'es'
-- Útil para obtener valores de propiedades de tipo monolingualtext
function p.getPropiedadEnEspanyol(idEntidad, idPropiedad)
-- Ver cs:Modul:Wikidata/item formatEntityWithGender
--
local entidad = mw.wikibase.getEntityObject(idEntidad)
if not entidad then
return
end
local declaracion = elementoTabla(entidad,'claims', idPropiedad)
if not declaracion then
return
end
local valor
for k,v in pairs(declaracion) do
valor = elementoTabla(v,'mainsnak', 'datavalue', 'value')
if valor and valor.language == 'es' then
return valor.text
end
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 filtra los valores de una propiedad y devuelve solo los que
tengan el calificador "qualifier" indicado con uno de los valores "values"
========================================================================= `-- ]]
function p.filtroCalificadores(t, qualifier, values, negativo)
local f = {} -- Tabla que se devolverá con el resultado del filtrado
for k,v in pairs(t) do
local counts = false
if(v["qualifiers"] ~= nil and v["qualifiers"][qualifier] ~= nil) then
for k2,v2 in pairs(v["qualifiers"][qualifier]) do
-- Comprobar si el identificador del valor del cualificador está en la lista
for k3,v3 in pairs(values) do
if (v2["datavalue"] ~= nil and v2["datavalue"]["value"] ~= nil and v2["datavalue"]["value"]["id"] ~= nil and v3 == v2["datavalue"]["value"]["id"])then
counts = true -- Si está marcar como true
end
end
end
end
if counts and not negativo then -- Si uno de los valores del cualificador dio true se inserta el elemento
table.insert(f, v)
elseif not counts and negativo then -- Si ninguno de los valores del cualificador dio true se inserta el elemento
table.insert(f, v)
end
end
return f
end
--[[ =========================================================================
Función que filtra los valores de una propiedad y devuelve solo los que
tengan uno de los valores "values"
========================================================================= `-- ]]
function p.filtroValores(t, values, negativo)
local f = {} -- Tabla que se devolverá con el resultado del filtrado
for k,v in pairs(t) do
local counts = false
if(v["mainsnak"]["datavalue"]["value"]["id"] ~= nil) then
for k2,v2 in pairs(values) do
if (v2 == v["mainsnak"]["datavalue"]["value"]["id"])then
counts = true -- Si está marcar como true
end
end
end
if counts and not negativo then -- Si uno de los valores del cualificador dio true se inserta el elemento
table.insert(f, v)
elseif not counts and negativo then -- Si ninguno de los valores del cualificador dio true se inserta el elemento
table.insert(f, v)
end
end
return f
end
--[[ =========================================================================
Función que filtra los valores de una propiedad y devuelve solo los que
tengan formatos de valor, omitiendo los de formato desconocido o sin valor
========================================================================= `-- ]]
function p.filtroDesconocidos(t)
for k,v in pairs(t) do
if(v["mainsnak"]["snaktype"] ~= "value") then
t[k] = nil
end
local qual = v["qualifiers"]
if(qual ~= nil) then
for qualk,qualv in pairs(qual) do
local prop = qualv
for propk,propv in pairs(prop) do
if(propv["snaktype"] ~= "value") then
prop[propk] = nil
-- same as: qual[prop] = nil
-- same as: t["qualifiers"][prop] = nil
end
end
if #prop == 0 then
prop = nil
qual[qualk] = nil
end
end
if #qual == 0 then
qual = nil
end
end
end
return t
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)
-- Si el parámetro especificado era "|calificador="" no devolver propiedad y paréntesis
if(opciones.calificador ~= nil and opciones.calificador ~= '') then
return wValorCalificativoFormateado
end
-- Si el parámetro especificado era "|calificativo="" devolver propiedad y calificativo entre paréntesis
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 ==
-- * Con el resto de valores en propiedad
if 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: monolingü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
-- * Para tipo coordenadas cuando se da como valor de propiedad: latitud, longitud o precisión
if TIPOLLP == 'latitud' then
return valorDato.value['latitude']
elseif TIPOLLP == 'longitud' then
return valorDato.value['longitude']
elseif TIPOLLP == 'precisión' then
return valorDato.value['precision']
else
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
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 )
TIPOLLP="" --Variable global para identificar los casos de latitud, longitud o precisión
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 argumentos[1]=='longitud' or argumentos[1]=='latitud' or argumentos[1]=='precisión' then
TIPOLLP=argumentos[1]
marco.args[argumentos[1]]='P625'
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 = nil;
else
if not mw.wikibase.isValidEntityId(tostring(argumentos.entityId)) then
argumentos.entityId = mw.wikibase.getEntityIdForCurrentPage() or nil
end
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 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 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 lapiz 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
function p.formatoLista(tabla, opciones)
if not tabla or not tabla[1] then
return
end
local tipo_lista = opciones.lista
local lapiz
if opciones.linkback == 'sí' and opciones.entityId and opciones.propiedad then
lapiz = '<span class=\"wikidata-link lapiz 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/' .. opciones.entityId .. '?uselang=es#' .. opciones.propiedad ..
']]</span>'
else
lapiz = ''
end
if not tabla[2] then
-- Si la tabla solo tiene un elemento devolverlo
return tabla[1] .. lapiz
end
if tipo_lista == 'no ordenada' or tipo_lista == 'ordenada' or tipo_lista == 'nobullet' then
local lista = mw.text.listToText( tabla, '</li><li>', '</li><li>' )
if tipo_lista == 'no ordenada' then
return '<ul><li>' .. lista .. lapiz .. '</li></ul>'
elseif tipo_lista == 'ordenada' then
return '<ol><li>' .. lista .. lapiz .. '</li></ol>'
else
return '<ul style="list-style-type:none;list-style-image:none;margin-left:0;padding-left:0"><li>' .. lista .. lapiz .. '</li></ul>'
end
else
local separadores = {
[''] = '',
[','] = ', ',
['null'] = ', ',
['no'] = ''
}
local conjunciones = {
[''] = '',
['y'] = ' y ',
['o'] = ' o ',
['null'] = ' y ',
['no'] = ''
}
local separador = opciones.separador
local conjuncion = opciones['conjunción']
if not separador then
separador = ', '
else
separador = separadores[separador] or separador
end
if not conjuncion then
conjuncion = ' y '
else
conjuncion = conjunciones[conjuncion] or conjuncion
end
if conjuncion == ' y ' and marco and tabla[2] then
conjuncion = ' ' .. marco:preprocess('{{y-e|{{Desvincular|' .. tabla[#tabla] .. '}}|sin texto}}') .. ' '
end
return mw.text.listToText( tabla, separador, conjuncion ) .. lapiz
end
end
-- Funciones existentes en otros módulos
function p.obtenerEtiquetaWikidata(entidad, fallback)
if not entidad then entidad = fallback end
if entidad and entidad.labels and entidad.labels.es then
return entidad.labels.es.value
end
end
function p.obtenerImagenWikidata(entidad, propiedad)
local imagen, valorImagen, piesDeImagen, k, pieDeImagen
if not entidad then
return
end
-- Obtener la primera imagen en Wikidata de la persona
local imagen = elementoTabla(entidad, 'claims', propiedad, 1)
--[[
-- Obtener el objeto de imagen, ya sea la primera, la última (WIP) o por fecha (WIP)
local imagen = (function()
local ImagenObj = elementoTabla(entidad, 'claims', idPropiedad)
if opciones.ordenar == 'por fecha' then
--
end
return elementoTabla(ImagenObj, 1)
end)()
--]]
if not imagen then
return
end
valorImagen = elementoTabla(imagen, 'mainsnak', 'datavalue', 'value')
piesDeImagen = elementoTabla(imagen, 'qualifiers', 'P2096')
-- Encontrar el pie en español
if piesDeImagen then
for k,pieDeImagen in pairs(piesDeImagen) do
if pieDeImagen.datavalue.value.language == 'es' then
return valorImagen, pieDeImagen.datavalue.value.text
end
end
end
-- Si no hay pie de imagen en español comprueba si hay fecha especificada para la imagen
piesDeImagen = elementoTabla(imagen, 'qualifiers', 'P585')
if piesDeImagen and piesDeImagen[1] then
return valorImagen, 'En ' .. require('Módulo:Wikidata/Fecha').FormateaFechaHora(piesDeImagen[1].datavalue.value, {['formatoFecha']='año',['enlace']='no'})
end
-- Sin pie de imagen en español
return valorImagen
end
function p.propiedad(entidad, idPropiedad, opciones)
if entidad and entidad.claims and entidad.claims[idPropiedad] then
if not opciones then
opciones = {['linkback']='sí'}
end
--[[
local ValorPosicional = (function()
if opciones['valor_posicional'] == 'último' then return -1 end
if type(opciones['valor_posicional']) == 'number' then return opciones['valor_posicional'] end
return 1
end)()
local ValorPosicionalCalif =(function()
if opciones['valor_posicional_calif'] == 'último' then return -1 end
if type(opciones['valor_posicional_calif']) == 'number' then return opciones['valor_posicional_calif'] end
return 1
end)()
local Calificador = opciones['calificador']
local Obj = (function()
local Obj = (function()
local Obj = elementoTabla(entidad, 'claims', idPropiedad)
if ValorPosicional == -1 then return elementoTabla(Obj, #Obj) end
return elementoTabla(Obj, ValorPosicional)
end)()
if Calificador then
Obj = (function()
local Obj = elementoTabla(Obj, 'qualifiers', Calificador)
if ValorPosicionalCalif == -1 then return elementoTabla(Obj, #Obj) end
return elementoTabla(Obj, ValorPosicionalCalif)
end)()
end
return Obj
end)()
Tipo = elementoTabla(Obj, 'datavalue', 'type')
-- Devolver el ID de la entidad, para propiedades de entidad
if opciones['formato'] == 'entidadID' then
return elementoTabla(Obj, 'datavalue', 'value', 'id')
end
-- Preparar para devolver el archivo más reciente en la propiedad. Buscar cómo hacerlo con los calificadores
if opciones['formato'] == 'archivo' then
if Calificador then return elementoTabla(Obj, 'datavalue', 'value') end
if not opciones['uno'] then opciones['uno'] = 'último' end
opciones['ordenar'] = 'por fecha'
end
-- Obtener la propiedad como cadena sin formato
if opciones['formato'] == 'cadena' then
opciones['linkback'] = 'no'
if Tipo == 'string' then
return elementoTabla(Obj, 'datavalue', 'value')
end
end
-- Devolver una cadena numérica correctamente formateada
if opciones['formato'] == 'número' then
if Tipo == 'quantity' then
return formatoNumero(elementoTabla(Obj, 'datavalue', 'value', 'amount'))
end
end
-- Devolver una cadena numérica con su unidad
if opciones['formato'] == 'unidad' then
if elementoTabla(entidad, 'claims', idPropiedad, 2, 'mainsnak', 'datavalue') then
return formatoNumero(elementoTabla(entidad, 'claims', idPropiedad, 1, 'mainsnak', 'datavalue', 'value', 'amount')) .. ' - ' .. numeroUnidad(elementoTabla(entidad, 'claims', idPropiedad, 2, 'mainsnak', 'datavalue'), opciones)
else
return numeroUnidad(elementoTabla(entidad, 'claims', idPropiedad, 1, 'mainsnak', 'datavalue'), opciones)
end
end
--]]
opciones.entityId = entidad.id
opciones.propiedad = idPropiedad
return p.getPropiedad(opciones, entidad.claims[idPropiedad])
end
end
function p.esUnValor(entidad, idPropiedad, idaBuscar)
if not entidad or not idPropiedad then
return false
end
local declaracion = elementoTabla(entidad, 'claims', idPropiedad)
local idBuscado
if not declaracion then
return false
end
for k,v in pairs(declaracion) do
idBuscado = elementoTabla(v,'mainsnak','datavalue','value','id')
if idBuscado == idaBuscar then
return true
end
end
return false
end
-- Obtener el objeto mw.language, para usar sus funciones en otros módulos
function p.language()
return es
end
return p