Saltar ao contido

Módulo:Wikidata

Esta páxina está semiprotexida
Na Galipedia, a Wikipedia en galego.
Indicacións de uso do módulo

Uso

Este módulo é un proxecto de declaración para a ferramenta de formato Wikidata

Ten as funcións Wikidata, getDeclaraciones, getPropiedad e setFrame.

Función Wikidata

Permite consultar unha propiedade específica do tema relacionado coa páxina actual (non podemos acceder ós outros ítems) no servidor de Wikidata.

Parámetros

propiedad

A identificación da propiedade, por exemplo "p18". Necesario.

separador e conxunción

Texto utilizado para separar os primeiros valores e o último valor dunha propiedade. Se non se especifica tómase por defecto como separador unha coma e como conxunción "e" respectivamente.

Por exemplo, no artigo de España, se se escribe {{#invoke:Wikidata|Wikidata|propiedad=p37}} xeraríase "castelán, galego, aranés, éuscaro e catalán" mentres que se se escribe {{#invoke:Wikidata|Wikidata|propiedad=p37|separador=/|conjunción=/}} mostraríase "español/galego/aranés/éuscaro/catalán".

valor-módulo

Nome do módulo para chamar a formatar o valor

valor-función

Nome da función que valor-módulo chama para formatar o valor. Necesítanse dous parámetros: o valor e unha matriz que contén os parámetros pasados á función formatoDeclaraciones. Para ver exemplos consultar Módulo:Wikidata/Formatos.

valor

Se se da o valor anula o valor de Wikidata.

prioridad

Se se da prioridad = si terá máis prioridade o valor de Wikidata que o valor que se dea ó parámetro valor

debeExistir

Se se informa con "sí" non se recuperan as entidades de Wikidata sen unha ligazón a un artigo de Wikipedia.

enlace

Pode tomar os valores enlace = sí ou enlace = no.

  • Se se da enlace = no aparecerá soamente a etiqueta do valor sen ligazón interna.
  • Se se utiliza enlace = sí mostrarase unha ligazón á correspondente páxina da Wikipedia definida en Wikidata se existe, se non ligarase á páxina co nome igual á etiqueta de Wikidata (se non existe un artigo con ese nome) e se non mostrarase unha ligazón ó elemento de Wikidata.
formatoTexto

Se se da formatoTexto = mayúscula ou cursiva ou mayúscula cursiva (da igual a orde)

  • Co valor mayúscula:

a primeira letra da propiedade porase en maiúsculas. Cando non se da o valor ó parámetro separador e por conseguinte os valores aparecen separados por unha coma a excepción do último que se separa por unha conxunción por defecto e, só se porá en maiúscula a inicial do primeiro valor. En caso de que se dea valor ó parámetro ligazón todos os valores apareceran coa inicial en maiúscula.

  • Co valor cursiva:

o texto da propiedade porase en cursivas.

formatoFecha

Os valores posibles son:

  • =año: Devólvese a data como un ano. Por exemplo 2014 ou 1 a. C.

Valores devoltos

Devolve a declaración formatada de acordo ás opcións.

Función getDeclaraciones

Para ser usado noutros módulos.

Valores devoltos

Devolve unha táboa con todas as declaracións do elemento

Función getPropiedad

Para ser usado noutros módulos.

Parámetros

declaraciones

Unha táboa de declaracións

opciones

Unha táboa coas opcións. Os elementos da táboa son os parámetros da función Wikidata.

Valores devoltos

Devolve a declaración formatada de acordo ás opcións.

Función setFrame

Para pasar o frame desde outro módulo. É necesario poñer esta función cando se usa a anterior en casos en que haxa que expandir wikitexto como por exemplo coas coordenadas ou os formatos de bandeiras.

Parámetros

frame

Unha táboa/obxecto que se pasa desde a invocación do módulo.

Valores devoltos

Ningún.

Esta documentación está transcluída desde Módulo:Wikidata/uso. Os editores poden probar cambios no mesmo en Módulo:Wikidata/probas.
Por favor, engade as categorías na subpáxina de documentación e os interwikis no Wikidata. Ver as subpáxinas deste módulo.

--[[*********************************************************************************
    * Nome: Módulo:Wikidata
    *
    * Descrición: Este módulo devolve o valor ou valores con ou sen formato específico
    *             a unha propiedade de Wikidata.
    *
    * Data última revisión: 6 de setembro de 2014.
    *if
    * Estado: En uso.
    * Nota: Adaptado de es.wiki
    *********************************************************************************`-- ]]

local p = {}
local es = mw.language.new('gl')
local primera = true
local marco

 --[[ =========================================================================
            Mensaxes de erro
      ========================================================================= `-- ]]

local avisos = {
    ["errores"] = {
        ["property-param-not-provided"] = "Parámetro da propiedade non proporcionado.",
        ["entity-not-found"] = "Entrada non atopada.",
        ["unknown-claim-type"] = "Tipo de notificación descoñecida.",
        ["unknown-snak-type"] = "Tipo de dato descoñecido.",
        ["unknown-datavalue-type"] = "Formato de dato descoñecido.",
        ["unknown-entity-type"] = "Tipo de entrada descoñecida.",
        ["unknown-value-module"] = "Debe axustar ambos parámetros de valor e o valor do módulo de funcións.",
        ["value-module-not-found"] = "Non se atopou o módulo apuntado por valor-módulo.",
        ["value-function-not-found"] = "Non se atopou a función apuntada por valor-función.",
        ["other entity"] = "Ligazóns a elementos diferentes desactivado."
    },
    ["somevalue"] = "''valor descoñecido''",
    ["novalue"] = ""
}

local elementoTabla = require('Módulo:Táboas').elemento

-- returns the page id (Q...) of the current page or nothing of the page is not connected to Wikidata
-- Función copiada de Module:Wikidata de en.wiki devolve o identificador Q da páxina actual ou nada se a páxina non 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

-- Función copiada de Module:Wikidata de en.wiki
local function findClaims(entity, property)
	if not property or not entity or not entity.claims then return end

	if mw.ustring.match(property, "^P%d+$") then
		-- if the property is given by an id (P..) access the claim list by this id
		return entity.claims[property]
	else
		property = mw.wikibase.resolvePropertyId(property)
		if not property then return end

		return entity.claims[property]
	end
end

-- Función copiada de Module:Wikidata de en.wiki
function p.claim(frame)
	local property = frame.args[1] or ""
	local id = frame.args["id"]
	local qualifierId = frame.args["qualifier"]
	local parameter = frame.args["parameter"]
	local list = frame.args["list"]
	local references = frame.args["references"]
	local showerrors = frame.args["showerrors"]
	local default = frame.args["default"]
	if default then showerrors = nil end

	-- get wikidata entity
	local entity = mw.wikibase.getEntityObject(id)
	if not entity then
		if showerrors then return printError("entity-not-found") else return default end
	end
	-- fetch the first claim of satisfying the given property
	local claims = findClaims(entity, property)
	if not claims or not claims[1] then
		if showerrors then return printError("property-not-found") else return default end
	end

	-- get initial sort indices
	local sortindices = {}
	for idx in pairs(claims) do
		sortindices[#sortindices + 1] = idx
	end
	-- sort by claim rank
	local comparator = function(a, b)
		local rankmap = { deprecated = 2, normal = 1, preferred = 0 }
		local ranka = rankmap[claims[a].rank or "normal"] .. string.format("%08d", a)
		local rankb = rankmap[claims[b].rank or "normal"] .. string.format("%08d", b)
		return ranka < rankb
	end
	table.sort(sortindices, comparator)

	local result
	local error
	if list then
		local value
		-- iterate over all elements and return their value (if existing)
		result = {}
		for idx in pairs(claims) do
			local claim = claims[sortindices[idx]]
			value, error = getValueOfClaim(claim, qualifierId, parameter)
			if not value and showerrors then value = error end
			if value and references then value = value .. getReferences(frame, claim) end
			result[#result + 1] = value
		end
		result = table.concat(result, list)
	else
		-- return first element
		local claim = claims[sortindices[1]]
		result, error = getValueOfClaim(claim, qualifierId, parameter)
		if result and references then result = result .. getReferences(frame, claim) end
	end

	if result then return result else
		if showerrors then return error else return default end
	end
end


function p.traballoFemenino_wikidata(frame)
    marco = frame
    local args = frame.args
	-- Para las ocupaciones más frecuentes no se accederá a Wikidata
	local tablaOcupacionesFemeninas={
		['Q40348'   ] = 'abogada',
		['Q16631371'] = 'académica',
		['Q15253558'] = 'activista',
		['Q1476215' ] = 'activista por los derechos humanos',
		['Q33999'   ] = 'actriz',
		['Q10800557'] = 'actriz de cine',
		['Q11481802'] = 'actriz de doblaje',
		['Q948329'  ] = 'actriz de género',		
		['Q2259451' ] = 'actriz de teatro',
		['Q10798782'] = 'actriz de televisión',
		['Q2405480' ] = 'actriz de voz',
		['Q488111'  ] = 'actriz pornográfica',
		['Q10873124'] = 'ajedrecista',
		['Q4773904' ] = 'antropóloga',			
		['Q2478141' ] = 'aristócrata',		
		['Q42973'   ] = 'arquitecta',
		['Q483501'  ] = 'artista',
		['Q7019111' ] = 'asistenta social',
		['Q11063'   ] = 'astrónoma',		
		['Q18814623'] = 'autobiógrafa',		
		['Q482980'  ] = 'autora',
		['Q5716684' ] = 'bailarina',
		['Q805221'  ] = 'bailarina de ballet',		
		['Q864503'  ] = 'bióloga',
		['Q8246794' ] = 'bloguera',		
		['Q177220'  ] = 'cantante',
		['Q2865819' ] = 'cantante de ópera',
		['Q488205'  ] = 'cantautora',		
		['Q901'     ] = 'científica',
		['Q15212951'] = 'cineasta',
		['Q1086863' ] = 'columnista',		
		['Q245068'  ] = 'comediante',
		['Q36834'   ] = 'compositora',
		['Q2722764' ] = 'conductora radiofónica',		
		['Q2490358' ] = 'coreógrafa',
		['Q18939491'] = 'diarista',
		['Q193391'  ] = 'diplomática',
		['Q2526255' ] = 'directora de cine',
		['Q5322166' ] = 'deseñadora',
		['Q627325'  ] = 'deseñadora gráfica',
		['Q462390'  ] = 'docente',
		['Q214917'  ] = 'dramaturga',
		['Q188094'  ] = 'economista',
		['Q974144'  ] = 'educadora',
		['Q131524'  ] = 'emprendedora',
		['Q43845'   ] = 'empresaria',
		['Q186360'  ] = 'enfermera',
		['Q11774202'] = 'ensayista',		
		['Q36180'   ] = 'escritora',
		['Q4853732' ] = 'escritora de literatura infantil',
		['Q1281618' ] = 'escultora',
		['Q11900058'] = 'exploradora',		
		['Q13472585'] = 'filántropa',
		['Q4964182' ] = 'filósofa',
		['Q169470'  ] = 'física',		
		['Q33231'   ] = 'fotógrafa',
		['Q28389'   ] = 'guionista',
		['Q201788'  ] = 'historiadora',
		['Q715301'  ] = 'historietista',		
		['Q82594'   ] = 'informática teórica',
		['Q16533'   ] = 'jueza',
		['Q185351'  ] = 'jurista',
		['Q644687'  ] = 'ilustradora',
		['Q14467526'] = 'lingüista',				
		['Q1371925' ] = 'locutora',		
		['Q2251335' ] = 'maestra',		
		['Q191633'  ] = 'mangaka',
		['Q170790'  ] = 'matemática',
		['Q39631'   ] = 'médica',
		['Q4610556' ] = 'modelo',
		['Q639669'  ] = 'música',
		['Q6625963' ] = 'novelista',
		['Q1930187' ] = 'periodista',
		['Q1028181' ] = 'pintora',
		['Q728711'  ] = 'playmate',
		['Q49757'   ] = 'poeta',		
		['Q82955'   ] = 'política',
		['Q270389'  ] = 'presentadora de noticias',
		['Q947873'  ] = 'presentadora de televisión',		
		['Q3282637' ] = 'productora de cine',
		['Q37226'   ] = 'profesora',
		['Q121594'  ] = 'profesora',
		['Q16145150'] = 'profesora de música',
                ['Q1622272' ] = 'profesora de universidad',
		['Q212980'  ] = 'psicóloga',
		['Q3242115' ] = 'revolucionaria',
		['Q3068305' ] = 'salonnière',		
		['Q622807'  ] = 'seiyū',
		['Q512314'  ] = 'socialité',		
		['Q2306091' ] = 'socióloga',
		['Q1141526' ] = 'stripper',		
		['Q1234713' ] = 'teóloga',		
		['Q333634'  ] = 'traductora',
		['Q350979'  ] = 'zoóloga',
	}
	
	local etiquetaOcupacionCorregida = tablaOcupacionesFemeninas[args.traballo]
	
 --       return etiquetaOcupacionCorregida 
          return 'traballo recibido: ' .. args.traballo        -- non concateno co de arriba pq da erro xa que é nil, mostra "veterinario e primatólogo"

end

-- Función que devolve o valor de entidad.claims[idPropiedad][ocurrencia].mainsnak.datavalue.value.text
-- con entidad.claims[idPropiedad][ocurrencia].mainsnak.datavalue.value.language = 'gl'

-- Útil para obter valores de propiedades de tipo monolingualtext
-- Adaptada de es.wiki. Gardamos de novo.

function p.getPropiedadEnGalego(frame)
    marco = frame
    local args = frame.args
--(idEntidade, idPropiedade)
	-- Ver cs:Modul:Wikidata/item	formatEntityWithGender
	
	-- 
	local entidade =  mw.wikibase.getEntityObject(args.idEntidade)
	
	if not entidade then
		return
	end
	
	local declaracion   = elementoTabla(entidade,'claims', args.idPropiedade)
	
	if not declaracion then
		return 'non atopou 2'
	end
	
	local valor
	
	for k,v in pairs(declaracion) do
		valor = elementoTabla(v,'mainsnak', 'datavalue', 'value')
		
		if valor.language == 'gl' then
			return valor.text
		end
	end
end

 --[[ =========================================================================
      Función para pasar o frame cando se usa noutros módulos.
     ========================================================================= `-- ]]
function p:setFrame(frame)
	marco = frame
end


 --[[ =========================================================================
      Función para identificar o ítem correspondente á páxina ou outro dado.
              Isto último aínda non 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 se o valor devolto é un ítem ou unha propiedade
      e en función diso engade o prefixo correspondente
     ========================================================================= `-- ]]

function SelecionEntidadPorValor( valor )
    local prefijo = ''
    if valor['entity-type'] == 'item' then
        prefijo = 'q' -- Prefixo de ítem
    elseif valor['entity-type'] == 'property' then
        prefijo = 'p' -- Prefixo de propiedade
    else
        return formatoError( 'unknown-entity-type' )
    end
    return prefijo .. valor['numeric-id'] -- Concaténase o prefixo e o código numérico
end

 --[[ =========================================================================
      Función auxiliar para dar formato ás mensaxes de erro
     ========================================================================= `-- ]]

function formatoError( clave )
    return '<span class="error">' .. avisos.errores[clave] .. '</span>'
end
 --[[ =========================================================================
      Función para determinar o rango
     ========================================================================= `-- ]]
function p.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 a declaración ou declaracións de maior rango
     ========================================================================= `-- ]]
function filtrarDeclaracionPorRango(tablaDeclaraciones)
    local rango = p.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 o tipo de declaración: Referencia, valor principal
      ou cualificador
     ========================================================================= `-- ]]

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] -- devolve o cualificador (só devolverá o primeiro valor)
        else
        	return "" --Para que non lance excepción se non existe o cualificador
        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]  -- devolve a fonte (queda que se itinere a táboa)
    elseif (calificador == '' or not calificador) and (opciones.dato ~= 'fuente') then
        return declaracion.mainsnak -- devolve o valor principal
    else
    	return ''
    end
