Modul:Wikidata

Fra MotorWiki
Hopp til navigering Hopp til søk

Dokumentasjon for denne modulen kan opprettes på Modul:Wikidata/dok

local i18n = {
    ["errors"] = {
        ["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 snak desconocido.",
        ["unknown-datavalue-type"] = "Tipo datavalue 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 value-module.",
        ["value-function-not-found"] = "No se ha encontrado la función apuntada por value-function."
    },
    ["somevalue"] = "''valor desconocido''",
    ["novalue"] = "''sin valor''"
}
 
function getEntityFromId( id )
    if id then
        return mw.wikibase.getEntityObject( id )
    end
    return mw.wikibase.getEntityObject()
end
 
function getEntityIdFromValue( value )
    local prefix = ''
    if value['entity-type'] == 'item' then
        prefix = 'Q'
    elseif value['entity-type'] == 'property' then
        prefix = 'P'
    else
        return formatError( 'unknown-entity-type' )
    end
    return prefix .. value['numeric-id']
end
 
function formatError( key )
    return '<span class="error">' .. i18n.errors[key] .. '</span>'
end
 
 
function formatStatements( options )
    if options.property == 'precisión' or options.property == 'breddegrad' or options.property == 'lengdegrad'  then
        propiedad = 'P625'
    else 
        propiedad = options.property
    end
    if not propiedad then
        return formatError( 'property-param-not-provided' )
    end
 
    --Get entity
    local entity = getEntityFromId( options.entityId )
    if not entity then
        return  ''--formatError( 'entity-not-found' )
    end
 
    if (entity.claims == nil) or (not entity.claims[propiedad]) then
        return '' --TODO error?
    end
 
    --Declaración de formato y concatenado limpio
 
    local propiedad = {}
    if options.property == 'breddegrad' or options.property == 'lengdegrad' or options.property == 'precisión' then
        propiedad = 'P625'
    else 
        propiedad = options.property
    end 
    local cadena = entity.claims[propiedad]
    local s = {} -- Esto es para que el índice 0 pase a ser 1. Necesario para que todo quede en el mismo orden que en ítem
    for k, v in pairs(cadena) do
        s[k+1] = v
    end 
    local formattedStatements = {}
    for i, statement in pairs(s) do
        table.insert( formattedStatements, formatStatement( statement, options ) )
    end
    return mw.text.listToText( formattedStatements, options.separator, options.conjunction )
end
 
function formatStatement( statement, options )
    if not statement.type or statement.type ~= 'statement' then
        return formatError( 'unknown-claim-type' )
    end
 
    return formatSnak( statement.mainsnak, options )
    --TODO reference and qualifiers
end
 
function formatSnak( snak, options )
    if snak.snaktype == 'somevalue' then
        return i18n['somevalue']
    elseif snak.snaktype == 'novalue' then
        return i18n['novalue']
    elseif snak.snaktype == 'value' then
        return formatDatavalue( snak.datavalue, options )
    else
        return formatError( 'unknown-snak-type' )
    end
end
 
function formatDatavalue( datavalue, options )
    --Use the customize handler if provided
    if options['value-module'] or options['value-function'] then
        if not options['value-module'] or not options['value-function'] then
            return formatError( 'unknown-value-module' )
        end
        local formatter = require ('Module:' .. options['value-module'])
        if formatter == nil then
            return formatError( 'value-module-not-found' )
        end
        local fun = formatter[options['value-function']]
        if fun == nil then
            return formatError( 'value-function-not-found' )
        end
        return fun( datavalue.value, options )
    end
    --Default formatters
    if options.property == 'breddegrad' then --Para las coordenadas
        return datavalue.value['breddegrad']
    elseif options.property == 'lengdegrad' then
        return datavalue.value['lengdegrad']
     elseif options.property == 'precisión' then
        return datavalue.value['precision']
 
    elseif datavalue.type == 'wikibase-entityid' then
        return formatEntityId( getEntityIdFromValue( datavalue.value ), options )
    elseif datavalue.type == 'string' then
        return datavalue.value --TODO ids + media
    elseif  datavalue.value['breddegrad']  and datavalue.value['lengdegrad'] then 
        return  marco:preprocess('{{coord|' .. datavalue.value['breddegrad'] .. '|' .. 
                   datavalue.value['lengdegrad'] .. '|type:' .. options.tipo .. '|display=' .. 
                   options.display ..'|format=' .. options.formato..'}}')
    else
        return formatError( 'unknown-datavalue-type' )
    end
end
 
function formatEntityId( entityId, options )
    local label = mw.wikibase.label( entityId )
 
    local link = mw.wikibase.sitelink( entityId )
    if link and  options['link'] ~=  'no' then
        if label then
            return '[[' .. link .. '|' .. label .. ']]'
        else
            return '[[' .. link .. ']]'
        end
    elseif label then
        return label --TODO what if no links and label + fallback language?
    else
        return ''
    end
end
 
local p = {}
 
function p.formatStatements( frame )
    marco = frame
    local args = frame.args
    local valorwikidata = formatStatements( frame.args )
    if args.prioridad == 'sí' and valorwikidata  ~= '' then
        return formatStatements( frame.args )
    elseif args.value and args.value ~= '' then
         return args.value
    else
        return formatStatements( frame.args )
  end  
end

-- Returns the page title of a linked page in another Wikimedia site as a string
-- If no wikidata page exists, or if no link exists to the given project, 
-- the function returns nil
function p.sitelink(frame)

	-- First argument is the site code ('enwiki', 'commonswiki', ...)
	local siteId = frame.args[1]
	
	-- Get Wikibase item connected to the current page
	local entity = mw.wikibase.getEntityObject()
	if not entity then
		return nil -- no wikidata page for current item
	end

	-- Get title the item is linked with in the given site
	return entity:getSitelink(siteId)
end

-- Returns Commons category, if any
function p.commonscat(frame)
	
	templateArgs = {}

	-- if a category name is specified explicitly, we use that value
	if frame.args[1] and frame.args[1] ~= '' then
		templateArgs[1] = frame.args[1]
		if frame.args[2] and frame.args[2] ~= '' then
			templateArgs[2] = frame.args[2]
		end
	
	-- otherwise, we fetch the category name from Wikidata
	else

		-- Get Wikibase item connected to the current page
		local entity = mw.wikibase.getEntityObject()
		if not entity then
			return '[[Kategori:Sider med Commonscat som mangler Wikidata-side]]'
		end  -- no wikidata page for current item
	
		-- Get formatted value
		local value = entity:formatPropertyValues( 'P373' )['value']
		if value == '' then  -- property not set
			-- Commons categories may also be stored as sitelinks
			value = p.sitelink({args = {'commonswiki'}})
			if value and mw.ustring.sub(value, 0, 9) == 'Category:' then
				value = mw.ustring.sub(value, 10)  -- remove namespace
			else
				value = ''  -- not a category, probably a gallery page
			end
		end
		if value == '' then  -- neither property nor sitelink available
			return '[[Kategori:Sider med Commonscat der Wikidata-siden mangler Commons-lenke]]'
		end
		
		templateArgs[1] = value
	
	end

	-- Return formatted value using a template
	if frame.args['template'] then
		return frame:expandTemplate{
			title = frame.args['template'],
			args = templateArgs
		}
	end

	-- or just return plain category name
	return templateArgs[1]

end

-- This is used to get a value, or a comma separated list of them if multiple values exist
p.hentVerdi = function(frame)
	local propertyID = mw.text.trim(frame.args[1] or "")
	local input_parm = mw.text.trim(frame.args[2] or "")
	if input_parm == "FETCH_WIKIDATA" then
		local entity = mw.wikibase.getEntityObject()
		local claims
		if entity and entity.claims then
			claims = entity.claims[propertyID]
		end
		if claims then
			-- if wiki-linked value output as link if possible
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then
				local out = {}
				for k, v in pairs(claims) do
					local sitelink = mw.wikibase.sitelink("Q" .. v.mainsnak.datavalue.value["numeric-id"])
					local label = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"])
					if label == nil then label = "Q" .. v.mainsnak.datavalue.value["numeric-id"] end
							
					if sitelink then
						out[#out + 1] = "[[" .. sitelink .. "|" .. label .. "]]"
					else
						out[#out + 1] = "[[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]<abbr title='Article is not yet available in this wiki'>[*]</abbr>"
					end
				end
				return table.concat(out, ", ")
			else
				-- just return best vakues
				return entity:formatPropertyValues(propertyID).value
			end
		else
			return ""
		end
	else
		return input_parm
	end
end

p.getQualifierValue = function(frame)
	local propertyID = mw.text.trim(frame.args[1] or "")
	local qualifierID = mw.text.trim(frame.args[2] or "")
	local input_parm = mw.text.trim(frame.args[3] or "")
	if input_parm == "FETCH_WIKIDATA" then
		local entity = mw.wikibase.getEntityObject()
		if entity.claims[propertyID] ~= nil then
			local out = {}
			for k, v in pairs(entity.claims[propertyID]) do
				for k2, v2 in pairs(v.qualifiers[qualifierID]) do
					if v2.snaktype == 'value' then
						if (mw.wikibase.sitelink("Q" .. v2.datavalue.value["numeric-id"])) then
							out[#out + 1] = "[[" .. mw.wikibase.sitelink("Q" .. v2.datavalue.value["numeric-id"]) .. "]]"
						else
							out[#out + 1] = "[[:d:Q" .. v2.datavalue.value["numeric-id"] .. "|" .. mw.wikibase.label("Q" .. v2.datavalue.value["numeric-id"]) .. "]]<abbr title='Article is not yet available in this wiki'>[*]</abbr>"
						end
					end
				end
			end
			return table.concat(out, ", ")
		else
			return ""
		end
	else
		return input_parm
	end
end

-- This is used to get a value like 'male' (for property p21) which won't be linked and numbers without the thousand separators
p.getRawValue = function(frame)
	local propertyID = mw.text.trim(frame.args[1] or "")
	local input_parm = mw.text.trim(frame.args[2] or "")
	if input_parm == "FETCH_WIKIDATA" then
		local entity = mw.wikibase.getEntityObject()
		local claims
		if entity then claims = entity.claims[propertyID] end
		if claims then
			local result = entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value
		
			-- if number type: remove thousand separators
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "quantity") then
				result = mw.ustring.gsub(result, "(%d),(%d)", "%1%2")
			end
			return result
		else
			return ""
		end
	else
		return input_parm
	end
end

p.getRawQualifierValue = function(frame)
	local propertyID = mw.text.trim(frame.args[1] or "")
	local qualifierID = mw.text.trim(frame.args[2] or "")
	local input_parm = mw.text.trim(frame.args[3] or "")
	if input_parm == "FETCH_WIKIDATA" then
		local entity = mw.wikibase.getEntityObject()
		if entity.claims[propertyID] ~= nil then
			local out = {}
			for k, v in pairs(entity.claims[propertyID]) do
				for k2, v2 in pairs(v.qualifiers[qualifierID]) do
					if v2.snaktype == 'value' then
						if v2.datavalue.value["numeric-id"] then
							out[#out + 1] = mw.wikibase.label("Q" .. v2.datavalue.value["numeric-id"])
						else
							out[#out + 1] = v2.datavalue.value
						end
					end
				end
			end
			local ret = table.concat(out, ", ")
			return string.upper(string.sub(ret, 1, 1)) .. string.sub(ret, 2)
		else
			return ""
		end
	else
		return input_parm
	end
end

p.getQualifierValue = function(frame)
	local propertyID = mw.text.trim(frame.args[1] or "")
	local qualifierID = mw.text.trim(frame.args[2] or "")
	local input_parm = mw.text.trim(frame.args[3] or "")
	if input_parm == "FETCH_WIKIDATA" then
		local entity = mw.wikibase.getEntityObject()
		if entity.claims[propertyID] ~= nil then
			local out = {}
			for k, v in pairs(entity.claims[propertyID]) do
				for k2, v2 in pairs(v.qualifiers[qualifierID]) do
					if v2.snaktype == 'value' then
						if (mw.wikibase.sitelink("Q" .. v2.datavalue.value["numeric-id"])) then
							out[#out + 1] = "[[" .. mw.wikibase.sitelink("Q" .. v2.datavalue.value["numeric-id"]) .. "]]"
						else
							out[#out + 1] = "[[:d:Q" .. v2.datavalue.value["numeric-id"] .. "|" .. mw.wikibase.label("Q" .. v2.datavalue.value["numeric-id"]) .. "]]<abbr title='Article is not yet available in this wiki'>[*]</abbr>"
						end
					end
				end
			end
			return table.concat(out, ", ")
		else
			return ""
		end
	else
		return input_parm
	end
end

-- This is used to get a value like 'male' (for property p21) which won't be linked and numbers without the thousand separators
p.getRawValue = function(frame)
	local propertyID = mw.text.trim(frame.args[1] or "")
	local input_parm = mw.text.trim(frame.args[2] or "")
	if input_parm == "FETCH_WIKIDATA" then
		local entity = mw.wikibase.getEntityObject()
		local claims
		if entity then claims = entity.claims[propertyID] end
		if claims then
			local result = entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value
		
			-- if number type: remove thousand separators
			if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "quantity") then
				result = mw.ustring.gsub(result, "(%d),(%d)", "%1%2")
			end
			return result
		else
			return ""
		end
	else
		return input_parm
	end
end

p.getRawQualifierValue = function(frame)
	local propertyID = mw.text.trim(frame.args[1] or "")
	local qualifierID = mw.text.trim(frame.args[2] or "")
	local input_parm = mw.text.trim(frame.args[3] or "")
	if input_parm == "FETCH_WIKIDATA" then
		local entity = mw.wikibase.getEntityObject()
		if entity.claims[propertyID] ~= nil then
			local out = {}
			for k, v in pairs(entity.claims[propertyID]) do
				for k2, v2 in pairs(v.qualifiers[qualifierID]) do
					if v2.snaktype == 'value' then
						if v2.datavalue.value["numeric-id"] then
							out[#out + 1] = mw.wikibase.label("Q" .. v2.datavalue.value["numeric-id"])
						else
							out[#out + 1] = v2.datavalue.value
						end
					end
				end
			end
			local ret = table.concat(out, ", ")
			return string.upper(string.sub(ret, 1, 1)) .. string.sub(ret, 2)
		else
			return ""
		end
	else
		return input_parm
	end
end

return p