Ir al contenido

Módulo:Wikidata

De Wikinoticias, la fuente libre de noticias
[ver · editar · actualizar]
Documentación de módulo
Aún no se han escrito las instrucciones sobre este módulo. Añádelas.


--[[*********************************************************************************
    * 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: 6 de septiembre de 2014.
    *
    * Estado: En uso. 
    *
    *********************************************************************************`-- ]]
 
local p = {}
local datequalifiers = {'P585', 'P571', 'P580', 'P582'}
local es = mw.language.new('es')
local primera = true
local marco
 --[[ =========================================================================
            Mensajes de error
      ========================================================================= `-- ]]
 
local avisos = {
    ["errores"] = {
        ["property-param-not-provided"] = "Parámetro de la propiedad no proporcionado.",
        ["entity-not-found"] = "Entrada no encontrada.",
        ["unknown-claim-type"] = "Tipo de notificación desconocida.",
        ["unknown-snak-type"] = "Tipo de dato desconocido.",
        ["unknown-datavalue-type"] = "Formato de dato desconocido.",
        ["unknown-entity-type"] = "Tipo de entrada desconocido.",
        ["unknown-value-module"] = "Debe ajustar ambos parámetros de valor y el valor del módulo de funciones.",
        ["value-module-not-found"] = "No se ha encontrado el módulo apuntado por valor-módulo.",
        ["value-function-not-found"] = "No se ha encontrado la función apuntada por valor-función.",
        ["other entity"] = "Enlaces a elementos diferentes desactivado."
    },
    ["somevalue"] = "''valor desconocido''",
    ["novalue"] = ""
}
 --[[ =========================================================================
      Función para pasar el frame cuando se usa en otros módulos.      
     ========================================================================= `-- ]]
function p:setFrame(frame)
	marco = frame
end
 --[[ =========================================================================
      Función para identificar el ítem correspondiente a la página o otro dado.
              Esto último aún no funciona.      
     ========================================================================= `-- ]]


function SelecionEntidadPorId( id )
 
        if id and id ~= ''  then
            return mw.wikibase.getEntityObject( id )
        else 
            return mw.wikibase.getEntityObject()
        end 
 
end 
 
 
 --[[ =========================================================================
      Función que identifica si el valor devuelto es un ítem o una propiedad 
      y en función de eso añade el prefijo correspondiente     
     ========================================================================= `-- ]]
 
function SelecionEntidadPorValor( valor )
    local prefijo = ''
    if valor['entity-type'] == 'item' then
        prefijo = 'q' -- Prefijo de ítem
    elseif valor['entity-type'] == 'property' then
        prefijo = 'p' -- Prefijo de propiedad
    else
        return formatoError( 'unknown-entity-type' )
    end
    return prefijo .. valor['numeric-id'] -- Se concatena el prefijo y el código numérico
end
 
 --[[ =========================================================================
      Función auxiliar para dar formato a los mensajes de error      
     ========================================================================= `-- ]] 
 
function formatoError( clave )
    return '<span class="error">' .. avisos.errores[clave] .. '</span>'
end
 --[[ =========================================================================
      Función para determinar el rango     
     ========================================================================= `-- ]]
function getRango(tablaDeclaraciones)
 
	local rank = 'deprecated'
 
    for indice, declaracion in pairs(tablaDeclaraciones) do
        if declaracion.rank == 'preferred' then
            return 'preferred'
        elseif declaracion.rank == 'normal' then
            rank = 'normal'
        end 
    end
 
    return rank
end
 
 --[[ =========================================================================
      Función para determinar la declaracion o declaraciones de mayor rango    
     ========================================================================= `-- ]]
function filtrarDeclaracionPorRango(tablaDeclaraciones)
    local rango = getRango(tablaDeclaraciones)
    local tablaAuxiliar = tablaDeclaraciones
    tablaDeclaraciones = {}
 
    for indice, declaracion in pairs(tablaAuxiliar) do
        if declaracion.rank == rango then
            table.insert(tablaDeclaraciones, declaracion)
        end 
    end 
    return tablaDeclaraciones
