Modul:Statements
Utseende
Statements er en eksperimentell modul for å sette inn verdier fra utsagn i eksisterende infobokser, og er et alternativ til parserfunksjonen {{#statements}}
. Modulen gjør nesten det samme, men kan også vise kvalifikatorer og referanser. Den har to former; text
som gir ren tekst og html
som gir html.
Bruk
[rediger kilde]Selv om det er mulig å kalle funksjoner direkte fra andre moduler, så er formålet at modulens funksjoner skal kalles direkte fra maler.
Metoder
[rediger kilde]- text
- Forenklet utlegg, men tilstrekkelig for testing av eksistens av verdier. Vil ikke vise kvalifikatorer og referanser.
- html
- Fullt utlegg, med lenking, kvalifikatorer og referanser.
Parametre
[rediger kilde]- anonyme
- Tittel eller P-id for angivelse av egenskapen som skal brukes.
- from
- Tittel eller P-id for angivelse av egenskapen som skal brukes. Hvis parameteren mangler eller er tom så vil det koblede elementet brukes.
Eksempler
[rediger kilde]Kode | Utlegg |
---|---|
; [[Marokko]]s {{P|31}}
: tekst: {{#invoke:Statements|text|P31|from=Q1028}}
: html: {{#invoke:Statements|html|P31|from=Q1028}}
; Referanser
<references />
|
|
; [[Marokko]]s {{P|1082}}
: tekst: {{#invoke:Statements|text|P1082|from=Q1028}}
: html: {{#invoke:Statements|html|P1082|from=Q1028}}
; Referanser
<references />
|
|
; [[Marokko]]s {{P|2046}}
: tekst: {{#invoke:Statements|text|P2046|from=Q1028}}
: html: {{#invoke:Statements|html|P2046|from=Q1028}}
; Referanser
<references />
|
|
; [[Knut Hamsun]]s {{P|26}}
: tekst: {{#invoke:Statements|text|P26|from=Q40826}}
: html: {{#invoke:Statements|html|P26|from=Q40826}}
; Referanser
<references />
|
|
; [[Knut Hamsun]]s {{P|40}}
: tekst: {{#invoke:Statements|text|P40|from=Q40826}}
: html: {{#invoke:Statements|html|P40|from=Q40826}}
; Referanser
<references />
|
|
; [[Arne E. Holm]]s {{P|40}}
: tekst: {{#invoke:Statements|text|P40|from=Q11959015}}
: html: {{#invoke:Statements|html|P40|from=Q11959015}}
; Referanser
<references />
|
|
Pågående arbeid
[rediger kilde]Det er noen forhold som trenger ytterligere avklaring, ikke minst om brukere har andre ønsker.
- 1. Seriekomma og konjunksjon
- Lister bruker seriekomma og konjunksjonen «og» («and»). Det er ikke alltid dette er riktig, men i norsk språk brukes konjunksjonene «og» («and») og «eller» («or») litt om hverandre. Nettsamfunnet har divergerende meninger om hva som er rett, se Wikipedia:Torget/Arkiv/2019/januar#Opplistinger.
- 2. Formatering av tall
- Tall bruker standard formatering,det vil si med mellomrom, slik det genereres av funksjonen
mw.message.numParam()
. Fordi standard formatering ikke bruker w:non-breaking space så kan vi få linjebrekk inne i tall. Det optimale ville vært å bruke narrow non-breaking space, men da vil utlegget bli forskjellig for tall i infoboksen og brødteksten.
- 3. Overstyring av navn på enheter
- Enhetens etikett (label), eller lang form, kan hentes effektivt. Enhetens kortform er derimot lastmessig kostbart å hente, her må hele elementet hentes inn, og derfor er det mulig å predefinere disse. Dette er mest aktuelt for SI-enheter. Eksempelet med areal er litt uheldig da «km²» ikke er en korrekt SI-enhet.
- 4. Forenkling av parentes
- Kvalifikatorer bruker en standardform, men de burde forenkles på samme vis som i brødtekst. Typisk forenkles startdatoen på et ekteskap til året, og navnet på et barn er kun fornavnet. Dette skaper imidlertid tvetydighet. Hvis to ekteskap treffer på samme året så må presisjonen økes med måned eller full dato. Tilsvarende for barn, har de forskjellig etternavn må dette angis. Vi kan unngå problemet ved å plassere fullform i en hoverboble, men det fungerer kun for html-formatet.
- 5. Angivelse av perioder
- Perioder angis normalt som «startdato–sluttdato», men det får vi ikke til med standardformatet. Dette er et eksempel på et unntak fra normalt utlegg, og egenskapene skal tas ut av datasettet og håndteres spesielt.
- 6. Ingen verdi og ukjent verdi
- Oppføringer med «ingen verdi» og «ukjent verdi» kan tilpasses egenskapen, slik at navnene blir mer naturlige. Hvis oppføringen for barn (P40) har «ukjent verdi» så blir det isteden vist «ukjent barn» i siste eksempelet.
Notater
[rediger kilde]Typisk kall i wikikode
{{#invoke:Statements|text|P40|from=Q11959015}}
Typisk testkall i consol
=mw.dumpObject(p.getFormattedValues(mw.getCurrentFrame(),'P2046', 'areal',true,'Q1028'))
Formatering av store tall
=mw.message.newRawMessage('Format: $1'):numParams(mw.wikibase.getBestStatements('Q4115189','P2067')[1].mainsnak.datavalue.value.amount):plain()
--- Statements…
-- @table local library variable
local libUtil = require 'libraryUtil'
local libRefs = require 'Module:Reference score'
local i18n = mw.loadData( 'Module:Statements/i18n' )
local h = {}
function h.findUnit( unit )
-- is this a simple countable
if unit == '1' then
return nil
end
-- this is not well-defined
local uri = mw.uri.new( unit )
if not uri then
return unit
end
local entityId = string.match( uri.path, 'Q%d+$')
if not entityId then
return unit
end
local label = mw.wikibase.getLabel( entityId )
local pKey = string.format( '%s-%s', 'statements-unit', string.lower( entityId ) )
local raw = i18n[pKey]
if raw then
local msg = mw.message.newRawMessage( raw )
if msg:exists() then
return label, msg:plain()
end
end
return label
end
function h.findMessage( key, property )
if not property then
local raw = i18n[key] or mw.ustring.format( '[%s]', key )
return mw.message.newRawMessage( raw )
end
local propertyId = mw.wikibase.resolvePropertyId( property )
if not propertyId then
local raw = i18n[key] or mw.ustring.format( '[%s]', key )
return mw.message.newRawMessage( raw )
end
local pKey = string.format( '%s-%s', key, string.lower( propertyId ) )
local raw = i18n[pKey] or i18n[key] or mw.ustring.format( '[%s]', key )
return mw.message.newRawMessage( raw )
end
function h.exists( handler, type )
if not handler then
return nil, mw.html.create( 'span' )
:addClass( 'warning' )
:wikitext( mw.message.newRawMessage( i18n['statements-not-implemented'], type ):plain() )
end
return handler
end
-- @field datatypes holds handlers for mainsnaks
h.snaktypes = {}
h.snaktypes['somevalue'] = {
text = function( snak )
return h.findMessage( 'statements-somevalue', snak.property ):plain()
end,
html = function( snak )
return mw.html.create( 'span' )
:wikitext( h.findMessage( 'statements-somevalue', snak.property ):plain() )
end,
}
h.snaktypes['novalue'] = {
text = function( snak )
return h.findMessage( 'statements-novalue', snak.property ):plain()
end,
html = function( snak )
return mw.html.create( 'span' )
:wikitext( h.findMessage( 'statements-somevalue', snak.property ):plain() )
end,
}
h.snaktypes['value'] = {
text = function( snak, property )
local handler = h.datatypes[snak.datatype]
if not handler then
return ''
end
return handler.text( snak.datavalue, snak.property )
end,
html = function( snak, property )
local handler, err = h.exists( h.datatypes[snak.datatype], snak.datatype )
if not handler then
return err
end
return mw.html.create( 'span' )
:node( handler.html( snak.datavalue, snak.property ) )
end,
}
-- @field datatypes holds handlers for datavalues
h.datatypes = {}
h.datatypes['wikibase-item'] = {
text = function( datavalue, property )
local handler = h.valuetypes[datavalue.type]
if not handler then
return ''
end
return handler.text( datavalue.value, property )
end,
html = function( datavalue, property )
local handler, err = h.exists( h.valuetypes[datavalue.type], datavalue.type )
if not handler then
return err
end
return handler.html( datavalue.value, property )
end
}
h.datatypes['quantity'] = {
text = function( datavalue, property )
local handler = h.valuetypes[datavalue.type]
if not handler then
return ''
end
return handler.text( datavalue.value, property )
end,
html = function( datavalue, property )
local handler, err = h.exists( h.valuetypes[datavalue.type], datavalue.type )
if not handler then
return err
end
return handler.html( datavalue.value, property )
end
}
-- @field datatypes holds handlers for values
h.valuetypes = {}
h.valuetypes['wikibase-entityid'] = {
-- @field text handler for generating a plain text layout
text = function( value, property )
local label = mw.wikibase.getLabel( value.id )
return label or value.id
end,
-- @field html handler for generating a fancy html layout
html = function( value, property )
local label = mw.wikibase.getLabel( value.id )
local sitelink = mw.wikibase.getSitelink( value.id )
local html = mw.html.create( 'span' )
:addClass( 'mw-wikibase-entityid' )
if sitelink then
html:addClass( 'extiw' )
end
return html:wikitext( mw.ustring.format( '[[%s|%s]]',
sitelink or mw.ustring.format( 'd:%s', value.id ),
label or value.id ) )
end
}
h.valuetypes['quantity'] = {
-- @field text handler for generating a plain text layout
text = function( value )
local long, short = h.findUnit( value.unit )
local msg = mw.message.newRawMessage( i18n['statements-format-quantity-scalar'] )
:numParams( tonumber( value.amount ) )
:params( short or long or '' )
return msg:plain()
end,
-- @field html handler for generating a fancy html layout
html = function( value )
local long, short = h.findUnit( value.unit )
local msg = nil
if value.amount then
msg = h.findMessage( 'statements-format-quantity-scalar', property )
:numParams( tonumber( value.amount ) )
:params( short or long or '' )
elseif value.lowerBound or value.upperBound then
local lower = value.lowerBound and h.findMessage( 'statements-format-quantity-range-lower-bound', property )
:numParams( tonumber( value.lowerBound ) )
or h.findMessage( 'statements-format-quantity-range-lower-open', property )
local upper = value.upperBound and h.findMessage( 'statements-format-quantity-range-upper-bound', property )
:numParams( tonumber( value.upperBound ) )
or h.findMessage( 'statements-format-quantity-range-upper-open', property )
msg = h.findMessage( 'statements-format-quantity-range', property )
:params( lower, upper, short or long )
else
msg = h.findMessage( 'statements-format-quantity-empty', property )
end
return mw.html.create( 'span' )
:addClass( 'mw-wikibase-quantity' )
:wikitext( msg:plain() )
end
}
--- Get entity.
-- This convenience function encapsulates base functionality,
-- and makes it possible to use both Q-ids and titles to reference
-- entities.
-- @throw on wrong argument.
-- @tparam nil|string entityIdOrTitle a string that can be both a Q-id and title
-- @treturn entity
function h.getEntity( entityIdOrTitle )
libUtil.checkType( 'Statements:getEntity', 1, entityIdOrTitle, 'string', true )
local entity = nil
if entityIdOrTitle then
if mw.ustring.match( entityIdOrTitle, '^Q%d+$' ) then
entity = mw.wikibase.getEntity( entityIdOrTitle )
elseif mw.ustring.match( entityIdOrTitle, '^.$' ) then
entity = mw.wikibase.getEntityIdForTitle( entityIdOrTitle )
end
end
if not entity then
entity = mw.wikibase.getEntityIdForCurrentPage()
end
return entity
end
--- Render plain text form.
-- This is an access point for use in a template.
-- Will not generate visible warnings.
-- @throw on wrong argument.
-- @tparam nil|table frame
-- @treturn wikitext
function h.text( frame )
libUtil.checkType( 'Statements:text', 1, frame, 'table', true )
frame = mw.getCurrentFrame()
local entity = h.getEntity( frame.args['from'] )
if not entity then
return 'no entity'
end
local statements = entity:getBestStatements( frame.args[1] )
if not statements then
return 'no statements'
end
local t = {}
for k,v in ipairs( statements ) do
if v.type == 'statement' then
local handler = h.snaktypes[k..':'..v.mainsnak.snaktype] or h.snaktypes[v.mainsnak.snaktype]
if handler then
local item = handler.text( v.mainsnak )
if item then
table.insert( t, item )
end
local refs = ''
end
end
end
if #t == 0 then
return '#t == 0'
elseif #t == 1 then
return t[1]
elseif #t == 2 then
return mw.ustring.format( '%s %s %s', t[1], mw.message.newRawMessage( i18n['statements-combiner'] ):plain(), t[2] )
end
local punctuation = mw.message.newRawMessage( i18n['statements-punctuation'] ):plain()
punctuation = punctuation .. ' '
local last = table.remove( t )
local first = table.concat( t, punctuation )
return mw.ustring.format( '%s, %s %s', first, mw.message.newRawMessage( i18n['statements-combiner'] ):plain(), last )
end
function h.qualifiers( snaks )
local keys = {}
for k,_ in pairs( snaks or {} ) do
table.insert( keys, k )
end
if #keys == 0 then
return ''
end
local t = {}
for _,k in pairs( mw.wikibase.orderProperties( keys ) ) do
-- lua keeps injection order
t[k] = snaks[k]
end
local wiki = mw.wikibase.formatValues( t )
if not wiki or wiki == '' then
return ''
end
local html = mw.html.create( 'span' )
:addClass( 'qualifiers' )
:wikitext( ' (', wiki, ') ' )
return html
end
--- Render fancy html form.
-- This is an access point for use in a template.
-- Generates visible warnings.
-- @throw on wrong argument.
-- @tparam nil|table frame
-- @treturn wikitext
function h.html( frame )
frame = mw.getCurrentFrame()
local entity = h.getEntity( frame.args['from'] )
if not entity then
return mw.html.create( 'span' )
:addClass( 'warning' )
:wikitext( mw.message.newRawMessage( i18n['statements-no-entity'] ):plain() )
end
local statements = entity:getBestStatements( frame.args[1] )
if not statements then
return mw.html.create( 'span' )
:addClass( 'warning' )
:wikitext( mw.message.newRawMessage( i18n['statements-no-statements'] ):plain() )
end
local t = {}
for _,v in ipairs( statements ) do
if v.type == 'statement' then
local handler = h.snaktypes[v.mainsnak.snaktype]
if handler then
local item = handler.html( v.mainsnak )
if item then
item:node( h.qualifiers( v.qualifiers ) )
item:wikitext( libRefs.render( frame, v.references ) )
table.insert( t, item )
end
end
end
end
local html = mw.html.create( 'span' )
:addClass( 'mw-statement' )
if #t == 0 then
return html
elseif #t == 1 then
return html:node( t[1] )
elseif #t == 2 then
return html:node( t[1] ):wikitext( ' ', mw.message.newRawMessage( i18n['statements-combiner'] ):plain(), ' ' ):node( t[2] )
end
local last = table.remove( t )
local punctuation = mw.message.newRawMessage( i18n['statements-punctuation'] ):plain()
for _,v in ipairs( t ) do
html:node( v ):wikitext( punctuation, ' ' )
end
html:wikitext( ' ', mw.message.newRawMessage( i18n['statements-combiner'] ):plain(), ' ' ):node( last )
return html
end
return h