end

 --[[ =========================================================================
      Función para recopilar as declaracións
     ========================================================================= `-- ]]

function p.getDeclaraciones(entityId)


    -- == Comprobamos que existe un ítem ligando á páxina en Wikidata ==
    if not pcall (SelecionEntidadPorId, entityId ) then
    	return false
    end
    local entidad  = SelecionEntidadPorId(entityId)

    if not entidad then
        return  '' -- Se a páxina non está ligada a un ítem non devolve nada
    end

    -- == Comprobamos que o ítem ten declaracións (claims) ==

    if not entidad.claims then
        return '' -- Se o ítem non ten declaracións non devolve nada
    end
    -- == Declaración de formato e concatenado limpo ==

    return entidad.claims
end

 --[[ =========================================================================
      Función para  crear a cadea que devolverá a declaración
     ========================================================================= `-- ]]

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' -- Se damos o valor latitude, lonxitude ou precisión será equivalente a dar P625
    else
        propiedad = opciones.propiedad -- No resto de casos lese o dado
    end

    if not propiedad then -- Comprobamos se existe a propiedade dada e, en caso contrario, devólvese un erro
        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 dea erro cando se faga o find en opciones['formatoTexto'] se vale nil
    if not opciones['formatoTexto'] then
    	opciones['formatoTexto'] = ''
    end

    -- Deixar, no seu caso, os valores de maior rango
    if (opciones.rangoMayor == 'si') then
        tablaOrdenada = filtrarDeclaracionPorRango(tablaOrdenada)
    end

    -- == Se só se desexa que devolva un valor ==
    if opciones.uno == 'si' then -- Para que devolva o valor de índice 1
        tablaOrdenada = {tablaOrdenada[1]}
    elseif opciones.uno == 'último' then -- Para que devolva a última entrada da táboa
        tablaOrdenada = {tablaOrdenada[#tablaOrdenada]}
    end

-- == Creamos unha táboa cos valores que devolverá ==

    local formatoDeclaraciones = {}
    local hayDeclaraciones
    for indice, declaracion in pairs(tablaOrdenada) do
    	declaracionFormateada = 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 o formato á lista de valores segundo o tipo de lista das
    -- opcións
    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 ou polo separador e a
      	-- conxunción das opcións
       	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

        return mw.text.listToText( formatoDeclaraciones, separador,conjuncion )
    end
end

function p.categorizar(opciones, declaracion)
	-- Evitar que dea erro cando se faga o find en opciones['formatoTexto'] se 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 unha táboa cos valores da propiedade.
	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' -- Se damos o valor latitude, lonxitude ou precisión será equivalente a dar p625
        else
            propiedad = opciones.propiedad -- No resto de casos lese o 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

    -- == Se só se desexa que devolva un valor ==
    --if opciones.uno == 'si' then -- Para que devolva o valor de índice 1
    --    return formatoDeclaracion( valoresDeclaracion[1],opciones)
    --end
    --if (opciones.rangoMayor == 'si') then -- Para que devolva os valores de maior rango
     --   valoresDeclaracion = filtrarDeclaracionPorRango(valoresDeclaracion)
    --end

--  Creamos unha táboa con cada categoría a partir de cada valor da declaración
    local categorias    = {}
    local hayCategorias

    if type(categoriaOpciones) == 'string' then
        local ModuloPaginas = require('Módulo:Páxinas')

        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 comproba se a páxina está ligada a  Wikidata
        en caso de estalo pasa o valor como argumento á función formatSnak()
     ========================================================================= `-- ]]

function formatoDeclaracion( declaracion, opciones)
    if not declaracion.type or declaracion.type ~= 'statement' then -- Compróbase que ten valor de tipo e que este sexa statement (declaración) o cal pasa sempre que existe a propiedade
        return formatoError( 'unknown-claim-type' ) -- Se non se cumpre devuelve erro
    end

    -- No caso de que haxa cualificador devólvese a dereita do valor da
    -- declaración entre parénteses.

    local calificativo = opciones.calificador

    if calificativo and declaracion.qualifiers then
    	-- De momento os cualificativos, normalmente anos, non se ligan
       local opcionesCalificativo = {['formatoTexto']='', enlace='no', ['formatoFecha']='año'} -- Pendente

       local wValorCalificativo
       local wValorCalificativoFormateado

       if type(calificativo) == 'function' then
       	  -- Utilizar a función recibida sobre todos os cualificativos
       	  wValorCalificativo           = declaracion.qualifiers
          wValorCalificativoFormateado = calificativo(wValorCalificativo, opcionesCalificativo)
       else
       	  -- Utilizar o primeiro valor do cualificativo da propiedade recibida
       	  wValorCalificativo = declaracion.qualifiers[mw.ustring.upper(calificativo)]

       	  if wValorCalificativo and wValorCalificativo[1] then
            wValorCalificativoFormateado = p.formatoDato(wValorCalificativo[1], opcionesCalificativo)
	      end
	    end

    	if wValorCalificativoFormateado then
    	   return p.formatoDato(declaracion.mainsnak, opciones) .. '&nbsp;<small>(' .. wValorCalificativoFormateado .. ')</small>'
    	end
    end

    -- Se non hai cualificativo.
    return p.formatoDato(seleccionDeclaracion(declaracion, opciones), opciones, declaracion.qualifiers)
end

 --[[ =========================================================================
        Función que comproba o tipo de dato (snaktype)
        se é value pasa o valor como argumento á función formatoValorDato()
     ========================================================================= `-- ]]

