Module:Sandbox/ChaoticShadow/InfoboxBuilder: Difference between revisions
Content added Content deleted
No edit summary |
No edit summary |
||
(24 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
local getArgs = require('Module:Arguments').getArgs |
|||
local InfoboxBuilder = {} |
|||
local p = {} |
|||
InfoboxBuilder.__index = InfoboxBuilder |
|||
InfoboxBuilder.__tostring = InfoboxBuilder.tostring |
|||
function p.main(frame) |
|||
local tagmap = { |
|||
local args = getArgs(frame) |
|||
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 = '#000', |
|||
bg = 'transparent' |
|||
}, |
|||
params = { |
|||
{ name = 'bg color' }, |
|||
{ name = 'text color' } |
|||
}, |
|||
paramnames = { 'bg color', 'text color' }, |
|||
args = {}, |
|||
final_args = {}, |
|||
proto_infobox = {}, |
|||
infobox = mw.html.create('table'):addClass('infobox'), |
|||
finished = false |
|||
}, 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 both the text and background color of the header |
|||
-- @param param string |
|||
-- Parameter name that helps map the colors |
|||
-- @param color_table { text, bg } |
|||
-- text string |
|||
-- Same as setHeaderTextColor |
|||
-- bg string |
|||
-- Same as setHeaderBackgroundColor |
|||
-- @return self |
|||
-- The current object |
|||
function InfoboxBuilder:setHeaderColorsByParam(param, color_table) |
|||
if param == nil then |
|||
error("Parameter name must not be nil") |
|||
elseif color_table == nil then |
|||
error("Header color table must not be nil") |
|||
end |
|||
local raw_param_value = self.args[param] |
|||
local colors = color_table[raw_param_value] |
|||
if colors == nil then |
|||
return self |
|||
end |
|||
self:setHeaderTextColor(colors.text) |
|||
self:setHeaderBackgroundColor(colors.bg) |
|||
return self |
|||
end |
|||
--- Sets the infobox params |
|||
-- @param ... {{ name, func, default, should_hide }, ...} |
|||
-- 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 == nil and v.name == "" then |
|||
error("name must not be nil or empty") |
|||
end |
|||
if self.paramnames[v.name] then |
|||
error("name cannot be duplicate") |
|||
end |
|||
self.params[v.name] = { |
|||
['type'] = type(v.func), |
|||
func = v.func, |
|||
default = v.default |
|||
} |
|||
table.insert(self.paramnames, v.name) |
|||
end |
|||
return self |
|||
end |
|||
--- Sets the infobox arguments |
|||
-- @param args Frame |
|||
-- A frame object, passed in when invoked |
|||
-- @return self |
|||
-- The current object |
|||
function InfoboxBuilder:setArgs(args) |
|||
for k,v in pairs(args) do |
|||
if v ~= '' then |
|||
self.args[k] = v |
|||
end |
|||
end |
|||
if self.args['bg color'] then |
|||
self:setHeaderBackgroundColor(self.args['bg color']) |
|||
end |
|||
if self.args['text color'] then |
|||
self:setHeaderTextColor(self.args['text color']) |
|||
end |
|||
return self |
|||
end |
|||
--- Gets the content associated with a parameter |
|||
-- @param param string |
|||
-- The param name, not nil or empty |
|||
-- @return content string |
|||
-- A string containing the content |
|||
function InfoboxBuilder:getContent(param) |
|||
if param == nil or param == "" then |
|||
error("Param must not be nil or empty") |
|||
end |
|||
if self.final_args[param] then |
|||
return self.final_args[param] |
|||
end |
|||
local content = nil |
|||
local current_param = self.params[param] |
|||
if current_param == nil then |
|||
error(string.format("No such param: %s", param)) |
|||
end |
|||
local raw_param_value = self.args[param] or current_param.default |
|||
if raw_param_value == nil then |
|||
return raw_param_value |
|||
end |
|||
if current_param['type'] == 'function' then |
|||
content = current_param.func(raw_param_value) |
|||
elseif current_param['type'] == 'table' then |
|||
content = current_param.func[raw_param_value] |
|||
else |
|||
content = raw_param_value |
|||
end |
|||
self.final_args[param] = content |
|||
return content |
|||
end |
|||
--- Adds a header |
|||
-- @param arg { content, attr, colspan, rowspan, css } |
|||
-- content string or nil The wikitext to be rendered |
|||
-- attr {...} or nil The attributes of the cell in table form |
|||
-- colspan number or nil The colspan of the cell |
|||
-- roswpan number or nil The rowspan of the cell |
|||
-- css {...} or nil The css of the cell in table form |
|||
-- @return self |
|||
-- The current object |
|||
function InfoboxBuilder:addHeader(arg) |
|||
self:addSpacer() |
|||
local _cell = self.infobox:tag('tr'):tag('th'):attr('colspan', 30) |
|||
_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 |
|||
if arg.tag == 'th' then |
|||
_cell:wikitext(arg.content) |
|||
elseif arg.tag == 'argth' then |
|||
_cell:wikitext(self:getContent(arg.content)) |
|||
end |
|||
self:addSpacer() |
|||
return self |
|||
end |
|||
--- Adds an image, or switchable images |
|||
-- @param ... { { tag, content, title }, ... } |
|||
-- tag "artd" or "td" Whether or not an it is based off a parameter |
|||
-- content string The content or the parameter name |
|||
-- title string or nil The title, if using switchable images |
|||
-- @return self |
|||
-- The current object |
|||
function InfoboxBuilder:addImage(...) |
|||
local argt = ... |
|||
local _cell = self.infobox:tag('tr'):tag('td'):css('text-align', 'center') |
|||
local content = '?' |
|||
local actual_args = {} |
|||
for _,v in ipairs(argt) do |
|||
local c = v.content |
|||
if v.tag == 'argtd' then |
|||
c = self:getContent(c) |
|||
end |
|||
if c ~= nil then |
|||
table.insert(actual_args, { title = v.title, content = c }) |
|||
end |
|||
end |
|||
if #actual_args == 0 then |
|||
return self |
|||
elseif #actual_args < 2 then |
|||
content = actual_args[1].content |
|||
else |
|||
local t = {} |
|||
for _,v in ipairs(actual_args) do |
|||
table.insert(t, v.title .. '=' .. v.content) |
|||
end |
|||
content = mw.getCurrentFrame():callParserFunction({ |
|||
name = '#tag', |
|||
args = { 'tabber', table.concat(t, '|-|') } |
|||
}) |
|||
end |
|||
_cell:attr('colspan', 30) |
|||
_cell:wikitext(content) |
|||
return self |
|||
end |
|||
--- Adds a row, with columns up to 30 columns spanned |
|||
-- @param ... { { tag, content, hide, attr, colspan, rowspan, css }, ... } |
|||
-- tag "th", "td", "argth", "argtd" |
|||
-- A string containing one of the above, "th" or |
|||
-- "td" uses content as the wikitext, "argth" or |
|||
-- "argtd" uses content as the parameter name |
|||
-- to produce the suitable content |
|||
-- content string Content to be used as wikitext or a parameter |
|||
-- name |
|||
-- attr {...} or nil The attributes of the cell in table form |
|||
-- colspan number or nil The colspan of the cell |
|||
-- rowspan number or nil The rowspan of the cell |
|||
-- css {...} or nil The css of the cell in table form |
|||
-- @return self |
|||
-- The current object |
|||
function InfoboxBuilder:addRow(should_hide, ...) |
|||
local argt = ... |
|||
local actual_values = {} |
|||
for i,v in ipairs(argt) do |
|||
if v.tag == 'argth' or v.tag == 'argtd' then |
|||
table.insert(actual_values, self:getContent(v.content)) |
|||
end |
|||
end |
|||
return mw.dumpObject(argt) |
|||
-- if should_hide and #actual_values > 0 then |
|||
-- return self |
|||
-- end |
|||
-- local _row = self.infobox:tag('tr') |
|||
-- for i,v in ipairs(argt) do |
|||
-- local _cell = _row:tag(tagmap[v.tag] or 'td') |
|||
-- :attr('colspan', 30 / #argt) |
|||
-- 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.content)) |
|||
-- end |
|||
-- end |
|||
-- return self |
|||
end |
|||
--- Creates the 30-col layout |
|||
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 |
|||
--- Adds links to the bottom of the infobox |
|||
function InfoboxBuilder:addLinks() |
|||
if not self.finished then |
|||
self.finished = true |
|||
local links = { |
|||
"[[Template:%s|<span style=\"color: %s;\">View</span>]]", |
|||
"[[Template talk:%s|<span style=\"color: %s;\">Talk</span>]]" |
|||
} |
|||
self:addHeader{ |
|||
tag = 'th', |
|||
content = |
|||
string.format(links[1], self.name, self.headerColors.text) |
|||
.. " • " .. |
|||
string.format(links[2], self.name, self.headerColors.text) |
|||
} |
|||
end |
|||
end |
|||
--- Generates the infobox |
|||
-- @return string |
|||
-- The html of the infobox |
|||
function InfoboxBuilder:tostring() |
|||
if not self.finished then |
|||
self:addLinks() |
|||
end |
|||
self.finished = true |
|||
return frame:extensionTag{ name = 'youtube', content = args['yt'] } |
|||
return tostring(self.infobox) |
|||
end |
end |
||
return |
return p |
Latest revision as of 19:38, 19 August 2021
Documentation for this module may be created at Module:Sandbox/ChaoticShadow/InfoboxBuilder/doc