end
 
 --[[ =========================================================================
      Función para seleccionar el tipo de declaración: Referencia, valor principal 
      o calificador      
     ========================================================================= `-- ]]
 
function seleccionDeclaracion(declaracion, opciones)
    local fuente = {}
    local propiedadFuente = {}
    local calificador = opciones.calificador
 
    if calificador ~= '' and calificador  and declaracion['qualifiers'] then
    	if declaracion['qualifiers'][mw.ustring.upper(calificador)] then
            return declaracion.qualifiers[mw.ustring.upper(calificador)][1] -- devuelve el calificador (solo devolverá el primer valor)
        else
        	return "" --Para que no lance excepción si no existe el calificador
        end
    elseif opciones.dato == 'fuente' and declaracion['references'] then
    	fuente = declaracion.references[1]['snaks']
        for k,v in pairs(fuente) do
            propiedadFuente = k
        end
        return declaracion.references[1]['snaks'][propiedadFuente][1]  -- devuelve la fuente (queda que se itinere la tabla)
    elseif (calificador == '' or not calificador) and (opciones.dato ~= 'fuente') then
        return declaracion.mainsnak -- devuelve el valor principal
    else 
    	return ''    
    end
end 
 
 --[[ =========================================================================
      Función para recopilar las declaraciones      
     ========================================================================= `-- ]] 
 
function p.getDeclaraciones(entityId)
 
 
    -- == Comprobamos que existe un ítem enlazado a la página en Wikidata ==
    if not pcall (SelecionEntidadPorId, entityId ) then 
    	return false
    end
    local entidad  = SelecionEntidadPorId(entityId) 
 
    if not entidad then
        return  '' -- Si la página no está enlazada a un ítem no devuelve nada
    end
 
    -- == Comprobamos que el ítem tiene declaraciones (claims) == 
 
    if not entidad.claims then
        return '' -- Si el ítem no tiene declaraciones no devuelve nada
    end
    -- == Declaración de formato y concatenado limpio ==
 
    return entidad.claims
