Modul:Sandkasse/Poul G/Dataliste
Udseende
Datalist is a module intended to support presentation ordered sequences (lists) of different dataitems.
The presentation can take three forms:
infobox
- the boxes normally found at the right side of the top of an article with key facts about the subject.section
- a section presented in the article. This section will be more fact centered and less prose-like than other sections. Eg an article about an engine could have a secion covering specifications such as dimension, volume, performance etc.TODOtable
- a tabular form, where the data of the subject of the article is comparet to relevant other subjects.
Datalist is ment to be "wrapped" in a template, where the template controls the behaviour of Datalist.
The data presented can originate from Wikidata properties (property
) or from parameters supplied from the calling page (data
).
Parameters
[rediger kildetekst]Parameters | Explanation | Example |
---|---|---|
Headlines above it all | ||
title titleclass titlestyle
|
Specifies the title to appear before the datalist. For infobox it will appear above the table. For setion it will generate a heading (==title== ) for the section.
|
title=Engine |
above aboveclass abovestyle
|
Specifies something to appear before the datalist, but after the title. For infobox it will generate a heading inside the box. For section it will generate normal text in the beginning of the section.
| |
Value-lines | # denotes numerically indexed parameters; they will be presented in their numerical order. [#] denotes parameters, which can be indexed or specified as a default value for all instances. If the same index are used for multiple purposes, the priority will be header, image & itemformatter/data/property .
| |
header# headerclass[#] headerstyle[#]
|
Specifies a headline to appear above a subsection. Intended for use, when many values might clutter the view. | header10=Developement and intro |
image# imageclass[#] imagestyle[#]
|
Specifies an image to be displayed at the given position. The specification should include with and could include caption and alt-text. Images specified in Wikidata can not be included this way; use the data-parameter instead.
|
image20=[[File:Harley-Davidson-WL.jpg|200px|Harley-Davidson 1947]] |
label# labelclass[#] labelstyle[#]
|
Specifies the label to appear before the value. If no label is given, and a wikidata-property is specified, the wikidata-label will be used.
|
label30=Designer |
data#
|
Specifies the name of the field to search for a value from the calling page. | data30=designer
and in the item-page: designer=Davidson |
property# link[#] rank[#] propertyformatter#
|
Specifies the property (attribute) to retrive from wikidata. Formatting of the value is delegated to Module:Wikidatas formatStatementsFromLua. If link, rank or (property-) formatter are specified, they are feed to Wikidata.formatStatementsFromLua. | property40=P22 |
itemformatter#
|
Specifies a formatter to generate a value based on the complete item. The format is Module.function. Intended for use, when more than one attribute is needed. The value vil override values found by property .
|
itemformatter50=Wikidata.lifespan |
priority[#]
|
As per. default, specified values (data ) and takes precedence over values found in wikidata (property/itemformatter ). Priority can be given to wikidata with this parameter.
|
priority=wikidata |
Tail | ||
below belowclass belowstyle
|
Specifies something to appear below the datalist. For infobox it will generate some centered text at the bottom of the box. For section it will generate normal text in the end of the section.
| |
Shared | ||
item[#]
|
Specifies the wikidata-item to fetch data from. Default the item linked to the displayed page will be used. Must be specified for item2++ in table .
|
item2=Q42 |
More Comprehensive Examples
[rediger kildetekst]Infobox
[rediger kildetekst]Lua-fejl i linje 107: attempt to concatenate local 'propValue' (a nil value).
{{#invoke:Sandkasse/Poul G/Dataliste|infobox | item = Q544661 | above = Svævefly<br/>Rolladen-Schneider LS4 | abovestyle = background: #87CEEB; font-size: larger; | link = local | rank = valid | image10 = [[file:Ls-4.JPG|300px|... caption ...]] | label20 = Class | property20 = P279 | label30 = Country | property30 = p17 | propertyformatter30 = iconItem | label40 = Manufacturer | property40 = p176 | label50 = Series length | property50 = p1092 | label51 = i DK | data51 = antalDK | antalDK = Ca. 30 | label60 = Designer | property60 = p287 | label70 = First flight | property70 = p606 | label90 = Handicap | data90 = handicap | handicap = 103.8 (EGU) | below = Demonstration only }}
Section
[rediger kildetekst]Lua-fejl i Modul:Math på linje 517: attempt to call field '?' (a nil value).
Table
[rediger kildetekst]TBS
-- test Bruger:Poul G/Infobox
local i18n = require('Module:Sandkasse/Poul G/I18n').new()
.append("Module:Sandkasse/Poul G/Dataliste")
.append{
["error-item-not-found"] = "item not found",
["errors"] = {
["item-not-found"] = "Ukendt emne (item).",
["no-frame"] = "Ingen system-ramme (frame) angivet.",
},
["somevalue"] = "''unknown value''",
["novalue"] = "''no value''",
["wikidata-differs"] = "different value in Wikidata",
["localdata-differs"] = "different local value",
}
local config = {
paramWithDefault = {
link = true,
rank = true,
},
imageProperties = {
p18 = true, P18 = true, -- image
p94 = true, P94 = true, -- coat of arms image
p154 = true, P154 = true, -- logo image
-- TODO https://www.wikidata.org/wiki/Wikidata:Requests_for_comment/Image_properties:_many_properties_or_many_qualifiers
},
}
--[[
local content = {
["p31=q5"] = { -- is a person
"p18", -- image
"p106", -- profession
"p569", -- date of birth
"p570", -- date of death
},
}
]]
local wikidata = require('Module:Wikidata/sandkasse') -- TODO
-- returns a sorted table with the suffixes found in templateArgs
-- example: getIndexes({"a5"=1,"b4"=2,"c16"=3,"c2"=4},{"a","c"}) --> {2,5,16}
local function getIndexes(templateArgs,prefixes)
-- extract removing duplicates
local keys = {}
for param, v in pairs(templateArgs) do
for __, prefix in pairs(prefixes) do
local num = tostring(param):match('^' .. prefix .. '([1-9]%d*)$')
if num then keys[tonumber(num)] = true end
end
end
if not #keys then return nil end
-- move to values and sort
local nums = {}
for key, _ in pairs(keys) do
table.insert(nums,key)
end
table.sort(nums)
return nums
end
-- pushes headers, lines and tailing to listener in top-down-left-right order
-- returns nil on success, otherwise error-info
local function datalistGenerator(frame, listener)
local templateArg = ( frame and frame.args ) or {}
local pageArg = ( frame and frame:getParent() and frame:getParent().args ) or templateArg
if pageArg and #pageArg == 0 then pageArg = templateArg end
-- grabs a parameter from templateArg; index will be appended if positive; if negative the absolute value will be tested first, then prefix without index
local function pick(prefix, index)
if type(index) ~= "number" or index == 0 then
return templateArg[prefix]
elseif index > 0 then
return templateArg[prefix..index]
else
return templateArg[prefix..(-index)] or templateArg[prefix]
end
end
local item, item1id = {}, pick("item",-1)
if item1id then
item[1] = mw.wikibase.getEntity(item1id:upper())
else
item[1] = mw.wikibase.getEntity() -- use wikidata associated to this page
end
-- TODO item[2+] (tabular)
local indexes = getIndexes(templateArg,{"header","image","data","property","itemformatter"})
if pick("title") then listener.title(pick("title"), pick("titleclass"), pick("titlestyle")) end
if pick("above") then listener.above(pick("above"), pick("aboveclass"), pick("abovestyle")) end
for _, index in pairs(indexes) do
-- listener.error("index = "..index)
if pick("header",index) then -- header-case
listener.header(pick("header",index), pick("headerclass",-index), pick("headerstyle",-index))
elseif pick("image",index) then -- image-case
listener.image(pick("image",index), pick("imageclass",-index), pick("imagestyle",-index))
elseif config.imageProperties[pick('property',index)] then
local propId = pick( 'property', index )
local propValue = wikidata.formatStatementsFromLua{ entity = item[1], property = propId, rank = 'one', }
listener.value('TODO image', nil, nil, propId .. " /" .. propValue .. "/ " )
elseif pick("data",index) or pick("property",index) or pick("itemformatter",index) then -- label/value-cases
-- listener.error("value")
local label, labelclass, labelstyle = pick("label",index), pick("labelclass",-index), pick("labelstyle",-index)
-- value specified; retrieve from the page calling the template
local dataId = pick("data",index)
local dataValue = dataId and pageArg[dataId]
if dataValue == "" then dataValue = nil end
-- property specified; retrieve from wikidata
local propId, propValue = pick("property",index)
if propId and not item[1] then return i18n.error("error-item-not-found") end
if propId then
propId = propId:upper() -- wikidata keys are uppercase
local wdArg = {
entity = item[1],
property = propId,
formatter = pick("propertyformatter",index),
}
setmetatable( wdArg, { __index = function( t, key )
if config.paramWithDefault[key] then
return pick( key, -index )
else
return pick( key, index )
end
end } )
propValue = wikidata.formatStatementsFromLua( wdArg )
if propValue == "" then propValue = nil end
-- take label from the property, if not given
if propValue and not label then
label = mw.language.getContentLanguage():ucfirst(mw.wikibase.label(propName) or '') -- TODO language fallback
end
end
-- itemformatter given; let it replace property
local formatter = pick("itemformatter",index)
if formatter then
formatter = mw.text.split(formatter,".",true)
formatter = require("Module:"..formatter[1])[formatter[2]] -- TODO errorhandling
propValue = formatter(item[1])
end
if propValue == "" then propValue = nil end
-- choose if needed
local showValue = dataValue or propValue
if dataValue and propValue and dataValue ~= propValue then
if pick("priority",-index) == "property" then
showValue = propValue .. '<sup title="'..i18n('localdata-differs')..'">Δ</sup>'
else
showValue = showValue .. '<sup title="'..i18n('wikidata-differs')..'">Δ[[:d:'..item[1]["id"]..'|WD]]</sup>' -- TODO note
end
end
-- TODO include empty values
if showValue then
listener.value(label,labelclass,labelstyle,showValue)
end
else
listener.error("unhandled index "..index)
end
end
if pick("below") then listener.below(pick("below"), pick("belowclass"),pick("belowstyle")) end
-- TODO notes
end
local Datalist = {}
function Datalist.infobox( frame )
local buffer = mw.html.create("table")
buffer
:addClass("infobox")
:css('width', '22em')
local listener = {
title = function(text, cls, style)
buffer
:tag('caption')
:addClass(cls)
:cssText(style)
:wikitext(text)
end,
above = function(text,cls,style)
buffer
:tag('tr')
:tag('th')
:attr('colspan', 2)
:addClass(cls)
:css('text-align', 'center')
:css('font-size', '125%')
:css('font-weight', 'bold')
:cssText(style)
:wikitext(text)
end,
header = function(text,cls,style)
buffer
:tag('tr')
:tag('th')
:attr('colspan','2')
:addClass(cls)
:css('text-align', 'center')
:cssText(style)
:wikitext(text)
end,
image = function(code,cls,style)
buffer
:tag('tr')
:tag('td')
:attr('colspan',2)
:addClass(cls)
:css('text-align', 'center')
:cssText(style)
:wikitext(code)
end,
value = function(label,labelclass,labelstyle,text)
local row = buffer:tag('tr')
if label then
row
:tag('th')
:addClass(labelclass)
:cssText(labelstyle)
:wikitext(label)
end
local dataCell = row:tag('td')
if not label then
dataCell
:attr('colspan', 2)
:css('text-align', 'center')
end
dataCell
:wikitext(text)
end,
below = function(text,cls,style)
buffer
:tag('tr')
:tag('td')
:attr('colspan', 2)
:addClass(cls)
:css('text-align', 'center')
:cssText(style)
:newline()
:wikitext(text)
end,
error = function(text)
buffer
:tag('tr')
:tag('td')
:attr('colspan', 2)
:addClass('error')
:css('text-align', 'center')
:wikitext(text)
end,
}
local err = datalistGenerator(frame, listener)
return err or tostring(buffer)
end
function Datalist.section(frame)
local buffer = mw.html.create("table")
local listener = {
title = function(text, cls, style)
buffer
:tag('h2') -- TODO control level by parameter
:addClass(cls)
:cssText(style)
-- :addClass('mw-headline') -- TODO check in TOC
:wikitext(text)
end,
above = function(text,cls,style)
buffer
:tag('p')
:addClass(cls)
-- :cssText(style)
:wikitext(text)
end,
header = function(text,cls,style)
buffer
:tag('h3') -- TODO control level by parameter
-- :addClass('mw-headline')
:addClass(cls)
-- :cssText(style)
:wikitext(text)
end,
image = function(code,cls,style)
buffer
:tag('div')
:addClass(cls)
:css('text-align', 'center')
:cssText(style)
:wikitext(code)
end,
value = function(label,labelclass,labelstyle,text)
local row = buffer:tag('p')
if label then
row
:tag('span')
:addClass(labelclass)
:cssText(labelstyle)
:wikitext(label..": ") -- TODO i18n
end
local dataCell = row:tag('span')
dataCell
:wikitext(text)
end,
below = function(text,cls,style)
buffer
:tag('p')
:addClass(cls)
:cssText(style)
:wikitext(text)
end,
error = function(text)
buffer
:tag('div')
:addClass('error')
-- :css('text-align', 'center')
:wikitext(text)
end,
}
datalistGenerator(frame, listener)
return tostring(buffer)
end
function Datalist.spam(arg,options)
return "spam " .. mw.dumpObject{arg=arg,options=options}
end
return Datalist