function p.formatoDato( dato, opciones, calificativos)
    if not dato or dato == '' then
        return ''
    end
    if dato.snaktype == 'somevalue' then
    	-- Data máis antiga
    	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/Data').FormateaFechaHora(calificativos['P1319'][1].datavalue.value, opcionesFecha)
            end
    	end

    	-- Se non ten un calificativo válido
        return avisos['somevalue'] -- Valor descoñecido
    elseif dato.snaktype == 'novalue' then
        return avisos['novalue'] -- Sen valor
    elseif dato.snaktype == 'value' then
        return formatoValorDato( dato.datavalue, opciones, calificativos) -- Se ten o tipo de dato pásase o valor á función formatDatavalue()
    else
        return formatoError( 'unknown-snak-type' ) -- Tipo de dato descoñecido
    end
end

 --[[ =========================================================================
       Función que establece o tipo de formato en función do tipo de valor
       (valorDato.type) e en caso de solicitarse un formato complementario asocia
       o módulo onde se establece o formato e a función deste que o establece
     ========================================================================= `-- ]]

function formatoValorDato( valorDato, opciones, calificativos)

	-- == Se se da o parámetro  valor-módulo e valor-función ==

	funcion = opciones['valor-función'] or opciones['value-function']
	if funcion and type(funcion) == 'function' then -- Uso desde LUA
	--  Ver un exemplo no módulo de Ficha de libro co 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'] = 'si'
              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 = 'si'
	    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
        return fun( valorDato.value, opciones, marco)
    end

    -- == Formatos por defecto en función do tipo de valor ==

--          * Para tipo coordenadas cando se da como valor de propiedade: latitude, lonxitude ou 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']

--           * Co resto de valores en propiedade

    elseif valorDato.type == 'wikibase-entityid' then    -- Tipo: Número de entidade que pode ser un ítem ou propiedade
	    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'] = 'si'
              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 = 'si'
	    end
        return p.formatoIdEntidad( SelecionEntidadPorValor( valorDato.value ), opcionesEntidad)
    elseif valorDato.type == 'string' then               -- Tipo: Cadea 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: Data/hora
        local opcionesFecha={['formatoFecha']=opciones['formatoFecha'],enlace=opciones.enlace}

        if mw.ustring.find(opciones['formatoTexto'],'mayúscula', plain ) and primera then
	        opcionesFecha['mayúscula']='si'
        end

        return require('Módulo:Wikidata/Data').FormateaFechaHora(valorDato.value, opcionesFecha, calificativos)
    elseif valorDato.type == 'monolingualtext' then       -- Tipo: monolingüe
    	if valorDato.value then
            return valorDato.value.text
        else
            return ''
        end
    elseif valorDato.type ==  'quantity' then            -- Tipo: Cantidade
    	cantidad = mw.ustring.gsub(valorDato.value['amount'], '+','')
    	unidad = mw.wikibase.label(mw.ustring.gsub(valorDato.value['unit'], '^.-/(Q%d+)$', '%1'))
    	if unidad and tonumber(cantidad) > 1 then
    		unidad = unidad..'s'
    	end

    	if not unidad or (opciones['formatoUnidad'] and opciones['formatoUnidad'] == 'número') then
    		return tonumber(cantidad)
    	else
    		return cantidad .. ' ' .. unidad
    	end
    elseif  valorDato.value['latitude']  and valorDato.value['longitude'] then -- Tipo: Coordenadas
    	local globo = require('Módulo:Wikidata/Globos')[valorDato.value.globe]

--Concatenamos os valores de latitude e lonxitude dentro do modelo 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' ) -- Se non é de ningún destos tipos devolverá erro de valor desconocido
    end
end

  --[[ =========================================================================
          Damos formato ás ligazons internas
       ========================================================================= `-- ]]