end
 
 --[[ =========================================================================
      Función para  crear la cadena que devolverá la declaración     
     ========================================================================= `-- ]] 
     
local function valinQualif(claim, qualifs)
	local claimqualifs = claim.qualifiers
	local i,qualif
	local vals, vals1, datavalue, value
	
	if not claimqualifs then
		return nil
	end
	for i, qualif in pairs(qualifs) do
		vals = claimqualifs[qualif]
		if vals then
			vals1 = vals[1]
			if vals1 then
				datavalue=vals1.datavalue
				
				if datavalue then
					value = datavalue.value
					
					if value then
						return value.time
					end
				end
			end
		end
	end
end     
 
function p.getPropiedad(opciones, declaracion)
    local propiedad     = {}
    local tablaOrdenada = {}

    if opciones.propiedad == 'precisión' or opciones.propiedad == 'latitud' or opciones.propiedad == 'longitud'  then
        propiedad = 'P625' -- Si damos el valor latitud, longitud o precisión equivaldrá a dar p625
    else
        propiedad = opciones.propiedad -- En el resto de casos se lee lo dado
    end

    if not propiedad then -- Comprobamos si existe la propiedad dada y en caso contrario se devuelve un error
        return formatoError( 'property-param-not-provided' )
    end
 
    if declaracion then
        tablaOrdenada = declaracion
    elseif not p.getDeclaraciones(opciones.entityId) then
    	return formatoError( 'other entity' )
    elseif p.getDeclaraciones(opciones.entityId)[mw.ustring.upper(propiedad)] then 
    	tablaOrdenada = p.getDeclaraciones(opciones.entityId)[mw.ustring.upper(propiedad)]
    else
    	return ''
    end

	-- Evitar que pete cuando se haga el find en opciones['formatoTexto'] si vale nil
    if not opciones['formatoTexto'] then
    	opciones['formatoTexto'] = ''
    end

    --Dejar en su caso los valores de mayor rango
    if (opciones.rangoMayor == 'sí') then
        tablaOrdenada = filtrarDeclaracionPorRango(tablaOrdenada)
    end

    --Ordenar en su caso por fecha. Ver la función chronosort de :fr:Module:Wikidata/Récup
    if opciones.ordenar == 'por fecha' then
    	require('Módulo:Tablas').ordenar(tablaOrdenada, 
    		function(elemento1,elemento2) 
    			local fecha1 = valinQualif(elemento1, datequalifiers) or '' -- elemento1.qualifiers.P580[1].datavalue.value.time or ''
    			local fecha2 = valinQualif(elemento2, datequalifiers) or '' -- elemento2.qualifiers.P580[1].datavalue.value.time or ''
    			
    		    return fecha1 < fecha2
    	    end
    	 )
    end

    -- == Si solo se desea que devuelva un valor ==
    if opciones.uno == 'sí' then -- Para que devuelva el valor de índice 1
        tablaOrdenada = {tablaOrdenada[1]}
    end

-- == Creamos una tabla con los valores que devolverá ==
 
    local formatoDeclaraciones = {}
    local hayDeclaraciones
    
   
    if opciones.eliminaranexo or opciones.eliminar1 or opciones.eliminar2 or opciones.eliminar3 or opciones.eliminar4
    or opciones.eliminar5 or opciones.eliminar6 or opciones.eliminar7  or opciones.eliminar8 
    or opciones.eliminar9 or opciones.eliminar10 then
    	for indice, declaracion in pairs(tablaOrdenada) do
    		declaracionFormateada = formatoDeclaracion(declaracion, opciones)
    		if opciones.eliminar1 then comparador1=mw.ustring.find(declaracionFormateada,opciones.eliminar1) end
    		if opciones.eliminar2 then comparador2=mw.ustring.find(declaracionFormateada,opciones.eliminar2) end
    		if opciones.eliminar3 then comparador3=mw.ustring.find(declaracionFormateada,opciones.eliminar3) end
    		if opciones.eliminar4 then comparador4=mw.ustring.find(declaracionFormateada,opciones.eliminar4) end
    		if opciones.eliminar5 then comparador5=mw.ustring.find(declaracionFormateada,opciones.eliminar5) end
    		if opciones.eliminar6 then comparador6=mw.ustring.find(declaracionFormateada,opciones.eliminar6) end
    		if opciones.eliminar7 then comparador7=mw.ustring.find(declaracionFormateada,opciones.eliminar7) end
    		if opciones.eliminar8 then comparador8=mw.ustring.find(declaracionFormateada,opciones.eliminar8) end
    		if opciones.eliminar9 then comparador9=mw.ustring.find(declaracionFormateada,opciones.eliminar9) end
    		if opciones.eliminar10 then comparador10=mw.ustring.find(declaracionFormateada,opciones.eliminar10) end
    		if declaracionFormateada and declaracionFormateada ~= '' and comparador1==nil
    			and comparador2==nil and comparador3==nil and comparador4==nil and comparador4==nil
    			and comparador5==nil and comparador6==nil and comparador7==nil and comparador8==nil
    			and comparador9==nil and comparador10==nil then
    			if opciones.eliminaranexo then
    				if declaracionFormateada:sub(1,8)=='[[Anexo:' and string.find(declaracionFormateada,'|')==nil then
    					finenlace =string.find(declaracionFormateada,']')
    					declaracionFormateada= declaracionFormateada:sub(1,finenlace-1) ..'|'..declaracionFormateada:sub(9)
    				end
    			end
            	table.insert(formatoDeclaraciones, declaracionFormateada)
            	hayDeclaraciones = true
        	end    
    	end
	else	
		for indice, declaracion in pairs(tablaOrdenada) do
    		declaracionFormateada = formatoDeclaracion(declaracion, opciones)
    		if declaracionFormateada and declaracionFormateada ~= '' then
            	table.insert(formatoDeclaraciones, declaracionFormateada)
            	hayDeclaraciones = true
        	end    
    	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
    if opciones['lista'] == 'no ordenada' then
        return '<ul><li>' .. mw.text.listToText( formatoDeclaraciones, '</li><li>','</li><li>' ) .. '</li></ul>'
    elseif opciones['lista'] == 'ordenada' then
        return '<ol><li>' .. mw.text.listToText( formatoDeclaraciones, '</li><li>','</li><li>' ) .. '</li></ol>'            
    else
     	-- valores separados por coma o por el separador y la
      	-- conjunción de las opciones
       	local separador, conjuncion
        	
        if opciones['conjunción'] == 'null' then
            conjuncion = nil
        else
            conjuncion = opciones['conjunción'] 
        end
    
        if opciones['separador'] == 'null' then
            separador	= nil
        else
            separador = opciones['separador']
        end
        
        if (conjuncion == nil or conjuncion == 'y') and table.getn(formatoDeclaraciones) > 1 then
        	conjuncion = ' ' .. string.sub(marco:preprocess('{{y-e|{{desenlazar|' .. formatoDeclaraciones[#formatoDeclaraciones] .. '}}}}'), 1, 1) .. ' '
        elseif conjuncion ~= nil and conjuncion == 'o' and table.getn(formatoDeclaraciones) > 1 then
        	conjuncion = ' ' .. conjuncion .. ' '
        end
            
        return mw.text.listToText( formatoDeclaraciones, separador,conjuncion )
    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 elementoTabla = require('Módulo:Tablas').elemento
	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

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 
    
    -- == Si solo se desea que devuelva un valor ==
    --if opciones.uno == 'sí' then -- Para que devuelva el valor de índice 1
    --    return formatoDeclaracion( valoresDeclaracion[1],opciones)
    --end
    --if (opciones.rangoMayor == 'sí') then -- Para que devuelva los valores de mayor rango
     --   valoresDeclaracion = filtrarDeclaracionPorRango(valoresDeclaracion)
    --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 = 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[valor.mainsnak.datavalue.value['numeric-id']]
            
            if categoria then
                table.insert(categorias, 'Categoría:' .. categoria)
                hayCategorias = true
            end
        end
    end
    
    if hayCategorias then
        return '[[' .. mw.text.listToText( categorias, ']][[',']][[') .. ']]'
    end
    
    return ''
end
 
 --[[ =========================================================================
        Función que comprueba si la página está enlazada a  Wikidata
        en caso de estarlo pasa el valor como a argumento a la función formatSnak()   
     ========================================================================= `-- ]]
 
