Modul:WikidataListe: Forskjell mellom sideversjoner

Fra Wikisida.no
Hopp til navigering Hopp til søk
(formatering)
(Legger ved ekstra informasjon for start- og sluttdatoer. Dette burde refaktoreres og gjøres mer generelt.)
Linje 51: Linje 51:
local extracted = ( claim.qualifiers or {} )[qualifier] or {}
local extracted = ( claim.qualifiers or {} )[qualifier] or {}
return not not extracted[1]
return not not extracted[1]
end

function getQualifier( claim, qualifier, strip )
if not claim.qualifiers then
return nil
end
local qualifiers = claim.qualifiers
if not qualifiers[qualifier] then
return nil
end
local qualifer = qualifiers[qualifier]
if not qualifer[1] then
return nil
end
if not strip then
return mw.wikibase.formatValue( claim.qualifiers[qualifier][1] )
end
-- this is to simple for more complex cases
return tostring( mw.wikibase.formatValue( claim.qualifiers[qualifier][1] ) ):gsub("%b<>", "")
end
end


Linje 171: Linje 194:
or formatYearQualifier(claim, 'P1319') -- tidligste dato
or formatYearQualifier(claim, 'P1319') -- tidligste dato
or '' -- all fail
or '' -- all fail
--do return mw.dumpObject(claim.qualifiers['P1326']) end
local startTitle = (hasQualifer(claim, 'P580') and getQualifier(claim, 'P580', true))
or (hasQualifer(claim, 'P1319') and getQualifier(claim, 'P1319', true))
or nil
local endYear = formatYearQualifier(claim, 'P582') -- til dato
local endYear = formatYearQualifier(claim, 'P582') -- til dato
or formatYearQualifier(claim, 'P1326') -- seneste dato
or formatYearQualifier(claim, 'P1326') -- seneste dato
or '' -- all fail
or '' -- all fail
local endTitle = (hasQualifer(claim, 'P582') and getQualifier(claim, 'P582', true))
formattedValue = string.format('%s (%s–%s)', formattedValue, startYear, endYear)
or (hasQualifer(claim, 'P1326') and getQualifier(claim, 'P1326', true))
or nil
local asterix = mw.html.create( 'sup' ):wikitext( '*' )
if startTitle then
local useFallback = not hasQualifer(claim, 'P580')
startYear = mw.html.create( 'span' )
:attr( 'title', string.format("%s: %s", mw.wikibase.getLabel( useFallback and 'P1319' or 'P580' ), startTitle ))
:wikitext( startYear .. (useFallback and tostring( asterix ) or ''))
end
if endTitle then
local useFallback = not hasQualifer(claim, 'P582')
endYear = mw.html.create( 'span' )
:attr( 'title', string.format("%s: %s", mw.wikibase.getLabel( useFallback and 'P1326' or 'P582' ), endTitle ))
:wikitext( endYear .. (useFallback and tostring( asterix ) or ''))
end
formattedValue = string.format("%s (%s–%s)", formattedValue, tostring(startYear), tostring(endYear))
end
end



Sideversjonen fra 2. jun. 2018 kl. 16:41

Formål

Å hente data fra Wikidata til infobokser når aktuelle data ikke er gitt lokalt.

Det er mulig å spesifisere at det ikke skal være noe i infoboksen selv om Wikidata skulle ha noe ved å oppgi verdi uten.

Bruk

Modulen brukes normalt ved å legge inn en rad i en infoboks ved:

