Module:Infobox: Difference between revisions

Fix tabs
(WIP - everything except categories is done, but module is untested)
(Fix tabs)
Line 17:
-- infobox_name: the name of the infobox
-- args : parameters from frame to pass through
-- Special args: version, default_version
-- Sets a meta table and creates a <div> tag wrapper
-- other fields are initialized in other functions
--]]
function Infobox.new(argsconfig, configparams, args)
local obj = setmetatable({
args_raw = args, -- parameters (uncleaned)
Line 29:
param_names = {}, -- ordered param list
params = {}, -- param definitions
max_buttons = 6, -- If there are more buttons than the max, the buttons will become a dropdown menu
default_version = 1, -- default version to populate the infobox
versions = nil, -- number of versions
version_names = {'INFOBOX_ERROR'}, -- title of each version (for selection and SMW); version_name[0] should not be used (base index should be 1)
rtable = nil, -- infobox table to return at the end
switch_datatable = nil, -- datatable for javascript for switch infoboxes
errors = {}, -- list of errors
},
Line 40:
obj:config(config)
obj:parse_versions()
obj:create()
obj:define_params(params)
return obj
end
Line 46 ⟶ 47:
 
function Infobox:config(...)
for k, v in pairs(...) do
if k == 'infobox_name' then
self.infobox_name = mw.ustring.gsub(v, '%s', '_')
Line 54 ⟶ 55:
end
if self.infobox_name == nil then
table.insert(self.errors, 'infobox_name needs to be defined in Infobox.new()\'s config!')
end
return self
Line 90 ⟶ 91:
end
end
self:parse_params()
--self:parse_categories()
return self
Line 110 ⟶ 111:
table.insert(self.version_names, self.args_raw['version'] or 'DEFAULT')
end
if self.versions == 1 then
table.insert(self.errors, 'There should be multiple versions or no versions. If defining a custom version name for a single entry, use "version=Name" instead of "version1=Name".')
self.versions = 0
end
if self.args_raw['default_version'] then
self.default_version = tonumber(self.args_raw['default_version'])
if self.default_version > self.versions then -- Make sure the default version exists
self.default_version = 1
end
end
end
 
Line 161 ⟶ 162:
--[[
Fetches a param value. If the value is nil, will return the default value instead
-- arg: a table generated from Infobox:param(), Infobox:raw_param() or Infobox:smw_param(), or else
-- version: '' for default, or else a number
--]]
function Infobox:get_param(arg, version)
if version == 0 then
version = ''
end
if type(arg) == 'table' then
local value = self[arg.property][arg.param_name..version]
if value == nil then -- Try to get default value if it exists
value = self[arg.property][arg.param_name]
end
return value
end
-- Other (int, string)
return arg
end
 
--[[
Calculates the parsed value of a param
-- param_name : string, name of the param
-- version : 0/'' for default, or else a number
-- smw : boolean, whether to use the smw function or default function
--]]
function Infobox:parse_param(param_name, version, smw)
if version == 0 then
version = ''
end
-- use func or smw_func depending on smw argument
local param = self.params[param_name]
local func = smw and param.smw_func or param.func
-- call functions by passing the param_name
if type(func) == 'function' then
return func(self:get_param(self.raw_param(param_name), version))
-- call tables by grabbing the function and reading the param arguments
elseif type(func) == 'table' then
local func_name = func.name
local func_params = func.params
local func_fetched_params = {}
for _, func_param in ipairs(func_params) do
table.insert(func_fetched_params, self:get_param(func_param, version))
end
return func_name(unpack(func_fetched_params))
else
table.insert(self.errors, 'Invalid param definition for '..param_name)
end
end
 
Line 213 ⟶ 214:
-- Calculate the param value for all params and all versions
for _, param_name in ipairs(self.param_names) do
for version=0, self.versions do
if version == 0 then
version = '' -- default version
end
end
-- Only get the parsed value if the raw value is defined
if self.args_raw[param_name..version] then
self.args_parsed[param_name..version] = self:parse_param(param_name, version, false)
-- Only get the smw value if smw_property is defined
if self.params[param_name].smw_property then
self.args_smw[param_name..version] = self:parse_param(param_name, version, true)
end
end
end
end
end
end
end
 
Line 286 ⟶ 287:
-----------
function Infobox:buttons()
if self.versions < 2 then
return
end
local buttons = self.rtable:tag('caption')
:tag('div')
:addClass('infobox-buttons')
:attr('data-default-version', self.default_version)
-- Dropdown list instead of buttons
if self.versions > self.max_buttons then
buttons:addClass('infobox-buttons-select')
end
for version=1, self.versions do
buttons:tag('span')
:attr('data-switch-index', version)
:attr('data-switch-anchor', '#'..self.version_names[version])
:addClass('button')
:wikitext(self.version_names[version])
end
for version=1, self.versions do
buttons:tag('span')
:attr('data-switch-index', version)
:attr('data-switch-anchor', '#'..self.version_names[version])
:addClass('button')
:wikitext(self.version_names[version])
end
end
Line 310 ⟶ 311:
-- Create infobox table
self.rtable = mw.html.create('table')
:addClass('plainlinks')
:addClass('infobox')
:addClass('infobox-'..self.infobox_name)
-- Add necessary class if switch infobox
if self.versions > 1 then
self.rtable:addClass('infobox-switch')
self.switch_datatable = mw.html.create('div')
:addClass('infobox-switch-resources')
:addClass('infobox-resources-'..self.infobox_name)
:addClass('hidden')
self.switch_datatable:tag('span'):wikitext('Versions: '..self.versions)
self.switch_datatable:tag('span'):wikitext('Default version: '..self.default_version)
self:buttons()
end
return self
end
 
 
function Infobox:add_switch_data(content)
-- Only check for params if there are multiple versions
if self.versions <= 1 then
return false
end
if type(content) ~= 'table' then
return false
end
-- Only if the data varies between the different versions
local first_value = self:get_param(cell_params.content, 1)
local all_same = true
for version=2, self.versions do
if first_value ~= self:get_param(cell_params.content, version) then
all_same = false
break
end
end
if all_same then
return false
end
-- Let's build the datatable
-- Prepend raw__ or smw$__ if not a parsed argument
local name = content.param_name
if content.property == 'args_raw' then
name = 'raw__' + name
end
if content.property == 'args_smw' then
name = 'smw__' + name
end
data_param = self.switch_datatable:tag('span'):attr('data-attr-param', name)
-- Add each version to the datatable
for version=1, self.versions do
text = self:get_param(content, version)
if text == nil then
text = edit
end
data_param:tag('span'):attr('data-attr-index', version):wikitext(text)
end
-- return the 'data-attr-param' name
return name
end
 
Line 440 ⟶ 441:
end
 
local content = Infobox:get_param(v.content, self.default_version)
if content == nil then
content = edit
end
_cell:wikitext(content)
 
-- Add the switch data if multiple values exist
data_attr_param = self:add_switch_data(v.content)
if data_attr_param then
_cell:attr('data-attr-param', data_attr_param)
end
end
 
-- allow classes to be defined on the whole row
if args.addClass then
_row:addClass(args.addClass)
end
 
Line 482 ⟶ 483:
-- Override tostring
function Infobox:tostring()
error_text = ''
if #self.errors > 0 then
for _, v in ipairs(self.errors) do
error_text = error_text..'<span class="mw-message-box-error">'..v..'</span>'
end
end
return tostring(self.rtable) .. tostring(self.switch_datatable) .. tostring(error_text)
end