function 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
       
       if type(calificativo) == 'function' then
       	  -- Utilizar la función recibida sobre todos los calificativos
       	  wValorCalificativo           = declaracion.qualifiers
          wValorCalificativoFormateado = calificativo(wValorCalificativo, opcionesCalificativo)
       	elseif opciones.formatoCalificador and opciones.formatoCalificador == '()' then
			wValorCalificativo = declaracion.qualifiers[mw.ustring.upper(calificativo)]
	    	if wValorCalificativo and wValorCalificativo[1] then
	    		wValorCalificativoFormateado = p.formatoDato(wValorCalificativo[1], opcionesCalificativo)
	    	end
    	elseif opciones.formatoCalificador and table.getn(mw.text.split(opciones.formatoCalificador, '%.')) == 2 then
    		moduloFormatoCalificador = mw.text.split(opciones.formatoCalificador, '%.')
    		formateado = require ('Módulo:' .. moduloFormatoCalificador[1])
	        if not formateado then
	            return formatoError( 'value-module-not-found' )
	        end
	        fun = formateado[moduloFormatoCalificador[2]]
	        if not fun then
	            return formatoError( 'value-function-not-found' )
	        end
	        
	        if mw.ustring.find(opciones['formatoTexto'],'mayúscula', plain ) and 
		       (primera or (opciones['separador'] and opciones['separador'] ~= 'null') or 
		       	(opciones['lista'] and opciones['lista'] ~= '')) then
		      opciones['mayúscula'] = 'sí'
	              primera = false
		    end
		    
		    if mw.ustring.find(opciones['formatoTexto'],'cursivas', plain ) then
		    	opcionesEntidad.cursivas = 'sí'
		    end
	        
	        wValorCalificativoFormateado = fun( declaracion.qualifiers, opciones, marco)
	        --return require('Módulo:Tablas').tostring(declaracion)
	    else
       	  -- Utilizar el primer valor del calificativo de la propiedad recibida
       	  wValorCalificativo = declaracion.qualifiers[mw.ustring.upper(calificativo)]
       	  
       	  if wValorCalificativo and wValorCalificativo[1] then
            wValorCalificativoFormateado = p.formatoDato(wValorCalificativo[1], opcionesCalificativo)
	      end
	    end
		if opciones.separadorcalificador then separador = opciones.separadorcalificador else separador = ' ' end
    	if wValorCalificativoFormateado then
    		datoFormateado = p.formatoDato(declaracion.mainsnak, opciones)
    		return (datoFormateado and datoFormateado .. separador.. '&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)
	
	-- == Si se da el parámetro  valor-módulo y valor-función ==
	
	funcion = opciones['valor-función'] or opciones['value-function']
	if funcion and type(funcion) == 'function' then -- Uso desde LUA
	--  Ver un ejemplo en el módulo de Ficha de libro con el ISBN.
	    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 funcion(valorDato.value, opcionesEntidad, marco, calificativos)
    elseif (opciones['valor-módulo'] and opciones['valor-módulo'] ~= "" ) or (opciones['value-function'] and opciones['valor-function'] ~= "" ) then
        if not opciones['valor-módulo'] or not opciones['valor-función'] then
            return formatoError( 'unknown-value-module' )
        end
        local formateado = require ('Módulo:' .. opciones['valor-módulo'])
        if not formateado then
            return formatoError( 'value-module-not-found' )
        end
        local fun = formateado[opciones['valor-función']]
        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
        
        return fun( valorDato.value, opciones, marco)
    end
 
    -- == Formatos por defecto en función del tipo de valor ==
 
--          * Para tipo coordenadas cuando se da como valor de propiedad: latitud, longitud o precisión
 
    if opciones.propiedad == 'latitud' then 
        return valorDato.value['latitude']
    elseif opciones.propiedad == 'longitud' then
        return valorDato.value['longitude']
    elseif opciones.propiedad == 'precisión' then
        return valorDato.value['precision']
 
--           * Con el resto de valores en propiedad
 
    elseif valorDato.type == 'wikibase-entityid' then    -- Tipo: Número de entidad que puede ser un ítem o propiedad
	    local opcionesEntidad = {}
	    if mw.ustring.find(opciones['formatoTexto'],'mayúscula', plain ) and 
	       (primera or (opciones['separador'] and opciones['separador'] ~= 'null') or 
	       	(opciones['lista'] and opciones['lista'] ~= '')) then
	      opcionesEntidad['mayúscula'] = 'sí'
              primera = false
	    end
	    opcionesEntidad.enlace         = opciones.enlace
	    opcionesEntidad.etiqueta       = opciones.etiqueta
	    opcionesEntidad['debeExistir'] = opciones['debeExistir']
	    
	    if mw.ustring.find(opciones['formatoTexto'],'cursivas', plain ) then
	    	opcionesEntidad.cursivas = 'sí'
	    end
        return p.formatoIdEntidad( SelecionEntidadPorValor( valorDato.value ), opcionesEntidad)
    elseif valorDato.type == 'string' then               -- Tipo: Cadena de texto (string)
        return valorDato.value 
    elseif valorDato.type == 'url' then     --Tipo URL (dirección web)
	    return value.url
    elseif valorDato.type == 'time' then                 -- Tipo: Fecha/hora
        local opcionesFecha={['formatoFecha']=opciones['formatoFecha'],enlace=opciones.enlace}
       
        if mw.ustring.find(opciones['formatoTexto'] or '','mayúscula', plain ) and primera then
	        opcionesFecha['mayúscula']='sí'
        end
        
        return require('Módulo:Wikidata/Fecha').FormateaFechaHora(valorDato.value, opcionesFecha, calificativos)
    elseif valorDato.type == 'monolingualtext' then       -- Tipo: monoligüe
    	if valorDato.value then
            return valorDato.value.text
        else 
            return ''
        end
    elseif valorDato.type ==  'quantity' then            -- Tipo: Cantidad 
    	return require('Módulo:Wikidata/Formatos').formatoUnidad(valorDato, opciones)
    elseif  valorDato.value['latitude']  and valorDato.value['longitude'] then -- Tipo: Coordenadas
    	local globo = require('Módulo:Wikidata/Globos')[valorDato.value.globe]
 
--Concatenamos los valores de latitud y longitud dentro de la plantilla Coord
 
        if globo ~= 'earth' then
            return  marco:preprocess('{{coord|' .. valorDato.value['latitude'] .. '|' .. 
                   valorDato.value['longitude'] .. '|globe:' .. globo .. '_type:' .. opciones.tipo .. '|display=' .. 
                   opciones.display ..'|formato=' .. opciones.formato..'}}')
        else
        	return  marco:preprocess('{{coord|' .. valorDato.value['latitude'] .. '|' .. 
                   valorDato.value['longitude'] .. '|type:' .. opciones.tipo .. '|display=' .. 
                   opciones.display ..'|formato=' .. opciones.formato..'}}')
        end
 
    else
        return formatoError( 'unknown-datavalue-type' ) -- Si no es de ninguno de estos tipos devolverá error valor desconocido
    end
end
 
  --[[ =========================================================================
          Damos formato a los enlaces internos    
       ========================================================================= `-- ]]

-- Opciones:
--     - enlace:		Valores posibles 'sí' o 'no'
--     - mayúscula:		Valores posibles 'sí' o 'no'
--     - cursivas:		Valores posibles 'sí' o 'no'

function p.formatoIdEntidad(idEntidad, opciones)
    local enlace   = mw.wikibase.sitelink(idEntidad)
    local etiqueta = mw.wikibase.label(idEntidad)
	return require('Módulo:Wikidata/Formatos').enlazar(enlace, etiqueta, idEntidad, opciones)
end
 
 --[[ =========================================================================
        Función principal     
     ========================================================================= `-- ]]
 
function p.Wikidata( frame )
    marco = frame
    local args = frame.args
    local valorWikidata = p.getPropiedad( frame.args , nil)
 	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' and 
 			string.upper(args.propiedad) ~= 'P41' and string.upper(args.propiedad) ~= 'P94'
 			and string.upper(args.propiedad) ~= 'P109' and string.upper(args.propiedad) ~= 'P94'
 			and string.upper(args.propiedad) ~= 'P154') then
	 	if valorWikidata ~= '' and args.valor and args.valor ~= '' then
	 		categorias = '[[Categoría:Wikipedia:Artículos con datos locales]]'
	 	elseif valorWikidata and valorWikidata == '' and args.valor and args.valor ~= '' and 
	 		(not args.calificador or args.calificador == '') and 
	 		(not args.dato or args.dato == '' or args.dato ~= 'fuente')then
	 		categorias = '[[Categoría:Wikipedia:Artículos con datos por trasladar a Wikidata]]'
	 	end
	end
 
    if args.prioridad == 'sí' and valorWikidata  ~= '' then -- Si se da el valor sí a prioridad tendrá preferencia el valor de Wikidata 
    	if args.importar and args.importar == 'no' and args.valor and args.valor ~= '' then 
    		return args.valor .. categorias
    	elseif valorWikidata then
        	return valorWikidata .. categorias -- valor que sustituye al valor de Wikidata parámetro 2
        else
        	return categorias
        end
    elseif args.valor and args.valor ~= '' then 
         return args.valor .. categorias
    elseif args.importar and args.importar == 'no' then 
         return ''
    elseif valorWikidata then -- Si el valor es nil salta una excepcion al concatenar
        return valorWikidata .. categorias
    else
    	return ''
  end  
end
 
return p