-- Opcións:
--     - ligazóns:		Valores posibles 'si' ou 'non'
--     - maiúscula:		Valores posibles 'si' ou 'non'
--     - cursivas:		Valores posibles 'si' ou 'non'

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:Artigos con datos locais]]'
        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:Artigos con datos por trasladar a Wikidata]]'
        end
    end

    if args.prioridad == 'si' and valorWikidata  ~= '' then -- Se se da o valor si a prioridade, terá preferencia o 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 substitúe ó 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 -- Se o valor é nil salta unha excepcion ó concatenar
        return valorWikidata .. categorias
    else
    	return ''
  end
end

-- mw.wikibase.getLabelWithLang or getLabelByLang with a table of languages
local function getLabelByLangs(id, languages)
	local label
	local lang = languages[1]
	if lang == wiki.langcode then
		-- using getLabelWithLang when possible instead of getLabelByLang
		label, lang = mw.wikibase.getLabelWithLang(id)
	else
		for _, l in ipairs(languages) do
			label = mw.wikibase.getLabelByLang(id, l)
			lang = l
			if label then
				break
			end
		end
	end
	return label, lang
end

-- Is gender femenine? true or false
local function feminineGender(id)
	local entity = mw.wikibase.getEntityObject(id)
	local genderClaims = entity.claims["P21"] -- sex or gender
	if genderClaims then
		local genderId = getValueOfClaim(genderClaims[1], nil, {["formatting"]="raw"})
		if genderId == "Q6581072" or genderId == "Q1052281" or genderId == "Q43445" then -- female, transgender female, female organism
			return true
		end
	end
	return false