{{#invoke:WikidataListe/test|rad|<diverse parametre>}}

eller for å hente og formattere en verdi fra Wikidata, enten for en infoboks eller for annen tekst ved:

{{#invoke:WikidataListe/test|verdi|<diverse parametre>}}
Parameter Utelatt Forklaring
qid Identitet til sidens tilkoblede wikidataelement Identiteten til et wikidataelement. Verdiene vil hentes fra dette elementet hvis parameteren har verdi.
pid Identitet til egenskapen på Wikidata som skal hentes. Verdiene som returneres kan være tom, enkeltverdi eller liste
param Navnet til en parameter til infoboksen som kan ha verdi som skal overstyre verdien fra Wikidata.
ref Skal verdiene referansebelegges? "nei" vil forhindre det, ellers blir det referanser.
tekst Verdi av param Tekst i venstrekolonnen for raden, hvis ikke det er det samme som verdien i param.
kollaps 5 Et tall som angir hvor mange verdier som skal vises før listen vises sammenslått. Hvis intet argument er gitt blir verdien 5 brukt.
kval Kvalifikatorer på Wikidata som skal vises. En kommaseparert liste med egenskapsidentifikatorer. Listes i den rekkefølge de skal vises, altså som «kval=Pxxx,Pyyy»
Pxxx Betingelser for enkeltkvalifikator. En kommaseparert liste, men foreløpig kun ett tilgjengelig valg «tittel». Hvis den ikke er gitt, vil etiketten til egenskapen brukes. Altså vil (P1686) vises som «For verk: verksnavn/lenke» «P1686=tittel:verk» vil endre dette til «verk: verksnavn/lenke» mens «P1686=tittel:» vil gi kun verksnavn/lenke.

Eksempel

Lua-feil i linje 31: assertion failed!.Lua-feil i linje 31: assertion failed!.Lua-feil i linje 31: assertion failed!.
WikidataListe
norsknavn = {{{norsknavn|{{#invoke:WikidataListe/test|verdi|qid={{{qid|}}}|pid=P1843|ref=Y}}|}}}

for å hente verdi for norsk navn ut fra (P1843). Eksempelvis vil

{{{norsknavn|{{#invoke:WikidataListe/test|verdi|qid=Q503989|pid=P1843|ref=Y}}|}}}

gi

som resultat.

Tilsvarende vil (P1705) for (Q26087)

{{#invoke:WikidataListe/test|verdi|qid=Q26087|pid=P1705|ref=nei}}

gi

For kraftverk vil:

{{#invoke:WikidataListe/test|rad|pid=P2957 |qid= {{{qid|}}}|param=slukeevne|ref=Y}} {{#invoke:WikidataListe/test|rad|pid=P2109 |qid= {{{qid|}}}|param=effekt}} {{#invoke:WikidataListe/test|rad|pid=P4131 |qid= {{{qid|}}}|param=årsproduksjon}}

med qid= Q5645687 ( (Q5645687)) gi verdiene i denne infoboksen


Referanser



local WikidataDato = require( 'Module:WikidataDato' )
local p = {}

function dump( out )
	if type( out ) == 'table' then
		local s = '{ '
		for k,v in pairs( out ) do
			if type( k ) ~= 'number' then k = '"'..k..'"' end
			s = s .. '['..k..'] = ' .. dump( v ) .. ','
		end
		return s .. '} '
	else
		return tostring( out )
	end
end

-- filter(function, table)
function filter(func, tbl)
	local newtbl= {}
	for i, v in pairs(tbl) do
		if func(v) then
			table.insert(newtbl, v)
		end
	end
	return newtbl
 end

-- Returns an array of non-deprecated claims for the given property.
-- If there's no Wikidata entity or no claims, an empty array is returned.
function getNonDeprecatedClaims( property )
	assert( property )

	local entity = mw.wikibase.getEntity()
	if not entity then
		return {}
	end

	local propertyId =  mw.wikibase.resolvePropertyId( property ) or 'none'
	local claims = ( entity.claims or {} )[propertyId] or {}

	claims = filter( function( claim ) return claim.mainsnak end, claims )
	claims = filter( function( claim ) return claim.rank ~= 'deprecated' end, claims )

	return claims
end

function hasQualifer( claim, qualifier )
	assert( claim )
	assert( qualifier )

	local extracted = ( claim.qualifiers or {} )[qualifier] or {}
	return not not extracted[1]
end

function getQualifier( claim, qualifier, strip )
	if not claim.qualifiers then
		return nil
	end
	
	local qualifiers = claim.qualifiers
	if not qualifiers[qualifier] then
		return nil
	end
	
	local qualifer = qualifiers[qualifier]
	if not qualifer[1] then
		return nil
	end
	
	if not strip then
		return mw.wikibase.formatValue( claim.qualifiers[qualifier][1] )
	end
	
	-- this is to simple for more complex cases
	return tostring( mw.wikibase.formatValue( claim.qualifiers[qualifier][1] ) ):gsub("%b<>", "")
end

function formatYearQualifier(claim, qualifier)
	assert( claim )
	assert( qualifier )

	local extracted = ( claim.qualifiers or {} )[qualifier] or {}
	if not (extracted[1] and extracted[1].snaktype == 'value') then
		return nil
	end

	return WikidataDato.aarFraClaim(extracted[1])
end

-- Returns either "ingen", "ukjent", "" or "Qxxxxxx"
function getValue(claim)
	assert( claim )

	-- map snak type
	local mainsnak = claim.mainsnak or {}
	if mainsnak.snaktype == 'novalue' then
		return "ingen"
	elseif mainsnak.snaktype == 'somevalue' then
		return "ukjent"
	elseif mainsnak.snaktype ~= 'value' then
		-- just in case
		return nil
	end

	-- check datatype
	if mainsnak.datatype ~= 'wikibase-item' then
		return nil
	end
	
	local datavalue = mainsnak.datavalue or {}
	if datavalue.type ~= 'wikibase-entityid' then
		return nil
	end
	
	local value = datavalue.value or {}
	if value['entity-type'] ~= 'item' then
		return nil
	end

	-- at this point there should be an ordinary value, but be safe
	return 'Q' .. ( value["numeric-id"] or 'xxxx')
end

function formatValue(value, first, link)
	assert( value )
	--assert( first )

	-- setter link til true som default hvis ingen verdi er angitt
	link = link or true

	if string.sub(value, 1, 1) ~= "Q" then
		-- Verdien er enten "ukjent" eller "ingen"
		return string.format("''%s''", value)
	end

	local label = mw.wikibase.label( value )
	local sitelink = mw.wikibase.sitelink( value )
	if first and label then
		local lang = mw.language.getContentLanguage()
		label = lang:ucfirst( label )
	end

	if not link then
		-- Vi ønsker kun tekst, ikke wikilenke
		if label then
			return label
		end
		return ''
	end

	if label and sitelink then
		return '[[' .. sitelink .. '|' .. label .. ']]'
	end
	if label and not sitelink then
		return label
	end
	if sitelink and not label then
		return '[[' .. sitelink .. ']]'
	end

	return ''
end

-- Returns all values from Wikidata for the given property
-- If no values are found, an empty string is returned.
function getFormattedValues(frame, prop, param, link)
	local claims = getNonDeprecatedClaims(prop)

	local i = 0
	local manglerOversettelse = false
	local formattedValues = {}
	
	for i, claim in ipairs(claims) do
		local value = getValue(claim)
		if value then
			local formattedValue = formatValue(value, i == 1, link)

			if formattedValue == '' then
				-- Målet har ikke en etikett på norsk bokmål, ei heller en artikkel på nowiki.
				-- Vi skriver ut en lenke til Wikidata for å gjøre det enkelt å legge til en etikett.
				-- For vanlige lesere kan det imidlertid være forvirrende med en Wikidata-lenke,
				-- så det er ikke helt optimalt. Vi marker derfor også at artikkelen skal legges til
				--  i en vedlikeholdskategori.
				manglerOversettelse = true
				formattedValue = "[[d:" .. value .. '|' .. value .. ']]'
			end

			if hasQualifer(claim, 'P580') -- startdato
				or hasQualifer(claim, 'P1319') -- tidligste dato
				or hasQualifer(claim, 'P582') --sluttdato
				or hasQualifer(claim, 'P1326') -- seneste dato
			then
				local startYear = formatYearQualifier(claim, 'P580')  -- fra dato
						or formatYearQualifier(claim, 'P1319') -- tidligste dato
						or '' -- all fail
				--do return mw.dumpObject(claim.qualifiers['P1326']) end
				local startTitle = (hasQualifer(claim, 'P580') and getQualifier(claim, 'P580', true))
						or (hasQualifer(claim, 'P1319') and getQualifier(claim, 'P1319', true))
						or nil
				local endYear = formatYearQualifier(claim, 'P582')  -- til dato
						or formatYearQualifier(claim, 'P1326') -- seneste dato
						or '' -- all fail
				local endTitle = (hasQualifer(claim, 'P582') and getQualifier(claim, 'P582', true))
						or (hasQualifer(claim, 'P1326') and getQualifier(claim, 'P1326', true))
						or nil
				local asterix = mw.html.create( 'sup' ):wikitext( '*' )
				if startTitle then
					local useFallback = not hasQualifer(claim, 'P580')
					startYear = mw.html.create( 'span' )
						:attr( 'title', string.format("%s: %s", mw.wikibase.getLabel( useFallback and 'P1319' or 'P580' ), startTitle ))
						:wikitext( startYear .. (useFallback and tostring( asterix ) or ''))
				end
				if endTitle then
					local useFallback = not hasQualifer(claim, 'P582')
					endYear = mw.html.create( 'span' )
						:attr( 'title', string.format("%s: %s", mw.wikibase.getLabel( useFallback and 'P1326' or 'P582' ), endTitle ))
						:wikitext( endYear .. (useFallback and tostring( asterix ) or ''))
				end
				formattedValue = string.format("%s (%s–%s)", formattedValue, tostring(startYear), tostring(endYear))
			end

			if formattedValue ~= '' then
				table.insert(formattedValues, formattedValue)
			end
		end
	end

	local resultat = table.concat(formattedValues, ", ")

	-- use of # to get count will fail in the future
	if #formattedValues > 5 then
		resultat = string.format([[
			<div class="mw-collapsible mw-collapsed">
				<div class="sentrert">%s oppføringer</div>
				<div class="mw-collapsible-content">%s</div>
			</div>
		]], #formattedValues, resultat)
	end

	if manglerOversettelse then
		resultat = resultat .. "[[Kategori:Artikler hvor " .. param .. " mangler oversettelse]]"
	end

	return resultat
end

function getFrameValue(frame, params)
	local args = frame.args
	if args[1] == nil then
		local pFrame = frame:getParent();
		args = pFrame.args;
		for k,v in pairs( frame.args ) do
			args[k] = v;
		end
	end
	
	-- params kan være én enkelt verdi eller flere verdier adskilt med komma.
	-- F.eks. vil "religion,livssyn" sjekke både "religion" og "livssyn".
	for param in mw.text.gsplit( params, ',', true ) do
		 if args[param] then
			return mw.text.trim( args[param] )
		 end
	end
	return ""
end

function p.grenserTil(frame)
	assert( frame )
	return getFormattedValues(frame,'P47',"grenser til")
end

function p.yrker(frame)
	assert( frame )
	return getFormattedValues(frame,'P106',"beskjeftigelse", false)
end

function _strip( str )
	return string.sub( str, 2 , string.len( str )-1 )
end

function strip( str )
	local lang = mw.language.getContentLanguage()
	-- Fjern mest mulig formatering fra den lokale verdien
	local stripped = str:gsub("%[%[([^%[%]%{%}%|]+)%|([^%[%]%{%}%|]+)%]%]", "%2")
	stripped = stripped:gsub("%b<>", "")
	local last = nil
	repeat
		last = stripped
		stripped = stripped:gsub( "(%b[])", _strip )
				:gsub( "(%b{})", _strip ) -- not sure if this should be escaped
				:gsub( "(%b())", _strip )
	until ( last == stripped )
	stripped = stripped:gsub("''+", "")
	stripped = lang:uc(stripped)
	return stripped
end

function velg(frame, prop, param, link)
	local verdiFraFrame = getFrameValue(frame, param)
	if verdiFraFrame == "uten-ukat" then
		-- Hvis malargumentet er satt til "uten-ukat" betyr det at det ikke er
		-- ønskelig at feltet vises selv om det finnes data på Wikidata OG
		-- at siden ikke skal kategoriseres. Dette kan brukes av maler som
		-- [[Infoboks:Forsker]] for å skjule felt som er lite relevante.
		return ""
	end
	if verdiFraFrame == "uten" then
		-- Hvis malargumentet er satt til "uten" betyr det at det ikke er
		-- ønskelig at feltet vises, selv om det finnes data på Wikidata.
		return "[[Kategori:Artikler hvor " .. param .. " spesifisert som uten]]"
	end

	local verdiFraWikidata = getFormattedValues(frame, prop, param, link)
	if verdiFraWikidata == "" then
		-- No value at Wikidata.
		if verdiFraFrame == "" then
			return ""
		end
		return verdiFraFrame .. "[[Kategori:Artikler hvor " .. param .. " mangler på Wikidata]]"
	end

	if verdiFraFrame == "" then
		if verdiFraWikidata == "" then
			return ""
		end
		return verdiFraWikidata .. "[[Kategori:Artikler hvor " .. param .. " hentes fra Wikidata]]"
	end
	

	if strip(verdiFraFrame) == strip(verdiFraWikidata) then
		-- Den lokale verdien er helt lik Wikidata-verdien
		return verdiFraFrame .. "[[Kategori:Artikler hvor " .. param .. " samme som på Wikidata]]"
	end

	-- Den lokale verdien er ikke *helt* lik Wikidata-verdien, men vi vet ikke om det er
	-- snakk om betydningsforskjeller.
	return verdiFraFrame .. "[[Kategori:Artikler hvor " .. param .. " forskjellig fra Wikidata]]"
end

function rad( frame, prop, param, link, displayName )
	assert( frame )
	local lang = mw.language.getContentLanguage()
	local verdiFraFrame = getFrameValue( frame, param )
	local value = velg( frame, prop, param, link )
	displayName = displayName or lang:ucfirst(param)
	if verdiFraFrame == "uten" or verdiFraFrame == "uten-ukat" then
		-- I dette tilfellet har velg() returnert en kategori av typen
		-- [[Kategori:Artikler hvor {param} spesifisert som uten]].
		-- Vi sender denne videre.
		return value
	end
	if value == "" then
		return ""
	end
	return string.format([[
		<tr class="rad" valign="top">
			<th colspan="2" class="nowrap">%s</th>
			<td colspan="2">%s</td>
		</tr>
	]], displayName, value)
end

function p.radYrke(frame)
	assert( frame )
	return rad(frame,'P106','beskjeftigelse', false)
end

function p.velgYrke(frame)
	assert( frame )
	return velg(frame,'P106','beskjeftigelse', false)
end
function p.radUtdannet_ved(frame)
	assert( frame )
	return rad(frame,'P69','utdannet ved')
end
function p.radUtdannelse(frame)
	assert( frame )
	return rad(frame,'P512','akademisk grad')
end
function p.radDoktorgradsveileder(frame)
	assert( frame )
	return rad(frame,'P184','doktorgradsveileder')
end
function p.radEktefelle(frame)
	assert( frame )
	return rad(frame,'P26','ektefelle', true)
end
function p.radMor(frame)
	assert( frame )
	return rad(frame,'P25','mor')
end
function p.radFar(frame)
	assert( frame )
	return rad(frame,'P22','far')
end
function p.radBarn(frame)
	assert( frame )
	return rad(frame,'P40','barn')
end
function p.radSoesken(frame)
	assert( frame )
	return rad(frame,'P3373','søsken')
end
function p.radParti(frame)
	assert( frame )
	return rad(frame,'P102','parti')
end
function p.radBarn(frame)
	assert( frame )
	return rad(frame,'P40','barn')
end
function p.rad(frame)
	assert( frame )
	return rad(frame, frame.args['wdp'], frame.args['param'], nil, frame.args['tekst'])
end

return p