Editing Module:Infobox
Jump to navigation
Jump to search
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 4: | Line 4: | ||
-- <nowiki> |
-- <nowiki> |
||
-- Edit button for unknown params |
|||
require('strict') |
|||
local editbutton = require('Module:Edit button') |
local editbutton = require('Module:Edit button') |
||
local |
local edit = editbutton("'''?''' (edit)") |
||
local pagename = mw.title.getCurrentTitle().fullText |
|||
local Infobox = {} |
local Infobox = {} |
||
Line 13: | Line 15: | ||
--[[ |
--[[ |
||
Infobox class |
Infobox class |
||
-- infobox_name: the name of the infobox |
|||
-- config: table containing configuration parameters |
|||
-- |
-- args : parameters from frame to pass through |
||
-- Special args: version, default_version |
|||
-- args : values passed from the Template |
|||
-- Sets a meta table and creates a <div> tag wrapper |
|||
---- the following values are treated specially: default_version, version, version1, version2... |
|||
-- other fields are initialized in other functions |
|||
--]] |
--]] |
||
function Infobox.new( |
function Infobox.new(args, config) |
||
local obj = setmetatable({ |
local obj = setmetatable({ |
||
args_raw = args, -- parameters (uncleaned) |
args_raw = args, -- parameters (uncleaned) |
||
Line 24: | Line 27: | ||
args_smw = {}, -- parameters parsed for smw |
args_smw = {}, -- parameters parsed for smw |
||
infobox_name = nil, -- template name |
infobox_name = nil, -- template name |
||
classes = {}, -- list of classes to add, using the default_version |
|||
param_names = {}, -- ordered param list |
param_names = {}, -- ordered param list |
||
params = {}, -- param definitions |
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 |
versions = nil, -- number of versions |
||
version_names = {}, -- title of each version (for selection and SMW) |
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 |
|||
categories = {}, -- set of categories |
|||
errors = {}, -- list of errors |
errors = {}, -- list of errors |
||
__smw_debug = {}, -- debug data for smw subobjects |
|||
}, |
}, |
||
Infobox) |
Infobox) |
||
-- Step 1, setup config vars and count the versions |
|||
obj:config(config) |
obj:config(config) |
||
obj:parse_versions() |
obj:parse_versions() |
||
obj:create() |
|||
-- Step 2, process the params |
|||
obj:define_params(params) |
|||
obj:parse_params() |
|||
-- Table |
|||
obj:table_header() |
|||
obj:buttons() |
|||
-- Misc |
|||
obj:store_smw() |
|||
obj:parse_categories() |
|||
return obj |
return obj |
||
end |
end |
||
function Infobox:config(...) |
|||
--[[ |
|||
for k, v in pairs(...) do |
|||
Refers to a param after being processed by the validating func |
|||
Used in add_row(), define_params() and is_param_defined() |
|||
--]] |
|||
function Infobox.param(param_name) |
|||
local param = { |
|||
property = 'args_parsed', |
|||
param_name = param_name, |
|||
} |
|||
return param |
|||
end |
|||
--[[ |
|||
Refers to a param in raw form as passed from the Template |
|||
Used in add_row(), define_params() and is_param_defined() |
|||
--]] |
|||
function Infobox.raw_param(param_name) |
|||
local param = { |
|||
property = 'args_raw', |
|||
param_name = param_name, |
|||
} |
|||
return param |
|||
end |
|||
--[[ |
|||
Refers to a param after being processed by the validating smw_func |
|||
Used in add_row(), define_params() and is_param_defined() |
|||
--]] |
|||
function Infobox.smw_param(param_name) |
|||
local param = { |
|||
property = 'args_smw', |
|||
param_name = param_name, |
|||
} |
|||
return param |
|||
end |
|||
--[[ |
|||
Checks to see if a param is defined. |
|||
-- param: Infobox.param(name), Infobox.raw_param(name) or Infobox.smw_param(name) |
|||
Returns 0 if param is never defined |
|||
1 if param is defined for a fraction of the versions |
|||
2 if param is defined for all versions |
|||
]] |
|||
function Infobox:is_param_defined(param) |
|||
local undefined = 0 |
|||
local defined = 0 |
|||
for version = 1, self.versions do |
|||
local value = self:get_param(param, version) |
|||
if value ~= nil then |
|||
defined = 1 |
|||
else |
|||
undefined = 1 |
|||
end |
|||
end |
|||
return 1 + defined - undefined |
|||
end |
|||
--[[ |
|||
Adds a row to the infobox table |
|||
Parameter should be a table of cells, where each cell is a table with the following arguments: |
|||
-- tag : 'td' or 'th' |
|||
-- content : a string or Infobox.param(name), Infobox.raw_param(name), Infobox.smw_param(name) |
|||
-- attr (optional) : mw.html:attr({ arg1 = '1', ... }) |
|||
-- css (optional) : mw.html:css({ arg1 = '1', ...) |
|||
-- class (optional) : mw.html:addClass('arg') |
|||
---- class also supports a table of values, even though mw.html:addClass() does not |
|||
---- common classes: infobox-subheader |
|||
-- rowspan (optional) : mw.html:attr('rowspan',arg) |
|||
-- colspan (optional) : mw.html:attr('colspan',arg) |
|||
-- title (optional) : mw.html:attr('title',arg) |
|||
The row itself may be assigned a single class by setting the value of the key addClass |
|||
-- addClass : mw.html:addClass('arg') |
|||
-- this function currently only supports a single string |
|||
--]] |
|||
function Infobox:add_row(...) |
|||
local args = ... |
|||
local _row = self.rtable:tag('tr') |
|||
-- For each cell |
|||
for _, v in ipairs(args) do |
|||
local _cell = _row:tag(v.tag) |
|||
-- Optional parameters |
|||
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.title then |
|||
_cell:attr('title',v.title) |
|||
end |
|||
if v.css then |
|||
_cell:css(v.css) |
|||
end |
|||
if v.class then |
|||
if type(v.class) == 'string' then |
|||
_cell:addClass(v.class) |
|||
-- mw.html:addClass() doesn't function with tables, add in a loop |
|||
elseif type(v.class) == 'table' then |
|||
for _, w in ipairs(v.class) do |
|||
_cell:addClass(w) |
|||
end |
|||
end |
|||
end |
|||
-- Populate the cell contents |
|||
local content = self:get_param(v.content, self.default_version) |
|||
if content == nil then |
|||
content = self.params[v.content.param_name].empty |
|||
end |
|||
_cell:wikitext(content) |
|||
-- Add the switch data if multiple values exist |
|||
local 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 |
|||
return self |
|||
end |
|||
--[[ |
|||
Adds a blank row of padding spanning the given number of columns |
|||
--]] |
|||
function Infobox:pad(colspan, class) |
|||
local tr = self.rtable:tag('tr'):tag('td'):attr('colspan', colspan or 1):addClass('infobox-padding') |
|||
if class then |
|||
tr:addClass(class) |
|||
end |
|||
return self |
|||
end |
|||
--[[ |
|||
Adds a class to the table as a whole |
|||
--]] |
|||
function Infobox:addClass(arg) |
|||
self.rtable:addClass(arg) |
|||
return self |
|||
end |
|||
--[[ |
|||
Setup config values |
|||
-- config: table containing configuration parameters |
|||
---- infobox_name = mandatory unique identifier for this infobox, used for css |
|||
---- max_buttons = max number of switch buttons before using a dropdown list instead |
|||
--]] |
|||
function Infobox:config(config) |
|||
for k, v in pairs(config) do |
|||
if k == 'infobox_name' then |
if k == 'infobox_name' then |
||
self.infobox_name = mw.ustring.gsub(v, '%s', '_') |
self.infobox_name = mw.ustring.gsub(v, '%s', '_') |
||
elseif k == 'max_buttons' then |
elseif k == 'max_buttons' then |
||
self.max_buttons = tonumber(v) |
self.max_buttons = tonumber(v) |
||
elseif k == 'class' then |
|||
if type(v) == 'string' then |
|||
self.classes = {v} |
|||
elseif type(v) == 'table' then |
|||
self.classes = v |
|||
end |
|||
end |
end |
||
end |
end |
||
if self.infobox_name == nil then |
if self.infobox_name == nil then |
||
table.insert(self.errors, 'infobox_name needs to be defined in Infobox.new()\'s config!') |
|||
end |
end |
||
return self |
return self |
||
end |
end |
||
--[[ |
--[[ |
||
Function for defining parameters |
|||
Counts the number of versions in the infobox |
|||
-- name : parameter name |
|||
Populates Infobox.version_names |
|||
-- func : function to define param, defaults to looking at blanks |
|||
Sets Infobox.default_version |
|||
DO NOT DEFINE VERSION HERE |
|||
USE :maxVersion() |
|||
Can be used any number of times for efficient definition |
|||
--]] |
--]] |
||
function Infobox:parse_versions() |
|||
local function insert_version_name(version_name) |
|||
table.insert(self.version_names, version_name) |
|||
if smwutils.valid_subobject_name(version_name) == false then |
|||
table.insert(self.errors, 'Illegal version value: must not be "0" nor contain a "." in the first five characters') |
|||
end |
|||
end |
|||
-- Count the versions and setup self.version_names |
|||
local i = 1 |
|||
while self.args_raw['version'..i] do |
|||
insert_version_name(self.args_raw['version'..i]) |
|||
i = i + 1 |
|||
end |
|||
self.versions = i - 1 |
|||
-- Should either have 0 or 2+ versions |
|||
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".') |
|||
end |
|||
-- Handle the no version case - check for a custom version_name |
|||
if self.versions == 0 then |
|||
insert_version_name(self.args_raw['version'] or 'DEFAULT') |
|||
self.versions = 1 |
|||
end |
|||
-- Check for a default_version |
|||
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 |
|||
--[[ |
|||
Define all used parameters (except for default_version/version) |
|||
-- name : parameter name as used in the Template |
|||
-- func : function to validate and process the Template argument |
|||
-- If func is a function, will call func(Infobox.raw_param(name)) |
|||
-- If func is a table, contains the following key-value pairs: |
|||
---- name : function |
|||
---- params : list of arguments to pass to the function (use Infobox.raw_param(), |
|||
---- Infobox.param() and Infobox.smw_param() to use arguments) |
|||
-- empty (optional) : text to display in the infobox if func returns nil, defaults to "? (edit)" |
|||
-- category_never : category to add if func returns nil for all versions |
|||
-- category_partial : category to add if func returns nil for some versions, but a value for other versions |
|||
-- category_incomplete : category to add if func returns nil for at least 1 version (i.e. category_never and category_partial combined) |
|||
-- category_complete : category to add if func returns a value for all versions |
|||
-- smw_property (optional) : if this string is defined, the parameter will be saved into smw |
|||
-- smw_func (optional) : function to validate and process the Template argument to save into smw |
|||
-- func is used by default if smw_func is not defined |
|||
--]] |
|||
function Infobox:define_params(...) |
function Infobox:define_params(...) |
||
-- For every parameter, store its corresponding function to self.params |
|||
for _, v in ipairs(...) do |
for _, v in ipairs(...) do |
||
-- For every parameter, store its corresponding function to self.params |
|||
if v.name then |
if v.name then |
||
local param = {} |
local param = {} |
||
Line 307: | Line 86: | ||
end |
end |
||
end |
end |
||
-- If empty is not defined, default message is "? (edit)" |
|||
param.empty = v.empty or editbutton("'''?''' (edit)") |
|||
-- Get the category names |
|||
param.category_never = v.category_never |
|||
param.category_partial = v.category_partial |
|||
param.category_incomplete = v.category_incomplete |
|||
param.category_complete = v.category_complete |
|||
-- Store the param |
|||
self.params[v.name] = param |
self.params[v.name] = param |
||
table.insert(self.param_names, v.name) |
table.insert(self.param_names, v.name) |
||
end |
end |
||
end |
end |
||
self:parse_params() |
|||
--self:parse_categories() |
|||
return self |
return self |
||
end |
end |
||
--[[ |
--[[ |
||
Counts the number of versions in the infobox, and populates version_names |
|||
Fetches a param value. If the value is nil, will return the default value instead |
|||
-- arg: a non-table value (string, number, etc), or Infobox.param(name), Infobox.raw_param(name), Infobox.smw_param(name) |
|||
-- version: 0/'' for default, or else a number |
|||
Returns arg if a constant |
|||
param value (or default value) if Infobox.param(name), Infobox.raw_param(name), Infobox.smw_param(name) |
|||
--]] |
--]] |
||
function Infobox: |
function Infobox:parse_versions() |
||
-- Count the versions |
|||
if version == 0 then |
|||
local i = 1 |
|||
while self.args_raw['version'..i] do |
|||
table.insert(self.version_names, self.args_raw['version'..i]) |
|||
i = i + 1 |
|||
end |
end |
||
self.versions = i - 1 |
|||
-- Handle Infobox.param(), Infobox.raw_param(), Infobox.smw_param() |
|||
-- Handle the no version case - might have a custom version_name |
|||
if type(arg) == 'table' then |
|||
if self.versions == 0 then |
|||
local value = self[arg.property][arg.param_name..version] |
|||
table.insert(self.version_names, self.args_raw['version'] or 'DEFAULT') |
|||
-- If nil, grab default value (which could be nil as well) |
|||
if value == nil then |
|||
value = self[arg.property][arg.param_name] |
|||
end |
|||
return value |
|||
end |
end |
||
if self.versions == 1 then |
|||
-- Everything else passes through unmodified (string, number, etc) |
|||
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".') |
|||
return arg |
|||
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 |
end |
||
-- Value is not defined if "action=edit" exists in string, otherwise |
|||
-- value is defined if not nil and non-empty string |
|||
--[[ |
|||
function Infobox.is_value_defined(value) |
|||
Calculates the parsed value of a param |
|||
if value == nil then |
|||
-- param_name : param_name as a string |
|||
return false |
|||
-- version : 0/'' for default, or else a number |
|||
-- smw : boolean, will use smw_func if true, or func is false |
|||
--]] |
|||
function Infobox:parse_param(param_name, version, smw) |
|||
if version == 0 then |
|||
version = '' |
|||
end |
end |
||
if type(value) ~= 'string' then |
|||
-- use func or smw_func depending on smw argument |
|||
return true |
|||
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 = {} |
|||
local i = 1 |
|||
for _, func_param in ipairs(func_params) do |
|||
func_fetched_params[i] = self:get_param(func_param, version) |
|||
i = i + 1 |
|||
end |
|||
return func_name(unpack(func_fetched_params)) |
|||
else |
|||
table.insert(self.errors, 'Invalid param definition for '..param_name) |
|||
end |
end |
||
if value:find('action=edit') then |
|||
return false |
|||
end |
|||
if value:find('%S') then |
|||
return true |
|||
end |
|||
return false |
|||
end |
end |
||
--[[ |
--[[ |
||
Checks to see if a param is defined. |
|||
Parses all the param values (args_parsed and args_smw) |
|||
Returns 0 if param is never defined. Returns 1 if param is defined for some versions. Returns 2 if param is defined for all versions. |
|||
--]] |
|||
-- param: a table generated from Infobox:param(), Infobox:raw_param() or Infobox:smw_param() |
|||
function Infobox:parse_params() |
|||
]] |
|||
-- Calculate the param value for all params and all versions |
|||
function Infobox:is_param_defined(param) |
|||
for _, param_name in ipairs(self.param_names) do |
|||
local undefined = 0 |
|||
for version=0, self.versions do |
|||
local defined = 0 |
|||
for version = 1, self.versions do |
|||
local value = self:get_param(param, version) |
|||
end |
|||
if self.is_value_defined(value) then |
|||
-- get the parsed value |
|||
defined = 1 |
|||
self.args_parsed[param_name..version] = self:parse_param(param_name, version, false) |
|||
else |
|||
-- Only get the smw value if smw_property is defined |
|||
undefined = 1 |
|||
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 |
||
return 1 + defined - undefined |
|||
end |
end |
||
--[[ |
--[[ |
||
Fetches a param value. If the value is nil, will return the default value instead |
|||
Creates the table header |
|||
-- 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: |
function Infobox:get_param(arg, version) |
||
if version == 0 then |
|||
-- Create infobox table |
|||
version = '' |
|||
self.rtable = mw.html.create('table') |
|||
end |
|||
:addClass('plainlinks') |
|||
if type(arg) == 'table' then |
|||
:addClass('infobox') |
|||
local value = self[arg.property][arg.param_name..version] |
|||
:addClass('infobox-'..self.infobox_name) |
|||
if value == nil then -- Try to get default value if it exists |
|||
for _, class in ipairs(self.classes) do |
|||
value = self[arg.property][arg.param_name] |
|||
local class_name = self:get_param(class, self.default_version) |
|||
end |
|||
if type(class_name) == 'string' then |
|||
return value |
|||
self.rtable:addClass('infobox-'..mw.ustring.gsub(class_name, '%s', '_')) |
|||
end |
|||
-- Other (int, string) |
|||
end |
|||
return arg |
|||
-- Create the switch datatable if multiple versions |
|||
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') |
|||
end |
|||
return self |
|||
end |
end |
||
--[[ |
--[[ |
||
Calculates the parsed value of a param |
|||
If multiple versions exist, creates a set of buttons for switching |
|||
-- param_name : string, name of the param |
|||
-- self.max_buttons : if the number of versions exceeds this value, a dropdown will be created instead |
|||
-- version : 0/'' for default, or else a number |
|||
-- smw : boolean, whether to use the smw function or default function |
|||
--]] |
--]] |
||
function Infobox: |
function Infobox:parse_param(param_name, version, smw) |
||
if version == 0 then |
|||
version = '' |
|||
return |
|||
end |
|||
-- use func or smw_func depending on smw argument |
|||
-- Button caption |
|||
local param = self.params[param_name] |
|||
local func = smw and param.smw_func or param.func |
|||
:tag('div') |
|||
-- call functions by passing the param_name |
|||
:addClass('infobox-buttons') |
|||
if type(func) == 'function' then |
|||
:attr('data-default-index', self.default_version) |
|||
return func(self:get_param(self.raw_param(param_name), version)) |
|||
-- Dropdown list instead of buttons if too many versions |
|||
-- call tables by grabbing the function and reading the param arguments |
|||
if self.versions > self.max_buttons then |
|||
elseif type(func) == 'table' then |
|||
buttons:addClass('infobox-buttons-select') |
|||
local func_name = func.name |
|||
end |
|||
local func_params = func.params |
|||
-- Create all the buttons |
|||
local func_fetched_params = {} |
|||
for version=1, self.versions do |
|||
for _, func_param in ipairs(func_params) do |
|||
local button = buttons:tag('span') |
|||
table.insert(func_fetched_params, self:get_param(func_param, version)) |
|||
:attr('data-switch-index', version) |
|||
end |
|||
:attr('data-switch-anchor', '#'..self.version_names[version]) |
|||
return func_name(unpack(func_fetched_params)) |
|||
:addClass('button') |
|||
else |
|||
:wikitext(self.version_names[version]) |
|||
table.insert(self.errors, 'Invalid param definition for '..param_name) |
|||
-- In case of dropdown list, hide the buttons as the switch gadget will convert them to a dropdown list - we can't directly create the dropdown list here as the select/option tags are rejected by wikitext |
|||
end |
|||
if self.versions > self.max_buttons then |
|||
end |
|||
button:addClass('hidden') |
|||
end |
|||
end |
|||
function Infobox:parse_params() |
|||
-- 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 |
|||
-- 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 |
||
--[[ |
|||
For each version, stores a subobject for all params that have smw_property defined |
|||
--]] |
|||
function Infobox:store_smw() |
function Infobox:store_smw() |
||
-- Abort if not in mainspace |
|||
if mw.title.getCurrentTitle().namespace ~= 0 then |
|||
return false |
|||
end |
|||
-- Store a subobject for each version |
|||
for version=1, self.versions do |
for version=1, self.versions do |
||
-- Generate a subobject name |
|||
-- Reminder - subobject name cannot have a . in the first 5 characters |
-- Reminder - subobject name cannot have a . in the first 5 characters |
||
local subobject_name = self.version_names[version] |
local subobject_name = 'Infobox.'..pagename..'#'..self.version_names[version] |
||
local subobject = {} |
|||
-- Store each param that has smw_property defined and is not nil |
|||
-- Store each param that has smw_property defined and has a defined value |
|||
local subobject = {Infobox = self.infobox_name} -- Also store the current Infobox name |
|||
for _, param_name in ipairs(self.param_names) do |
for _, param_name in ipairs(self.param_names) do |
||
local property = self.params[param_name].smw_property |
local property = self.params[param_name].smw_property |
||
if property then |
if property then |
||
value = self:get_param(self.smw_param(param_name), version) |
|||
if value |
if self.is_value_defined(value) then |
||
subobject[property] = value |
subobject[property] = value |
||
end |
end |
||
end |
end |
||
end |
end |
||
local result = mw.smw.subobject(subobject, subobject_name) |
|||
-- Keep a copy for debugging |
|||
if result ~= true then |
|||
self.__smw_debug[subobject_name] = subobject |
|||
table.insert(self.errors, 'SMW error: '..result.error) |
|||
-- Save subobjects if not in mainspace |
|||
if mw.title.getCurrentTitle():inNamespace(0) then |
|||
local result = true |
|||
if self.versions == 1 then |
|||
result = mw.smw.set(subobject) |
|||
else |
|||
result = mw.smw.subobject(subobject, subobject_name) |
|||
end |
|||
if result ~= true then |
|||
table.insert(self.errors, 'SMW error: '..result.error) |
|||
end |
|||
end |
end |
||
end |
end |
||
return true |
|||
end |
end |
||
function Infobox.param(param_name) |
|||
param = { |
|||
property = 'args_parsed', |
|||
param_name = param_name, |
|||
} |
|||
return param |
|||
end |
|||
function Infobox.raw_param(param_name) |
|||
param = { |
|||
property = 'args_raw', |
|||
param_name = param_name, |
|||
} |
|||
return param |
|||
end |
|||
function Infobox.smw_param(param_name) |
|||
param = { |
|||
property = 'args_smw', |
|||
param_name = param_name, |
|||
} |
|||
return param |
|||
end |
|||
----------- |
|||
-- Table -- |
|||
----------- |
|||
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 |
|||
end |
|||
function Infobox:create() |
|||
-- 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 |
|||
--[[ |
--[[ |
||
Add parameters functions |
|||
Automatically add categories for each param as defined in define_params() |
|||
All parameters should be tables |
|||
The first parameter defines the type of cell to create |
|||
-- tag = 'th' or 'td' |
|||
The second parameter defines what is inside the tag |
|||
-- content = string or Infobox.param |
|||
Additional named parameters can be used to add any styling or attributes |
|||
-- attr : mw.html:attr({ arg1 = '1', ... }) |
|||
-- css : mw.html:css({ arg1 = '1', ...) |
|||
-- class : mw.html:addClass('arg') (common class: infobox-subheader) |
|||
---- class also supports a table of values, even though mw.html:addClass() does not |
|||
-- rowspan : mw.html:attr('rowspan',arg) |
|||
-- colspan : mw.html:attr('colspan',arg) |
|||
-- title : mw.html:attr('title',arg) |
|||
Example: |
|||
ipsobox:addRow( { 'th' , 'Header', title = 'Title' }, |
|||
{ 'argh', 'arg1', class = 'parameter' } }) |
|||
produces: |
|||
<tr><th title="Title">Header</th><th class="parameter">args.arg1</th></tr> |
|||
adding it to the infobox table of ipsobox |
|||
Cells defined as 'argh' and 'argd' will automatically have data-attr-param="" added, and defined as the passed argument if the infobox in creation is defined as a switch infobox |
|||
The row itself may be modified with metadata using the named index "addClass' |
|||
-- addClass : mw.html:addClass('arg') |
|||
-- this function currently only supports a single string |
|||
--]] |
--]] |
||
function Infobox: |
function Infobox:add_row(...) |
||
-- New row to add |
|||
for _, param_name in ipairs(self.param_names) do |
|||
local args = ... |
|||
local _row = self.rtable:tag('tr') |
|||
-- For each member of tags |
|||
if defined == 0 and param.category_never then |
|||
for _, v in ipairs(args) do |
|||
self.categories[param.category_never] = 1 |
|||
local _cell = _row:tag(v.tag) |
|||
-- mw.html:attr() and mw.html:css() both accept table input |
|||
-- colspan, rowspan, title will be quick ways to access attr |
|||
-- these functions also do all the necessary work |
|||
if v.attr then |
|||
_cell:attr(v.attr) |
|||
end |
end |
||
if |
if v.colspan then |
||
_cell:attr('colspan',v.colspan) |
|||
self.categories[param.category_partial] = 1 |
|||
end |
end |
||
if |
if v.rowspan then |
||
_cell:attr('rowspan',v.rowspan) |
|||
self.categories[param.category_incomplete] = 1 |
|||
end |
end |
||
if |
if v.title then |
||
_cell:attr('title',v.title) |
|||
self.categories[param.category_complete] = 1 |
|||
end |
|||
if v.css then |
|||
_cell:css(v.css) |
|||
end |
end |
||
end |
|||
end |
|||
-- if class is a string, it can be added directly |
|||
-- if a table, add every value |
|||
-- mw.html:addClass() doesn't function with tables |
|||
-- so iterate over the class names here and add them individually |
|||
if v.class then |
|||
if type(v.class) == 'string' then |
|||
_cell:addClass(v.class) |
|||
elseif type(v.class) == 'table' then |
|||
for _, w in ipairs(v.class) do |
|||
_cell:addClass(w) |
|||
end |
|||
end |
|||
end |
|||
local content = Infobox:get_param(v.content, self.default_version) |
|||
--[[ |
|||
if content == nil then |
|||
When a parameter is added into the table, add the alternative versions' data into the switch datatable |
|||
content = edit |
|||
-- content : a non-table value (string, number, etc), or Infobox.param(name), Infobox.raw_param(name), Infobox.smw_param(name) |
|||
end |
|||
Returns the name of the parameter in the tag 'data-attr-param' |
|||
_cell:wikitext(content) |
|||
--]] |
|||
function Infobox:add_switch_data(content) |
|||
-- Add the switch data if multiple values exist |
|||
if self.versions < 2 then |
|||
data_attr_param = self:add_switch_data(v.content) |
|||
return false |
|||
if data_attr_param then |
|||
_cell:attr('data-attr-param', data_attr_param) |
|||
end |
|||
end |
end |
||
-- Only needed for non-constant params |
|||
-- allow classes to be defined on the whole row |
|||
if type(content) ~= 'table' then |
|||
if args.addClass then |
|||
return false |
|||
_row:addClass(args.addClass) |
|||
end |
|||
-- Only needed if the param changes value between different versions |
|||
local first_value = self:get_param(content, 1) |
|||
local all_same = true |
|||
for version=2, self.versions do |
|||
if first_value ~= self:get_param(content, version) then |
|||
all_same = false |
|||
break |
|||
end |
|||
end |
end |
||
if all_same then |
|||
return self |
|||
end |
|||
-- Let's build the datatable |
|||
-- datum name: 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 |
|||
local data_param = self.switch_datatable:tag('span'):attr('data-attr-param', name) |
|||
-- Add each version to the datatable |
|||
for version=1, self.versions do |
|||
local text = self:get_param(content, version) |
|||
if text == nil then |
|||
text = self.params[content.param_name].empty |
|||
end |
|||
data_param:tag('span'):attr('data-attr-index', version):wikitext(text) |
|||
end |
|||
-- return the 'data-attr-param' name |
|||
return name |
|||
end |
end |
||
--[[ |
--[[ |
||
-- adds a blank row of padding spanning the given number of columns |
|||
Override tostring |
|||
--]] |
--]] |
||
function Infobox: |
function Infobox:pad(colspan, class) |
||
local tr = self:tag('tr') |
|||
-- Create error messages |
|||
:tag('td'):attr('colspan', colspan or 1):addClass('infobox-padding') |
|||
local error_text = '' |
|||
if class then |
|||
for _, v in ipairs(self.errors) do |
|||
tr:addClass(class) |
|||
error_text = error_text..'<span class="mw-message-box-error">'..v..'</span>' |
|||
end |
|||
-- Create categories |
|||
local category_text = '' |
|||
if mw.title.getCurrentTitle():inNamespace(0) then |
|||
for key, _ in pairs(self.categories) do |
|||
category_text = category_text..'[[Category:'..key..']]' |
|||
end |
|||
end |
end |
||
return self |
|||
local dump = '' |
|||
if self.args_raw.__dump then |
|||
setmetatable(self, nil) |
|||
dump = '<nowiki>'..mw.dumpObject(self)..'</nowiki>' |
|||
setmetatable(self, Infobox) |
|||
end |
|||
return tostring(self.rtable) .. tostring(self.switch_datatable) .. error_text .. category_text .. dump |
|||
end |
end |
||
-- addClass |
|||
function Infobox:addClass(arg) |
|||
self.rtable:addClass(arg) |
|||
return self |
|||
end |
|||
-- 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 |
|||
--[[ |
|||
Debug function |
|||
--]] |
|||
function Infobox:dump() |
function Infobox:dump() |
||
-- Temporarily detach the metatable so we don't override tostring anymore, allowing us to use dumpObject |
|||
setmetatable(self, nil) |
|||
mw.log(mw.dumpObject(self)) |
mw.log(mw.dumpObject(self)) |
||
setmetatable(self, Infobox) |
|||
mw.log(tostring(self)) |
mw.log(tostring(self)) |
||
end |
end |
||
return Infobox |
return Infobox |