end

-- Fetch female form of label
local function feminineForm(id, lang)
	local feminine_claims = findClaims(mw.wikibase.getEntityObject(id), 'P2521') -- female form of label
	if feminine_claims then
		for _, feminine_claim in ipairs(feminine_claims) do
			local feminine_value = getValueOfClaim(feminine_claim, nil, {["formatting"]=lang, ["lang"]={lang}})
			if feminine_value then
				return feminine_value
			end
		end
	end
end

-- Gets a label in a given language (content language by default) or its fallbacks, optionnally linked.
function p.getLabel(frame)
	local args = frame.args
	local id = mw.text.trim(args[1] or "")
	if id == "" then return end
	local editicon = not (args.editicon == "false" or args.editicon == "no")
	local languages = findLang()
	-- temporary track
	if args.fixed then
		require('Módulo:utilidades').rastreig("Wikidata/fixed")
	end
	
	local pencil = ''
	local label, lang
	if languages[1] == wiki.langcode then
		label = require("Module:Wikidata/labels").infoboxLabelsFromId[id] -- exceptions or labels fixed
	end
	
	if label == nil then
		label, lang = getLabelByLangs(id, languages)
		if label then
			if args.itemgender and feminineGender(args.itemgender) then
				label = feminineForm(id, lang) or label
			end
			label = mw.language.new(lang):ucfirst(mw.text.nowiki(label)) -- sanitize
		end
		pencil = addEditIcon(id, lang, languages[1], editicon)
	end
	
	local linked = args.linked
	if linked and linked ~= "" and linked ~= "no" then
		local article = mw.wikibase.getSitelink(id) or ("d:" .. id)
		return "[[" .. article .. "|" .. (label or id) .. "]]" .. pencil
	else
		return (label or id) .. pencil
	end
end
return p