Módulo:Wikidata , la enciclopedia libre

Icono de documentación de módulo Documentación del módulo[ver] [editar] [historial] [purgar]

A continuación se muestra la documentación transcluida desde la subpágina /doc. [salta a la caja de código]


Uso

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

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

Parámetro Descripción
propiedad Propiedad de Wikidata a obtener
valor Si se da el valor anula el valor de Wikidata.
prioridad Si se indica |prioridad=sí entonces el valor de Wikidata (de existir) tendrá precedencia por sobre el valor local.
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:
  • =año: Se devuelve la fecha como una año. Por ejemplo 2014 o 1 a. C.
Listas
lista no (por implementar): Solo se devuelve el primer elemento de Wikidata. De momento puede utilizarse el parámetro uno=sí . Por ejemplo, en el artículo de España, si se escribe {{#invoke:Wikidata|Wikidata|propiedad=p37|uno=sí}} se generaría "español".
  • =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:
  1. español
  2. gallego
  3. euskera
  4. catalán
  5. occitano
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:
  1. español
  2. gallego
  3. euskera
  4. catalán
  5. occitano
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:
  • 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 "español, gallego, euskera, catalán y occitano"
En este último caso se pueden utilizar los parámetros separador y conjunció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 "español/gallego/euskera/catalán/occitano".
Formatos
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 existentes se muestran en la siguiente sección.

Módulos y funciones específicas para formatos

tipo de dato / valor-función Módulo de Wikidata en el que se encuentra definido Descripción Usado en Ejemplos de propiedades de Wikidata
altura Ver magnitud
área Ver magnitud
bandera Formatos país Se muestra la bandera y el nombre del país. {{Ficha de biblioteca}}, {{Ficha de templo}} país (P17)
formatoCargo Formatos Ficha de persona cargo ocupado (P39)
educado en Formatos educación Se muestra el lugar donde se ha educado y en su caso entre paréntesis el grado académico, especialidad y periodo. Ficha de persona educado en (P69)
formatoGenero Ficha de película Ficha de película género (P136)
formatoId Formatos {{Infobox animanga principal}} instancia de (P31)
imagen Formato imagen {{Ficha de programa de televisión}}, {{Ficha de entidad subnacional}}, {{Ficha de artista musical}} imagen (P18), logotipo (P154)
lugar Formato lugar Formato para lugares de la forma ciudad (unidad administrativa, país) Ficha de persona, {{Ficha de organización}}, {{Ficha de competición deportiva}}, {{Ficha de aeropuerto}} lugar de nacimiento (P19), lugar de fallecimiento (P20), ubicación de la sede (P159), ubicación (P276), situado en la entidad territorial administrativa (P131)
magnitud Formato magnitud Se muestra la magnitud junto a sus unidades y en su caso entre paréntesis el valor en el sistema internacional. Ficha de lugar ficticio, {{Ficha de entidad subnacional}}, {{Ficha de cuerpo de agua}}, {{Ficha de espacio natural}}{{Ficha de localidad de España}}, {{Ficha de faro}} altura (P2048)

masa (P2067)

superficie (P2046), superficie de cuenca hidrográfica (P2053)

alcance del faro (P2929)

movimiento Formato movimiento Formato para movimientos Ficha de persona movimiento (P135)
formatoNumero Formatos {{Ficha de epidemia}} número de casos (P1603)
nacionalidad Formatos país Ficha de persona país de nacionalidad (P27)
formatoObraAnyo Formatos Ficha de película

Ficha de libro

compuesto por (P527)
formatoObraAutor Formatos Ficha de película basado en (P144)
formatoOcupacionFemenino

formatoOcupacionMasculino

Ficha de persona Formato para ocupaciones de personas Ficha de persona ocupación (P106)
periodicidad Formato magnitud Se muestra la periodicidad (anual, mensual, quincenal, semanal, etc). {{Ficha de periódico}}, {{Ficha de revista}} periodicidad (P2896)
premio Formato premio Formato para premios de obras eliminando los literales de la forma " a ...", " a la ..." o " en la categoría ...". Ficha de libro premio recibido (P166)
formatoURL

url

Formatos Ficha de persona, {{Ficha de videojuego}} página web oficial (P856)

Valores devueltos

Devuelve la declaración formateada de acuerdo a las opciones.

Función getDeclaraciones

Para ser usado en otro módulos.

Valores devueltos

Devuelve una tabla con todas las declaraciones del elemento

Función getPropiedad

Para ser usado en otros módulos.

Parámetros

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

Devuelve la declaración formateada de acuerdo a las opciones.

Función setFrame

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

frame

Una tabla/objeto que se pasa desde la invocación del módulo.

Valores devueltos

Ninguno.

Función addLinkback(texto, identificador de la entidad, identificador de la propiedad)

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


Esta documentación está transcluida desde Módulo:Wikidata/doc.
Por favor, añade las categorías en la subpágina de documentación y los interwikis en Wikidata. Subpáginas de este módulo.

--[[********************************************************************************* 	* 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.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 .. '&nbsp;<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')) .. '&nbsp;-&nbsp;' .. 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