Module:Sandbox/ChaoticShadow/InfoboxBuilder
Documentation for this module may be created at Module:Sandbox/ChaoticShadow/InfoboxBuilder/doc
local InfoboxBuilder = {}
InfoboxBuilder.__index = InfoboxBuilder
InfoboxBuilder.__tostring = InfoboxBuilder.tostring
local tagmap = {
th = 'th',
td = 'td',
argth = 'th',
argtd = 'td'
}
--- Create the infobox
-- @return obj metatable
-- a metatable describing the infobox
function InfoboxBuilder.new()
local obj = setmetatable({
name = '',
headerColors = {
text = '',
bg = ''
},
params = {},
paramnames = {},
args = {},
infobox = mw.html.create('table'):addClass('infobox')
}, InfoboxBuilder)
return obj
end
--- Set the infobox name, for use with bottom links
-- @param arg string
-- name of the template, not nil or empty
-- @return self
-- the current object
function InfoboxBuilder:setName(arg)
if arg == nil or arg == '' then
error("Template name must not be nil or empty")
end
self.name = arg
return self
end
--- Set the width of the infobox
-- @param arg string
-- width of the infobox, should be a valid value for the CSS "width"
-- property, not nil or empty
-- @return self
-- the current object
function InfoboxBuilder:setWidth(arg)
if arg == nil or arg == '' then
error("Width must not be nil or empty")
end
self.infobox:css('width', arg)
return self
end
--- Set the text color of the header
-- @param arg string
-- text color of the header, should be a valid value for the CSS
-- "color" property, not nil or empty
-- @return self
-- the current object
function InfoboxBuilder:setHeaderTextColor(arg)
if arg == nil or arg == '' then
error("Header text color must not be nil or empty")
end
self.headerColors.text = arg
return self
end
--- Set the background color of the header
-- @param arg string
-- background color of the header, should be a valid value for the
-- CSS "background-color" property, not nil or empty
-- @return self
-- the current object
function InfoboxBuilder:setHeaderBackgroundColor(arg)
if arg == nil or arg == '' then
error("Header background color must not be nil or empty")
end
self.headerColors.bg = arg
return self
end
--- Sets both the text and background color of the header
-- @param arg { text, bg }
-- text string
-- Same as setHeaderTextColor
-- bg string
-- Same as setHeaderBackgroundColor
-- @return self
-- the current object
function InfoboxBuilder:setHeaderColors(arg)
if arg == nil then
error("Header colors must not be nil")
end
self:setHeaderTextColor(arg.text)
self:setHeaderBackgroundColor(arg.bg)
return self
end
--- Sets the infobox params
-- @params ... {{ name, func, default }, ...}
-- name string
-- The name of the parameter, not nil cannot be duplicate
-- func function, table or string
-- A function that accepts the parameter as an argument and
-- returns a string, OR
-- A table that has the parameter as a key, OR
-- An empty string
-- default string or nil
-- The default value if no argument is given
-- @return self
-- the current object
function InfoboxBuilder:setParams(...)
for i, v in ipairs(...) do
if v.name and v.name ~= "" then
if self.paramnames[v.name] == nil then
if type(v.func) == 'function' or
type(v.func) == 'table' or
type(v.func) == 'string'
then
self.params[v.name] = {
['type'] = type(v.func),
func = v.func,
default = v.default
}
table.insert(self.paramnames, v.name)
else
error("func must be of type \"function\", \"table\", or " ..
"\"string\"")
end
else
error("name cannot be duplicaate")
end
else
error("name must not be nil or empty")
end
end
return self
end
function InfoboxBuilder:setArgs(args)
for k,v in pairs(args) do
self.args[k] = v
end
return self
end
function InfoboxBuilder:getContent(v)
local content = '?'
local argparams = self.params[v.content]
local arg = self.args[v.content] or self.params[v.content].default or ''
if argparams['type'] == 'function' then
content = self.params[v.content].func(arg)
elseif argparams['type'] == 'table' then
content = self.params[v.content].func[arg]
elseif argparams['type'] == 'string' then
content = arg
end
return content
end
function InfoboxBuilder:addHeader(arg)
local _cell = self.infobox:tag('tr'):tag('th')
_cell:css({
['text-align'] = 'center',
['background-color'] = self.headerColors.bg,
['color'] = self.headerColors.text
})
if arg.attr then
_cell:attr(arg.attr)
end
if arg.colspan then
_cell:attr('colspan', arg.colspan)
end
if arg.rowspan then
_cell:attr('rowspan', arg.rowspan)
end
if arg.css then
_cell:css(arg.css)
end
_cell:wikitext(arg.content)
return self
end
--[[
{ content, title }
]]--
function InfoboxBuilder:addImage(...)
local argt = ...
local _cell = self.infobox:tag('tr'):tag('td')
local content = '?'
if #argt < 2 then
content = self:getContent(argt[1]) -- tables start at 1
else
local t = {}
for i, v in ipairs(argt) do
table.insert(t, i, v.title .. "=" .. self:getContent(v))
end
content = mw.getCurrentFrame()
:callParserFunction({
name = '#tag',
args = {
'tabber',
table.concat(t, "|-|")
}
})
end
_cell:attr('colspan', 30)
_cell:wikitext(content)
return self
end
function InfoboxBuilder:addRow(...)
local _row = self.infobox:tag('tr')
for i, v in ipairs(...) do
mw.log(v.tag)
mw.log(tagmap[v.tag])
local _cell = _row:tag(tagmap[v.tag] or 'td')
if v.attr then
_cell:attr(v.attr)
end
if v.colspan then
_cell:attr('colspan', v.colspan)
end
if v.rowspan then
_cell:attr('rowspan', v.rowspan)
end
if v.css then
_cell:css(v.css)
end
if v.tag == 'th' or v.tag == 'td' then
_cell:wikitext(v.content)
elseif v.tag == 'argth' or v.tag == 'argtd' then
_cell:wikitext(self:getContent(v))
end
end
return self
end
function InfoboxBuilder:addSpacer()
local spacer = self.infobox:tag('tr')
for i=1,30,1 do
spacer:tag('td')
:attr('colspan', 1)
:css('width', 'calc(100% / 30)')
end
end
function InfoboxBuilder:tostring()
return tostring(self.infobox)
end
return InfoboxBuilder