Modul:WikidataListe
![]() | Denne modulen brukes på mer enn 200 000 sider. Det anbefales at endringer testes i en sandkasse før de legges inn. Diskutér gjerne også endringer på diskusjonssiden først. |
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 ved å legge inn
aktuell parameter = {{#invoke:WikidataListe|velg aktuell parameter}}
i en infoboks. aktuell parameter står her for en av de implementerte parameterne. Disse er nå:
- yrke =
{{#invoke:WikidataListe|velgyrke}}
Det vil kategoriseres i et antall kategorier som bør opprettes som skjulte kategorier når malen utvides. Disse kategoriene vil ha den aktuelle parameteren som del av navnet. For yrke er kategoriene: Kategori:Artikler hvor yrke forskjellig fra Wikidata, Kategori:Artikler hvor yrke hentes fra Wikidata, Kategori:Artikler hvor yrke mangler på Wikidata, Kategori:Artikler hvor yrke samme som på Wikidata, Kategori:Artikler hvor yrke spesifisert som uten.
Hvis det ikke finnes noen norsk etikett («label») for den aktuelle verdien, enkelte av de aktuelle verdiene, vil de bli utelatt fra det som hentes fra Wikidata. Derved vil yrke mangle på Wikidata også hvis yrket ikke har noe norsk navn på Wikidata.
Hvis det på Wikidata finnes en lenke til en artikkel på vår Wikipedia, vil verdiene som hentes fra Wikidata være lenket til denne.
Eksempel
For å hente medvirkende fra P161 som kan overstyres med {{{medvirkende|}}}
brukes f.eks koden: {{#invoke:WikidataListe|values|param=medvirkende|wdp=P161}}
Du kan eksperimentere med denne modulens sandkasse (rediger | forskjell) og testtilfeller (opprett). Vennligst legg kategorier på undersiden /dok. Vis undersider av denne modulen. |
local WikidataDato = require( 'Module:WikidataDato' )
local refs = require 'Module:Reference score'
local p = {}
-- The value given to the properties in the table are not significant, they just need to exist
local useReferences = {
["P19"] = "fødested", -- fødested
["P20"] = "dødssted", -- dødssted
["P22"] = "far", -- far
["P25"] = "mor", -- mor
["P26"] = "ektefelle", -- ektefelle
["P69"] = "utdannet ved", -- utdannet ved
["P84"] = "arkitekt", -- arkitekt
["P102"] = "medlem av politisk parti", -- medlem av politisk parti
["P106"] = "beskjeftigelse", -- beskjeftigelse
["P119"] = "gravsted", -- gravsted
["P161"] = "medvirkende", -- medvirkende
["P166"] = "utmerkelse", -- utmerkelse
["P3373"] = "søsken" -- søsken
}
local useCountry = {
["P19"] = "fødested", -- fødested
["P20"] = "dødssted" -- dødssted
}
local linktext = 'Rediger på Wikidata'
local linktarget = 'https://www.wikidata.org/wiki/%s?uselang=%s#%s'
local kollapsNum = 5
-- 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
function kollaps(num)
if kollapsNum>0 then
if num>kollapsNum then
return true
end
end
return false
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 getBestStatements( property, qid )
assert( property )
local entity = mw.wikibase.getEntity(qid)
if not entity then
return {}
end
return entity:getBestStatements(property)
end
function hasQualifer( claim, qualifier )
assert( claim )
assert( qualifier )
local qualifiers = claim.qualifiers or {}
local snaks = qualifiers[qualifier] or {}
return not not snaks[1]
end
function isStrange( snak )
if not snak then
return nil
end
return snak.snaktype == 'novalue'
or snak.snaktype == 'somevalue'
or nil
end
function getStrange( snak )
return (snak.snaktype == 'novalue' and 'ingen')
or (snak.snaktype == 'somevalue' and 'ukjent')
or nil
end
function getQualifier( claim, qualifier, strip )
if not claim.qualifiers then
return nil
end
local qualifiers = claim.qualifiers or {}
if not qualifiers[qualifier] then
return nil
end
local snaks = qualifiers[qualifier] or {}
if not snaks[1] then
return nil
end
local snak = snaks[1] or {}
if isStrange( snak ) then
return getStrange( snak )
end
if not strip then
return mw.wikibase.formatValue( snak )
end
-- this is to simple for more complex cases
return tostring( mw.wikibase.formatValue( snak ) ):gsub("%b<>", "")
end
function formatYearQualifier(claim, qualifier)
assert( claim )
assert( qualifier )
local snaks = ( claim.qualifiers or {} )[qualifier] or {}
if not snaks[1] then
return nil
end
local snak = snaks[1] or {}
if isStrange( snak ) then
return getStrange( snak )
end
return WikidataDato.aarFraClaim( snak )
end
-- Returns either "ingen", "ukjent", "" or "Qxxxxxx"
function getValue(claim)
assert( claim )
local mainsnak = claim.mainsnak or {}
if isStrange( mainsnak ) then
return getStrange( mainsnak )
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
if type( link ) ~= 'boolean' then
link = true
end
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
function formatTimePeriod( claim, first, second )
local startYear = formatYearQualifier(claim, first) -- fra dato
or formatYearQualifier(claim, 'P1319') -- tidligste dato
or '' -- all fail
--do return mw.dumpObject(claim.qualifiers['P1326']) end
local startTitle = (hasQualifer(claim, first) and getQualifier(claim, first, true))
or (hasQualifer(claim, 'P1319') and getQualifier(claim, 'P1319', true))
or nil
local endYear = formatYearQualifier(claim, second) -- til dato
or formatYearQualifier(claim, 'P1326') -- seneste dato
or '' -- all fail
local endTitle = (hasQualifer(claim, second) and getQualifier(claim, second, true))
or (hasQualifer(claim, 'P1326') and getQualifier(claim, 'P1326', true))
or nil
local asterix = mw.html.create( 'sup' ):wikitext( '*' )
if startTitle then
local useFallback = (first == 'P1319') or not hasQualifer(claim, first)
startYear = mw.html.create( 'span' )
:attr( 'title', string.format("%s: %s", mw.wikibase.getLabel( useFallback and 'P1319' or first ), startTitle ))
:wikitext( startYear .. (useFallback and tostring( asterix ) or ''))
end
if endTitle then
local useFallback = (second == 'P1326') or not hasQualifer(claim, second)
endYear = mw.html.create( 'span' )
:attr( 'title', string.format("%s: %s", mw.wikibase.getLabel( useFallback and 'P1326' or second ), endTitle ))
:wikitext( endYear .. (useFallback and tostring( asterix ) or ''))
end
return string.format("(%s–%s)", tostring(startYear), tostring(endYear))
end
function formatTimePoint( claim )
local pointYear = formatYearQualifier(claim, 'P585')
or '' -- all fail
local pointTitle = (hasQualifer(claim, 'P585') and getQualifier(claim, 'P585', true))
or nil
if pointTitle then
pointYear = mw.html.create( 'span' )
:attr( 'title', string.format("%s: %s", mw.wikibase.getLabel( 'P585' ), pointTitle ))
:wikitext( pointYear )
end
return string.format("(%s)", tostring(pointYear))
end
function formatEdit( qid, langCode, prop )
if not qid then
return ''
end
local link = mw.ustring.format( linktarget, qid, langCode, prop )
local text = '[[File:OOjs UI icon edit-ltr-progressive.svg'
.. '|frameless|text-top|10px'
.. '|alt=' .. mw.text.nowiki( linktext )
.. '|link=' .. mw.text.nowiki( link )
.. '|' .. mw.text.nowiki( linktext )
.. ']]'
local html = mw.html.create( 'span' )
:addClass( 'wb-edithandle' )
-- @todo this must be adjusted
-- :attr( 'data-bridge-edit-flow', 'single-best-value' )
:wikitext( text )
return tostring( html )
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,calcRefs,qid)
local claims = getBestStatements(prop,qid)
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 useCountry[prop] then
if (hasQualifer(claim, 'P17') or hasQualifer(claim, 'P131')) then
local country = getQualifier(claim,"P17")
if not country or country == "" then
country = getQualifier(claim,"P131")
end
if country and country ~= '' then
formattedValue = formattedValue .. ', ' .. country
.. "[[Kategori:Artikler hvor sted presiseres med kvalifikator fra Wikidata]]"
end
end
end
-- Dette er egentlig valg av en algoritme, dvs det burde skrives som et pattern
if hasQualifer(claim, 'P523') or hasQualifer(claim, 'P524') then
formattedValue = formattedValue .. ' ' .. formatTimePeriod( claim, 'P523', 'P524' )
elseif hasQualifer(claim, 'P580') or hasQualifer(claim, 'P582') then
formattedValue = formattedValue .. ' ' .. formatTimePeriod( claim, 'P580', 'P582' )
elseif hasQualifer(claim, 'P729') or hasQualifer(claim, 'P730') then
formattedValue = formattedValue .. ' ' .. formatTimePeriod( claim, 'P729', 'P730' )
elseif hasQualifer(claim, 'P2031') or hasQualifer(claim, 'P2032') then
formattedValue = formattedValue .. ' ' .. formatTimePeriod( claim, 'P2031', 'P2032' )
elseif hasQualifer(claim, 'P3415') or hasQualifer(claim, 'P3416') then
formattedValue = formattedValue .. ' ' .. formatTimePeriod( claim, 'P3415', 'P3416' )
elseif hasQualifer(claim, 'P575') then
formattedValue = formattedValue .. ' ' .. formatTimePoint( claim, 'P575' )
elseif hasQualifer(claim, 'P585') then
formattedValue = formattedValue .. ' ' .. formatTimePoint( claim, 'P585' )
elseif hasQualifer(claim, 'P606') then
formattedValue = formattedValue .. ' ' .. formatTimePoint( claim, 'P606' )
elseif hasQualifer(claim, 'P813') then
formattedValue = formattedValue .. ' ' .. formatTimePoint( claim, 'P813' )
elseif hasQualifer(claim, 'P1191') then
formattedValue = formattedValue .. ' ' .. formatTimePoint( claim, 'P1191' )
elseif hasQualifer(claim, 'P1249') then
formattedValue = formattedValue .. ' ' .. formatTimePoint( claim, 'P1249' )
elseif hasQualifer(claim, 'P3999') then
formattedValue = formattedValue .. ' ' .. formatTimePoint( claim, 'P3999' )
elseif hasQualifer(claim, 'P1319') or hasQualifer(claim, 'P1326') then
formattedValue = formattedValue .. ' ' .. formatTimePeriod( claim, 'P1319', 'P1326' )
end
if formattedValue ~= '' then
local tmp = nil
if calcRefs == 'Y' and useReferences[prop]
then
tmp = refs.render(frame, claim.references)
end
table.insert(formattedValues, formattedValue..(tmp or ''))
end
end
end
local resultat = table.concat(formattedValues, ", ")
local qid = mw.wikibase.getEntityIdForCurrentPage()
local langCode = mw.language.getContentLanguage():getCode()
if #formattedValues > 0 then
resultat = resultat .. formatEdit( qid, langCode, prop )
end
-- use of # to get count will fail in the future
if kollaps(#formattedValues) 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 _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("<span[^>]-wb%-edithandle[^>]*>.-</span>", "")
: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("''+", "")
:gsub("^%s+", "")
:gsub("%s+$", "")
:gsub("(%s)%s+", "%1")
stripped = lang:uc(stripped)
return stripped
end
function velg(frame, prop, param, link, qid)
local verdiFraFrame = getFrameValue(frame, param)
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 calcRefs = 'Y'
if verdiFraFrame ~= '' then
-- Hvis malargumentet er satt til en lokal verdi betyr det at det ikke er ønskelig
-- at feltet vises med lokal data, selv om det finnes data på Wikidata.
-- Ikke beregn referanser for at de ikke skal komme med i referanselisten
-- Lag Wikidata resultatene slik at det kan sammenlignes og lages vedlikeholdkategorier
calcRefs = 'N'
end
local verdiFraWikidata = getFormattedValues(frame, prop, param, link,calcRefs,qid)
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 verdiFraWikidata -- .. "[[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, qid )
assert( frame )
local lang = mw.language.getContentLanguage()
local verdiFraFrame = getFrameValue( frame, param )
local value = velg( frame, prop, param, link, qid )
displayName = displayName or lang:ucfirst(param)
if verdiFraFrame == "uten" 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.rad(frame)
assert( frame )
if frame.args['ref'] then
useReferences[frame.args['wdp']] = "frame.args['param']"
end
local qid = nil
if frame.args['qid'] and frame.args['qid'] ~= "" then
qid = frame.args['qid']
end
return rad(frame, frame.args['wdp'], frame.args['param'], nil, frame.args['tekst'], qid)
end
function p.values(frame)
assert( frame )
if frame.args['ref'] then
useReferences[frame.args['wdp']] = "frame.args['param']"
end
if frame.args['kollaps'] then
kollapsNum = tonumber(frame.args['kollaps'])
end
local qid = nil
if frame.args['qid'] and frame.args['qid'] ~= "" then
qid = frame.args['qid']
end
return velg(frame, frame.args['wdp'], frame.args['param'], true, qid)
end
-- nye metoder
local sprakNb = {
["nb"] = "bokmål",
}
local sprakNo = {
["nb"] = "", -- bokmål
["nn"] = " ([[nynorsk|nn]])",
["se"] = " ([[nordsamisk|se]])",
}
function formatUrl(url)
local urltext = url
local j1 = string.find(urltext,'//',1,true)
if j1 then urltext = string.sub(urltext,j1+2,string.len(urltext)) else urltext = '' end
if urltext ~= '' then
local i1 = string.find(urltext,'/',1,true)
if i1 then urltext = string.sub(urltext,1,i1-1) end
else
urltext = url
end
return "[" .. url .. " " .. urltext .. "]"
end
function p.formatLenke(sitelink,label)
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
function p.formatSpraak(snak)
assert( snak )
local spraakid = snak.datavalue.value.id or nil
if not spraakid then
return nil
end
local prop = getBestStatements("P218",spraakid) or getBestStatements("P220",spraakid) or nil
if prop then
if not prop[1] then
return ""
end
if not prop[1].mainsnak then
return ""
end
local kortnavn = prop[1].mainsnak.datavalue.value or nil
local sitelink = mw.wikibase.sitelink( spraakid )
return p.formatLenke(sitelink,kortnavn)
end
local lab = mw.wikibase.label(spraakid)
return lab
end
function formatQualifier(qual,pval)
if qual and pval then
local qv = qual[pval]
local snak = qv[1] or nil
if snak and snak.snaktype == "value" then
if pval == "P407" then
return p.formatSpraak(snak)
end
return mw.wikibase.formatValues(qv)
end
end
end
function filtrerMonolingualtext(claim,lang)
local snak = claim.mainsnak
if lang[snak.datavalue.value.language] then
return claim
end
return nil
end
function filtrerClaim(claim)
local snak = claim.mainsnak
if snak.snaktype ~= "value" then
return nil
end
local datatype = snak.datatype
if datatype == 'monolingualtext' then
return filtrerMonolingualtext(claim,sprakNo)
end
return claim
end
function filtrerClaims(claims)
local resultat = {}
for i, claim in ipairs(claims) do
local filtrert = filtrerClaim(claim)
if filtrert then
table.insert(resultat, filtrert)
end
end
return resultat
end
function sorterClaims(claims)
local resultat = {}
for i, claim in ipairs(claims) do
table.insert(resultat, claim)
end
return resultat
end
function dump(item)
return "<pre>" .. mw.text.jsonEncode(item, mw.text.JSON_PRETTY) .. "</pre>"
end
function formaterClaim(claim,claims)
local snak = claim.mainsnak
local qu = claim.qualifiers
local rf = claim.references
if true then
--return dump(claim.mainsnak)
end
local fmtClaim = mw.wikibase.formatValue(snak)
if snak.snaktype ~= "value" then
-- refValue = datatype .. ": Ingen verdi"
else
local datatype = snak.datatype
if true then
-- return dump(snak) .. mw.wikibase.formatValues(snak)
end
if datatype == 'url' then
fmtClaim = formatUrl(snak.datavalue.value)
local qt = formatQualifier(qu,"P407")
if qt and qt ~= "" then
fmtClaim = fmtClaim .. " (" .. qt .. ")"
end
elseif datatype == 'time' then
fmtClaim = norskDatoFraClaim(snak)
elseif datatype == 'monolingualtext' then
fmtClaim = fmtClaim .. sprakNo[snak.datavalue.value.language]
--elseif datatype == 'wikibase-item' then
--refValue = formatItem(property)
end
end
return fmtClaim
end
function formaterClaims(claims)
local formattedValues = {}
for i, claim in ipairs(claims) do
local resultat = formaterClaim(claim)
if resultat then
if useReferences[claim.mainsnak.property] then
local ref = refs.render(mw.getCurrentFrame(), claim.references)
resultat = resultat .. ref
end
table.insert(formattedValues, resultat)
end
end return formattedValues
end
function getWikidataVerdi(qid,pid)
local verdiListe = ""
local claims = getBestStatements(pid,qid)
local i = 0
local manglerOversettelse = false
local filtrerteClaims = filtrerClaims(claims)
local sorterteClaime = sorterClaims(filtrerteClaims)
local formattedValues = formaterClaims(sorterteClaime)
local sep = ", "
if kollaps(#formattedValues) then
sep = "<br/>"
end
verdiListe = table.concat(formattedValues, sep)
if kollaps(#formattedValues) then
verdiListe = string.format([[
<div class="mw-collapsible mw-collapsed">
<div class="sentrert">%s oppføringer</div>
<div class="mw-collapsible-content">%s</div>
</div>
]], #formattedValues, verdiListe)
end
return verdiListe
end
function p._verdi(frame,qid,pid,param,ref,sprak)
local verdi = getFrameValue(frame, param)
if verdi == "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 parameter spesifisert som uten]]"
end
if verdi ~= '' then
return verdi
end
useReferences[pid] = "ja"
if ref and ref == 'nei' then
useReferences[pid] = nil
end
verdi = getWikidataVerdi(qid,pid)
return verdi
end
function p.verdi(frame)
assert( frame )
if frame.args['kollaps'] then
kollapsNum = tonumber(frame.args['kollaps'])
end
local qid = nil
if frame.args['qid'] and frame.args['qid'] ~= "" then
qid = frame.args['qid']
end
local pid = frame.args['pid'] or frame.args['wdp'] or nil
local ref = frame.args['ref'] or nil
local param = frame.args['param'] or "xxx"
local sprak = frame.args['språk'] or nil
local resultat = p._verdi(frame,qid,pid,param,ref,sprak)
return resultat
end
return p