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> |
||
require('strict') |
|||
local editbutton = require('Module:Edit button') |
|||
local smwutils = require('Module:SMW Utils') |
|||
local Infobox = {} |
local Infobox = {} |
||
Infobox.__index = Infobox |
Infobox.__index = Infobox |
||
Infobox.__tostring = Infobox.tostring |
|||
-- Edit button for unknown params |
|||
local editbutton = require('Module:Edit button') |
|||
local edit = editbutton("'''?''' (edit)") |
|||
-- Page title |
|||
local pagename = mw.title.getCurrentTitle().fullText |
|||
-- map of flags to html tags used by Infobox.addRow() |
|||
-- let's only define it once, since :addRow() is used multiple times per module |
|||
local tagmap = { |
|||
tr = 'tr', |
|||
th = 'th', |
|||
td = 'td', |
|||
argh = 'th', |
|||
argd = 'td' |
|||
} |
|||
--[=[ |
|||
-- Standardized functions |
|||
-- called as string with defineParams |
|||
--]=] |
|||
-- Standardized "has content" function |
|||
function hasContent(arg, default) |
|||
-- Return arg if any non-whitespace character is found |
|||
return string.match(arg or '','%S') and arg or default |
|||
end |
|||
-- Standardized "name" function |
|||
function subjectName(arg) |
|||
return string.match(arg or '','%S') and arg or nil |
|||
end |
|||
-- Create a standardized release function, since so many pages use it |
|||
-- Turns release and update into a single parameter |
|||
function releaseUpdate(release, update) |
|||
if not Infobox.isDefined(release) then |
|||
return nil |
|||
end |
|||
if string.lower(release) == 'no' then |
|||
return 'N/A' |
|||
end |
|||
if not Infobox.isDefined(update) then |
|||
return string.format('%s (Update unknown)',release) |
|||
end |
|||
if string.lower(update) == 'no' then |
|||
return release |
|||
end |
|||
return string.format('%s ([[Update:%s|Update]])', release, update) |
|||
end |
|||
-- Standardized image function |
|||
function image(img) |
|||
if img and img:find('%S') then |
|||
return img |
|||
else |
|||
return nil |
|||
end |
|||
end |
|||
-- Standardized numbers |
|||
function numbers(num) |
|||
num = string.gsub(num or '',',','') |
|||
return tonumber(num) |
|||
end |
|||
-- map of names to pre-defined functions, used by Infobox:defineParams |
|||
local func_map = { |
|||
name = subjectName, |
|||
release = { name = releaseUpdate, params = { 'release', 'update' }, flag = 'p' }, |
|||
removal = { name = releaseUpdate, params = { 'removal', 'removalupdate' }, flag = 'p' }, |
|||
has_content = hasContent, |
|||
image = image, |
|||
numbers = numbers, |
|||
} |
|||
-- used to fill nil params in switching sections |
|||
-- this message isn't kidding |
|||
-- If you see this message anywhere outside of this code |
|||
-- (including inside switchfo box data) |
|||
-- report it |
|||
local nil_param = 'INFOBOX MODULE ERROR, PLEASE REPORT TO WIKI ADMIN' |
|||
-- In case the nil_param is needed outside of this module |
|||
-- give it an easy way to be accessed |
|||
function Infobox.nilParam() |
|||
return nil_param |
|||
end |
|||
-- switch infobox globals |
|||
local LINE_WIDTH = 300 |
|||
local MAX_LINES = 2 |
|||
local DEFAULT_MAX_BUTTONS = 6 |
|||
-- calculate with width of a switch infobox button |
|||
-- potential @TODO: rework to use actual character widths |
|||
function button_width(label) |
|||
local PX_PER_CHAR = 6 |
|||
local PX_PAD_MAR = 24 |
|||
return string.len(label) * PX_PER_CHAR + PX_PAD_MAR |
|||
end |
|||
Infobox.splitpoint = '&&SPLITPOINT&&' |
|||
-- quick test to see if a value is considered nil |
|||
function Infobox.isDefined(arg) |
|||
if arg == nil then |
|||
return false |
|||
end |
|||
if type(arg) == 'string' then |
|||
if arg == nil_param then |
|||
return false |
|||
elseif arg:find('%S') then |
|||
if arg:find('action=edit') then |
|||
return false |
|||
else |
|||
return true |
|||
end |
|||
else |
|||
return false |
|||
end |
|||
end |
|||
return true |
|||
end |
|||
--[[ |
--[[ |
||
Infobox class |
Infobox class |
||
-- args : parameters from frame to pass through |
|||
-- config: table containing configuration parameters |
|||
-- Sets a meta table and creates a <div> tag wrapper |
|||
-- params : definitions for each used value |
|||
-- other fields are initialized in other functions |
|||
-- args : values passed from the Template |
|||
---- the following values are treated specially: default_version, version, version1, version2... |
|||
--]] |
--]] |
||
function Infobox.new( |
function Infobox.new(args) |
||
local obj = setmetatable({ |
local obj = setmetatable({ |
||
args = args, -- parameters (uncleaned) |
|||
rargs = {}, -- parameters (cleaned) |
|||
params = {}, -- parameters mapped to functions |
|||
paramnames = {}, -- parameter names |
|||
dupeable = {}, -- parameters that are allowed to have duplicated switch data |
|||
add_infobox_class = true, -- if true, will add the class 'infobox' |
|||
param_names = {}, -- ordered param list |
|||
switchfo = false, -- switch infobox? or not? |
|||
switchfoattr = {}, -- switch data class changes |
|||
max_buttons = 6, -- If there are more buttons than the max, the buttons will become a dropdown menu |
|||
maxbuttons = DEFAULT_MAX_BUTTONS, -- maximum number of buttons before switching becomes a menu |
|||
default_version = 1, -- default version to populate the infobox |
|||
switch_tag = '', -- switchfo data |
|||
switch_buttons_tag = '', -- switchfo buttons |
|||
version_names = {}, -- title of each version (for selection and SMW) |
|||
custom_buttons = false, |
|||
rtable = nil, -- infobox table to return at the end |
|||
smw_error_tag = '', |
|||
switch_datatable = '', -- datatable for javascript for switch infoboxes |
|||
rtable = nil, -- returned infobox table |
|||
labels = nil, -- returned labels |
|||
_smw = {}, -- semantic mediawiki data |
|||
_smwOne = {}, -- semantic mediawiki data part 2 |
|||
_smwSubobject = {}, -- semantic mediawiki data part 3 |
|||
_smwSubobjectAppliesTo = nil, -- semantic mediawiki data part 3.5 |
|||
_smwElement = {}, -- semantic mediawiki data part 4 |
|||
setSMWElement = true, |
|||
versions = -1, -- number of switch versions (-1 is uncalculated) |
|||
infoboxname = nil, -- template name |
|||
appendStrs = {}, |
|||
bottomlinks = { -- template bottom links |
|||
links = { |
|||
{ 'Template talk:%s', 'talk' }, |
|||
{ 'Template:%s', 'view' } |
|||
}, |
|||
colspan = 2 |
|||
}, |
|||
catdata = {}, -- meta category data |
|||
catlist = {}, -- defined table of category names (strings) |
|||
__finished = false, -- infobox status |
|||
}, |
}, |
||
Infobox) |
Infobox) |
||
-- Step 1, setup config vars and count the versions |
|||
obj:config(config) |
|||
obj:parse_versions() |
|||
-- 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 |
||
--[[ |
--[[ |
||
Removes the addition of infobox class |
|||
Refers to a param after being processed by the validating func |
|||
use before :create() |
|||
Used in add_row(), define_params() and is_param_defined() |
|||
--]] |
--]] |
||
function Infobox |
function Infobox:removeClassInfobox() |
||
self.add_infobox_class = false |
|||
local param = { |
|||
property = 'args_parsed', |
|||
param_name = param_name, |
|||
} |
|||
return param |
|||
end |
end |
||
--[[ |
--[[ |
||
Creates an infobox |
|||
Refers to a param in raw form as passed from the Template |
|||
-- If Infobox:maxVersions() has not been run, it will be run here |
|||
Used in add_row(), define_params() and is_param_defined() |
|||
-- If the infobox should be a switch infobox, all labels will be added |
|||
-- Creates a wikitable that will be the infobox |
|||
THIS SHOULD BE DONE AFTER ADDING AND CLEANING PARAMETERS |
|||
--]] |
--]] |
||
function Infobox |
function Infobox:create() |
||
-- Run to find if this is a switch infobox and if so, how many boxes |
|||
local param = { |
|||
if self.versions == -1 then |
|||
property = 'args_raw', |
|||
self:maxVersion() |
|||
param_name = param_name, |
|||
end |
|||
-- Run if switch infobox |
|||
return param |
|||
if self.switchfo then |
|||
end |
|||
-- Buttons wrapper |
|||
-- Hidden by default, unhidden by javascript |
|||
self.switch_buttons_tag = mw.html.create('div') |
|||
:addClass('infobox-buttons') |
|||
-- default version to immediately switch to via js |
|||
local defv = tonumber(self.args.defver) |
|||
if defv and defv <= self.versions then -- you troll, don't try to show something that isn't there |
|||
self.switch_buttons_tag:attr('data-default-version',defv) |
|||
end |
|||
local numlines = 1 |
|||
local width_working = 0 |
|||
local total_width = 0 |
|||
local buttons = {} |
|||
-- Add individual buttons to the wrapper |
|||
for i=1,self.versions do |
|||
local wid = button_width(self.labels[i] or i) |
|||
width_working = width_working + wid |
|||
total_width = total_width + wid |
|||
if width_working > LINE_WIDTH then |
|||
numlines = numlines + 1 |
|||
width_working = wid |
|||
end |
|||
local b = mw.html.create('span') |
|||
:attr('data-switch-index',tostring(i)) |
|||
-- space to underscore |
|||
:attr('data-switch-anchor','#'..string.gsub(self.labels[i] or i,' ','_')) |
|||
:addClass('button') |
|||
:wikitext(self.labels[i] or i) |
|||
table.insert(buttons, {b, wid}) |
|||
end |
|||
local best = {-1, 100000} |
|||
if (numlines > 1) and (numlines <= MAX_LINES) then |
|||
-- attempt to balance line widths |
|||
local w_s, w_e = 0,total_width |
|||
for i = 1,#buttons-1 do |
|||
w_s = w_s + buttons[i][2] |
|||
w_e = w_e - buttons[i][2] |
|||
if w_s > LINE_WIDTH then |
|||
-- w_s only increases, so we're done once it exceeds the width |
|||
break |
|||
end |
|||
if w_e <= LINE_WIDTH then |
|||
-- w_e only decreases, so just continue if it exceeds line |
|||
local diff = math.abs(w_s - w_e) |
|||
if diff < best[2] then |
|||
best = { i, diff } |
|||
end |
|||
end |
|||
end |
|||
if best[1] == -1 then |
|||
best = { math.floor(#buttons/2), 100000 } |
|||
end |
|||
end |
|||
for i,v in ipairs(buttons) do |
|||
self.switch_buttons_tag:node(v[1]) |
|||
if i == best[1] then |
|||
self.switch_buttons_tag:tag('br') |
|||
end |
|||
end |
|||
-- Used by JavaScript to turn the buttons into a menu list if too many variants |
|||
if self.versions > self.maxbuttons or numlines > MAX_LINES then |
|||
self.switch_buttons_tag:addClass('infobox-buttons-select') |
|||
end |
|||
self.switch_buttons_tag:done() |
|||
end |
|||
-- Create infobox table |
|||
self.rtable = mw.html.create('table') |
|||
:addClass('plainlinks') |
|||
if self.add_infobox_class then |
|||
self.rtable:addClass('infobox') |
|||
end |
|||
-- Add necessary class if switch infobox |
|||
if self.switchfo then |
|||
self.rtable:addClass('infobox-switch') |
|||
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 |
end |
||
-- Defines an infobox name ({{Template:arg}}) |
|||
-- Used to create a link at the bottom of pages |
|||
function Infobox:defineName(arg) |
|||
self.infoboxname = arg |
|||
end |
|||
-- Defines the bottom links of the infobox |
|||
--[[ |
|||
-- pass a table whose elements are tables that define a link and a label |
|||
Checks to see if a param is defined. |
|||
-- { |
|||
-- param: Infobox.param(name), Infobox.raw_param(name) or Infobox.smw_param(name) |
|||
-- { 'link', 'label }, |
|||
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 |
|||
-- The template name can be substituted into the tables using '%s' |
|||
]] |
|||
-- If we wanted Template:InFooBar to link to it's /doc page with a "doc" label: |
|||
function Infobox:is_param_defined(param) |
|||
-- { ... |
|||
local undefined = 0 |
|||
-- { 'Template:%s/doc', 'doc' }, |
|||
local defined = 0 |
|||
-- ... } |
|||
for version = 1, self.versions do |
|||
-- The template's name can only be called 5 times |
|||
local value = self:get_param(param, version) |
|||
function Infobox:defineLinks(arg) |
|||
if value ~= nil then |
|||
if type(arg) == 'table' then |
|||
defined = 1 |
|||
if arg.colspan then |
|||
else |
|||
self.bottomlinks.colspan = arg.colspan |
|||
undefined = 1 |
|||
end |
|||
if arg.links then |
|||
if type(arg.links) == 'table' then |
|||
self.bottomlinks.links = arg.links |
|||
end |
|||
end |
|||
if arg.hide then |
|||
self.bottomlinks.hide = arg.hide |
|||
end |
end |
||
end |
end |
||
return 1 + defined - undefined |
|||
end |
end |
||
-- Change max number of buttons before switching to menu |
|||
-- defaults to 5 |
|||
-- MUST BE RUN BEFORE :create() |
|||
function Infobox:setMaxButtons(arg) |
|||
-- if not a number, just go back to default |
|||
self.maxbuttons = tonumber(arg) or DEFAULT_MAX_BUTTONS |
|||
end |
|||
--[[ |
--[[ |
||
Add parameters functions |
|||
Adds a row to the infobox table |
|||
All parameters should be tables |
|||
Parameter should be a table of cells, where each cell is a table with the following arguments: |
|||
The first parameter defines the type of cell to create |
|||
-- tag : 'td' or 'th' |
|||
-- th : <th> |
|||
-- content : a string or Infobox.param(name), Infobox.raw_param(name), Infobox.smw_param(name) |
|||
-- td : <td> |
|||
-- attr (optional) : mw.html:attr({ arg1 = '1', ... }) |
|||
-- argh : <th> |
|||
-- css (optional) : mw.html:css({ arg1 = '1', ...) |
|||
-- argd : <td> |
|||
-- class (optional) : mw.html:addClass('arg') |
|||
The second parameter defines what is inside the tag |
|||
---- class also supports a table of values, even though mw.html:addClass() does not |
|||
-- th | th : text passed |
|||
---- common classes: infobox-subheader |
|||
-- argh | argd : parameter with the name passed |
|||
-- rowspan (optional) : mw.html:attr('rowspan',arg) |
|||
Additional named parameters can be used to add any styling or attributes |
|||
-- colspan (optional) : mw.html:attr('colspan',arg) |
|||
-- attr : mw.html:attr({ arg1 = '1', ... }) |
|||
-- css : mw.html:css({ arg1 = '1', ...) |
|||
-- class : mw.html:addClass('arg') |
|||
---- 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 |
|||
The row itself may be assigned a single class by setting the value of the key addClass |
|||
-- addClass : mw.html:addClass('arg') |
|||
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 at "meta" |
|||
-- meta.addClass : mw.html:addClass('arg') |
|||
-- this function currently only supports a single string |
-- this function currently only supports a single string |
||
--]] |
--]] |
||
function Infobox |
function Infobox.addRow(box, ...) |
||
-- New row to add |
|||
local args = ... |
local args = ... |
||
local _row = |
local _row = box.rtable:tag('tr') |
||
-- For each |
-- For each member of tags |
||
for |
for i, v in ipairs(args) do |
||
-- map tag name to appropriate tag, default to <td> |
|||
local _cell = _row:tag(v.tag) |
|||
local _cell = _row:tag(tagmap[v.tag] or 'td') |
|||
-- Optional parameters |
|||
-- 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 |
if v.attr then |
||
_cell:attr(v.attr) |
_cell:attr(v.attr) |
||
Line 155: | Line 391: | ||
_cell:css(v.css) |
_cell:css(v.css) |
||
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 v.class then |
||
if type(v.class) == 'string' then |
if type(v.class) == 'string' then |
||
_cell:addClass(v.class) |
_cell:addClass(v.class) |
||
-- mw.html:addClass() doesn't function with tables, add in a loop |
|||
elseif type(v.class) == 'table' then |
elseif type(v.class) == 'table' then |
||
for _, w in ipairs(v.class) do |
for _, w in ipairs(v.class) do |
||
Line 165: | Line 405: | ||
end |
end |
||
end |
end |
||
-- Populate the cell contents |
|||
-- if the cell is a normal th or td, add the exact argument passed |
|||
local content = self:get_param(v.content, self.default_version) |
|||
if |
if v.tag == 'th' or v.tag == 'td' then |
||
_cell:wikitext(v.content) |
|||
-- if defined with "arg", add the argument with name passed |
|||
end |
|||
elseif v.tag == 'argh' or v.tag == 'argd' then |
|||
_cell:wikitext(content) |
|||
local content = box.rargs[v.content] |
|||
-- Add the switch data if multiple values exist |
|||
-- if the requested parameter doesn't exist whatsoever, just return a blank string |
|||
local data_attr_param = self:add_switch_data(v.content) |
|||
if |
if not content then |
||
content = '' |
|||
_cell:attr('data-attr-param', data_attr_param) |
|||
-- If switches exist, first attempt to use the version1 values |
|||
elseif content.switches then |
|||
if content.switches[1] ~= nil_param then |
|||
content = content.switches[1] or '' |
|||
else |
|||
content = content.d or '' |
|||
end |
|||
-- fallback to default value |
|||
else |
|||
content = content.d or '' |
|||
end |
|||
_cell:wikitext(content) |
|||
-- add necessary attribute for switch infoboxes |
|||
if box.switchfo then |
|||
_cell:attr('data-attr-param',v.content) |
|||
end |
|||
end |
end |
||
end |
end |
||
-- not that meta |
|||
-- allow classes to be defined on the whole row |
-- allow classes to be defined on the whole row |
||
-- okay, sort of meta |
|||
if args.addClass then |
|||
if args.meta then |
|||
_row:addClass(args.addClass) |
|||
if args.meta.addClass then |
|||
_row:addClass(args.meta.addClass) |
|||
end |
|||
end |
end |
||
return self |
|||
return box |
|||
end |
end |
||
function Infobox.customButtonPlacement(box,arg) |
|||
box.custom_buttons = arg |
|||
return box |
|||
end |
|||
function Infobox.addButtonsRow(box, args) |
|||
if box.switchfo then |
|||
box.custom_buttons = true |
|||
local _row = box.rtable:tag('tr') |
|||
:addClass('rsw-infobox-switch-buttons-row') |
|||
:tag('td') |
|||
:addClass('rsw-infobox-switch-buttons') |
|||
:attr('colspan', args.colspan) |
|||
:node(box.switch_buttons_tag) |
|||
end |
|||
return box |
|||
end |
|||
function Infobox.addButtonsCaption(box) |
|||
if box.switchfo then |
|||
box.custom_buttons = true |
|||
local _row = box.rtable:tag('caption') |
|||
:addClass('rsw-infobox-switch-buttons-caption') |
|||
:node(box.switch_buttons_tag) |
|||
end |
|||
return box |
|||
end |
|||
--[[ |
--[[ |
||
-- adds a blank row of padding spanning the given number of columns |
|||
--]] |
--]] |
||
function Infobox |
function Infobox.pad(box, colspan, class) |
||
local tr = |
local tr = box:tag('tr') |
||
:tag('td'):attr('colspan', colspan or 1):addClass('infobox-padding') |
|||
:done() |
|||
if class then |
if class then |
||
tr:addClass(class) |
tr:addClass(class) |
||
end |
end |
||
tr:done() |
|||
return self |
|||
return box |
|||
end |
end |
||
--[[ |
--[[ |
||
-- functions the same as mw.html:wikitext() on the wrapper |
|||
Adds a class to the table as a whole |
|||
-- Should only be used for categories really |
|||
--]] |
--]] |
||
function Infobox |
function Infobox.wikitext(box, arg) |
||
box.rtable:wikitext(arg) |
|||
return |
return box |
||
end |
end |
||
--[[ |
|||
-- Adds the specified item(s) to the end of the infobox, outside of the table |
|||
-- items are concatenated together with an empty space |
|||
--]] |
|||
function Infobox.append(box, ...) |
|||
for i,v in ipairs({...}) do |
|||
table.insert(box.appendStrs, v) |
|||
end |
|||
return box |
|||
end |
|||
--[[ |
--[[ |
||
-- Adds a caption to the infobox |
|||
Setup config values |
|||
-- defaults to the pagename |
|||
-- config: table containing configuration parameters |
|||
-- or the default argument if defined |
|||
---- 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 |
function Infobox.caption(box) |
||
-- default to the article's name |
|||
for k, v in pairs(config) do |
|||
local name = pagename |
|||
if k == 'infobox_name' then |
|||
-- first see if the name parameter exists |
|||
self.infobox_name = mw.ustring.gsub(v, '%s', '_') |
|||
if box.rargs.name then |
|||
elseif k == 'max_buttons' then |
|||
-- then try the default |
|||
self.max_buttons = tonumber(v) |
|||
if box.rargs.name.d then |
|||
name = box.rargs.name.d |
|||
if type(v) == 'string' then |
|||
-- then look for swithes |
|||
self.classes = {v} |
|||
elseif box.rargs.name.switches then |
|||
-- then look at version 1 |
|||
self.classes = v |
|||
if box.rargs.name.switches[1] ~= nil_param then |
|||
name = box.rargs.name.switches[1] |
|||
end |
end |
||
end |
end |
||
end |
end |
||
if self.infobox_name == nil then |
|||
local caption = box.rtable:tag('caption') |
|||
table.insert(self.errors, 'infobox_name needs to be defined in Infobox.new()\'s config!') |
|||
:wikitext(name) |
|||
-- add necessary attribute for switch infoboxes |
|||
if box.switchfo then |
|||
caption:attr('data-attr-param','name') |
|||
end |
end |
||
return self |
|||
end |
|||
return box |
|||
end |
|||
--[[ |
--[[ |
||
-- Functions for styling the infobox |
|||
-- works the same as the respective mw.html functions |
|||
Populates Infobox.version_names |
|||
Sets Infobox.default_version |
|||
--]] |
--]] |
||
-- attr |
|||
function Infobox:parse_versions() |
|||
function Infobox.attr(box, arg) |
|||
box.rtable:attr(arg) |
|||
table.insert(self.version_names, version_name) |
|||
return box |
|||
if smwutils.valid_subobject_name(version_name) == false then |
|||
end |
|||
table.insert(self.errors, 'Illegal version value: must not be "0" nor contain a "." in the first five characters') |
|||
end |
|||
-- css |
|||
end |
|||
function Infobox.float(box,float) |
|||
box.rtable:css('float',float) |
|||
-- Count the versions and setup self.version_names |
|||
return box |
|||
local i = 1 |
|||
end |
|||
while self.args_raw['version'..i] do |
|||
insert_version_name(self.args_raw['version'..i]) |
|||
function Infobox.css(box, ...) |
|||
i = i + 1 |
|||
box.rtable:css(...) |
|||
end |
|||
return box |
|||
self.versions = i - 1 |
|||
end |
|||
-- Should either have 0 or 2+ versions |
|||
if self.versions == 1 then |
|||
-- addClass |
|||
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".') |
|||
function Infobox.addClass(box, arg) |
|||
end |
|||
box.rtable:addClass(arg) |
|||
-- Handle the no version case - check for a custom version_name |
|||
return box |
|||
if self.versions == 0 then |
|||
end |
|||
insert_version_name(self.args_raw['version'] or 'DEFAULT') |
|||
self.versions = 1 |
|||
-- Much like Infobox.addClass, but adds multiple classes |
|||
end |
|||
function Infobox.addClasses(box, ...) |
|||
-- Check for a default_version |
|||
for _, v in ipairs(...) do |
|||
if self.args_raw['default_version'] then |
|||
box.rtable:addClass(box) |
|||
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 |
||
return box |
|||
end |
end |
||
--[[ |
|||
Add tags directly to the infobox table |
|||
Use sparingly |
|||
Returns the tag created rather than the entire box |
|||
Which is an mw.html object |
|||
Further uses of :tag() will be mw.html.tag, rather than Infobox.tag |
|||
As such, Infobox:addRow() cannot be used afterwards without restating the infobox as the object |
|||
--]] |
|||
function Infobox.tag(box, arg) |
|||
return box.rtable:tag(arg) |
|||
end |
|||
--[[ |
--[[ |
||
Allows the infobox to use Semantic Media Wiki and give parameters properties |
|||
Define all used parameters (except for default_version/version) |
|||
Pass a table to this function to map parameter names to properties |
|||
-- name : parameter name as used in the Template |
|||
-- func : function to validate and process the Template argument |
|||
Calling syntax: |
|||
-- If func is a function, will call func(Infobox.raw_param(name)) |
|||
-- {{#show:page|?property}}: |
|||
-- If func is a table, contains the following key-value pairs: |
|||
-- "<property>" - unqualified and without a number will display the default value |
|||
---- name : function |
|||
-- "<property#>" - with a number will show the switch data from that index |
|||
---- params : list of arguments to pass to the function (use Infobox.raw_param(), |
|||
-- "all <property>" - adding all will display every unique value in a comma separated list |
|||
---- Infobox.param() and Infobox.smw_param() to use arguments) |
|||
-- empty (optional) : text to display in the infobox if func returns nil, defaults to "? (edit)" |
|||
Properties initiated in Infobox:finish() |
|||
-- 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: |
function Infobox:useSMW(arg) |
||
if type(arg) == 'table' then |
|||
-- For every parameter, store its corresponding function to self.params |
|||
for w, v in pairs(arg) do |
|||
self._smw[w] = v |
|||
if v.name then |
|||
local param = {} |
|||
-- Copy the function |
|||
if type(v.func) == 'function' or type(v.func) == 'table' then |
|||
param.func = v.func |
|||
end |
|||
-- If smw_property is defined, then use smw_func, or default to func if it is not defined |
|||
if v.smw_property then |
|||
param.smw_property = v.smw_property |
|||
if type(v.smw_func) == 'function' or type(v.smw_func) == 'table' then |
|||
param.smw_func = v.smw_func |
|||
else |
|||
param.smw_func = param.func |
|||
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 |
|||
table.insert(self.param_names, v.name) |
|||
end |
end |
||
end |
end |
||
return self |
|||
end |
end |
||
--[[ |
--[[ |
||
As above, but only assigns to "<property>", which will act like "all <property>" - "<property>#" not present |
|||
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) |
|||
Properties initiated in Infobox:finish() |
|||
-- 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:useSMWOne(arg) |
||
if |
if type(arg) == 'table' then |
||
for w, v in pairs(arg) do |
|||
version = '' |
|||
self._smwOne[w] = v |
|||
end |
|||
end |
end |
||
end |
|||
-- Handle Infobox.param(), Infobox.raw_param(), Infobox.smw_param() |
|||
--[[ |
|||
Set up the infobox to set properties in a SMW subobject. This will create a subobject for each version |
|||
- if there is only one version, it will put the properties directly on to the page, like useSMWOne |
|||
Properties initiated in Infobox:finish() |
|||
--]] |
|||
function Infobox:useSMWSubobject(arg) |
|||
if type(arg) == 'table' then |
if type(arg) == 'table' then |
||
for w, v in pairs(arg) do |
|||
local value = self[arg.property][arg.param_name..version] |
|||
self._smwSubobject[w] = v |
|||
-- If nil, grab default value (which could be nil as well) |
|||
if value == nil then |
|||
value = self[arg.property][arg.param_name] |
|||
end |
end |
||
return value |
|||
end |
end |
||
-- Everything else passes through unmodified (string, number, etc) |
|||
return arg |
|||
end |
end |
||
function Infobox:useSMWElement(arg) |
|||
if type(arg) == 'table' then |
|||
for w, v in pairs(arg) do |
|||
self._smwElement[w] = v |
|||
end |
|||
self.setSMWElement = true |
|||
end |
|||
end |
|||
--[[ |
--[[ |
||
Finishing function |
|||
Calculates the parsed value of a param |
|||
-- Finishes the return, adding necessary final tags |
|||
-- param_name : param_name as a string |
|||
-- version : 0/'' for default, or else a number |
|||
-- smw : boolean, will use smw_func if true, or func is false |
|||
--]] |
--]] |
||
function Infobox: |
function Infobox:finish() |
||
local onmain = mw.title.getCurrentTitle().namespace == 0 |
|||
if version == 0 then |
|||
-- Don't finish twice |
|||
version = '' |
|||
if self.__finished then |
|||
return |
|||
end |
end |
||
-- use func or smw_func depending on smw argument |
|||
-- Add switch infobox resources |
|||
local param = self.params[param_name] |
|||
--if self.switchfo then |
|||
local func = smw and param.smw_func or param.func |
|||
self.rtable:attr('data-resource-class', '.infobox-resources-'..string.gsub(tostring(self.infoboxname), ' ', '_')) |
|||
-- call functions by passing the param_name |
|||
-- Wrapper tag, hidden |
|||
if type(func) == 'function' then |
|||
self.switch_tag = mw.html.create('div') |
|||
return func(self:get_param(self.raw_param(param_name), version)) |
|||
:addClass('infobox-switch-resources') |
|||
-- call tables by grabbing the function and reading the param arguments |
|||
:addClass('infobox-resources-'..string.gsub(tostring(self.infoboxname), ' ', '_')) |
|||
elseif type(func) == 'table' then |
|||
:addClass('hidden') |
|||
local func_name = func.name |
|||
local func_params = func.params |
|||
for _, v in ipairs(self.paramnames) do |
|||
local func_fetched_params = {} |
|||
local |
local param = self.rargs[v] |
||
local default_value = param.d or edit |
|||
for _, func_param in ipairs(func_params) do |
|||
-- Parameters may not have any switches data, those are ignored |
|||
func_fetched_params[i] = self:get_param(func_param, version) |
|||
local switchattr = self.switchfoattr[v] |
|||
i = i + 1 |
|||
-- Parameter data wrapper |
|||
local res_span = self.switch_tag:tag('span') |
|||
:attr('data-attr-param',v) |
|||
-- Child for default value |
|||
local def = res_span:tag('span') |
|||
:attr('data-attr-index',0) |
|||
:wikitext(tostring(default_value)) |
|||
-- Switch classes |
|||
if switchattr then |
|||
def:attr('data-addclass',switchattr.d) |
|||
end |
|||
def:done() |
|||
if param.switches then |
|||
-- Add all switches, ignore those defined as nil |
|||
for i, w in ipairs(param.switches) do |
|||
if w ~= nil_param and w ~= nil and w ~= default_value then |
|||
local _w = res_span:tag('span') |
|||
:attr('data-attr-index',i) |
|||
:wikitext(tostring(w)) |
|||
-- Switch classes |
|||
if switchattr then |
|||
_w:attr('data-addclass',switchattr.switches[i]) |
|||
end |
|||
_w:done() |
|||
end |
|||
end |
|||
res_span:done() |
|||
end |
|||
end |
end |
||
return func_name(unpack(func_fetched_params)) |
|||
-- Add a tracking category for mainspace pages that have more than 1 version |
|||
else |
|||
if onmain then |
|||
table.insert(self.errors, 'Invalid param definition for '..param_name) |
|||
if self.versions > 1 then |
|||
-- version count data |
|||
self.switch_tag:tag('span') |
|||
:wikitext(string.format('Versions: [[Version count::%s]]',self.versions)) |
|||
:done() |
|||
self.switch_tag:wikitext('[[Category:Pages that contain switch infobox data]]') |
|||
end |
|||
end |
|||
self.switch_tag:done() |
|||
--end |
|||
-- smw data |
|||
if onmain then |
|||
-- members smw display, yes --> true; no --> false; other --> unknown |
|||
local function smwMembers(smw_arg) |
|||
local smw_argv = string.lower(smw_arg or '') |
|||
if smw_argv == 'yes' then |
|||
return 'true' |
|||
elseif smw_argv == 'no' then |
|||
return 'false' |
|||
else |
|||
return 'unknown' |
|||
end |
|||
end |
|||
-- release date smw display |
|||
local function smwRelease(smw_arg) |
|||
local _d,_m,_y = string.match(smw_arg or '', '%[%[(%d%d?) (%a+)%]%] %[%[(%d%d%d%d)%]%]') |
|||
if _d == nil then |
|||
return nil |
|||
end |
|||
return table.concat({_d,_m,_y},' ') |
|||
end |
|||
-- default, just return the text |
|||
local function smwDefault(smw_arg) |
|||
if smw_arg ~= nil_param and smw_arg ~= edit then |
|||
return smw_arg |
|||
else |
|||
return 'unknown' |
|||
end |
|||
end |
|||
local smw_to_func = { |
|||
members = smwMembers, |
|||
release = smwRelease, |
|||
removal = smwRelease, |
|||
default = smwDefault |
|||
} |
|||
local smw_data_arr = {} |
|||
-- custom properties |
|||
for w, v in pairs(self._smw) do |
|||
-- only needed to give special formatting to release |
|||
-- and to make members true/false |
|||
local smwfunc = smw_to_func[w] or smw_to_func.default |
|||
local curarg = self.rargs[w] |
|||
if curarg then |
|||
local _arg = curarg.d |
|||
local argdefault = _arg |
|||
if _arg == edit then |
|||
argdefault = 'unknown' |
|||
else |
|||
local _x = mw.text.split(tostring(_arg), Infobox.splitpoint, true) |
|||
if not smw_data_arr[v] then |
|||
smw_data_arr[v] = {} |
|||
end |
|||
if not smw_data_arr['All '..v] then |
|||
smw_data_arr['All '..v] = {} |
|||
end |
|||
for _,y in ipairs(_x) do |
|||
local temp_smw_data = smwfunc(y) |
|||
table.insert(smw_data_arr[v], temp_smw_data) |
|||
table.insert(smw_data_arr['All '..v], temp_smw_data) |
|||
end |
|||
end |
|||
if curarg.switches then |
|||
local _args = {} |
|||
for _, x in ipairs(curarg.switches) do |
|||
if x ~= nil_param then |
|||
table.insert(_args,x) |
|||
else |
|||
table.insert(_args,argdefault or nil_param) |
|||
end |
|||
end |
|||
for i, x in ipairs(_args) do |
|||
local _x = mw.text.split(tostring(x), Infobox.splitpoint, true) |
|||
if not smw_data_arr[v..i] then |
|||
smw_data_arr[v..i] = {} |
|||
end |
|||
if not smw_data_arr['All '..v] then |
|||
smw_data_arr['All '..v] = {} |
|||
end |
|||
for _,y in ipairs(_x) do |
|||
local temp_smw_data = smwfunc(y) |
|||
table.insert(smw_data_arr[v..i], temp_smw_data) |
|||
table.insert(smw_data_arr['All '..v], temp_smw_data) |
|||
end |
|||
end |
|||
end |
|||
end |
|||
end |
|||
-- if one version, put smwSubobject into smwOne and just do that |
|||
if self.versions < 2 and not self._smwSubobjectAppliesTo then |
|||
for w,v in pairs(self._smwSubobject) do |
|||
if not self._smwOne[w] then |
|||
self._smwOne[w] = v |
|||
elseif type(self._smwOne[w]) == 'table' then |
|||
table.insert(self._smwOne[w], v) |
|||
else |
|||
self._smwOne[w] = { self._smwOne[w], v } |
|||
end |
|||
end |
|||
end |
|||
for w, _v in pairs(self._smwOne) do |
|||
-- only needed to give special formatting to release |
|||
-- and to make members true/false |
|||
local smwfunc = smw_to_func[w] or smw_to_func.default |
|||
local curarg = self.rargs[w] |
|||
if curarg then |
|||
local _arg = curarg.d |
|||
local argdefault = _arg |
|||
if _arg == edit then |
|||
argdefault = 'unknown' |
|||
end |
|||
if curarg.switches then |
|||
local _args = {} |
|||
for _, x in ipairs(curarg.switches) do |
|||
if x ~= nil_param then |
|||
table.insert(_args,x) |
|||
else |
|||
table.insert(_args,argdefault or nil_param) |
|||
end |
|||
end |
|||
for i, x in ipairs(_args) do |
|||
local _x = mw.text.split(tostring(x), Infobox.splitpoint, true) |
|||
for _,y in ipairs(_x) do |
|||
local temp_smw_data = smwfunc(y) |
|||
for _,v in ipairs(type(_v) == 'table' and _v or {_v}) do |
|||
if not smw_data_arr[v] then |
|||
smw_data_arr[v] = {} |
|||
end |
|||
table.insert(smw_data_arr[v], temp_smw_data) |
|||
end |
|||
end |
|||
end |
|||
else |
|||
if Infobox.isDefined(_arg) then |
|||
local _targ = mw.text.split(tostring(_arg), Infobox.splitpoint, true) |
|||
for _,y in ipairs(_targ) do |
|||
local temp_smw_data = smwfunc(y) |
|||
for _,v in ipairs(type(_v) == 'table' and _v or {_v}) do |
|||
if not smw_data_arr[v] then |
|||
smw_data_arr[v] = {} |
|||
end |
|||
table.insert(smw_data_arr[v], temp_smw_data) |
|||
end |
|||
end |
|||
end |
|||
end |
|||
end |
|||
end |
|||
local smw_data_arr_elem = {} |
|||
for w, v in pairs(self._smwElement) do |
|||
-- only needed to give special formatting to release |
|||
-- and to make members true/false |
|||
local smwfunc = smw_to_func[w] or smw_to_func.default |
|||
local curarg = self.rargs[w] |
|||
if curarg then |
|||
local _arg = curarg.d |
|||
local argdefault = _arg |
|||
if _arg == edit then |
|||
argdefault = 'unknown' |
|||
end |
|||
if curarg.switches then |
|||
local _args = {} |
|||
for _, x in ipairs(curarg.switches) do |
|||
if x ~= nil_param then |
|||
table.insert(_args,x) |
|||
else |
|||
table.insert(_args,argdefault or nil_param) |
|||
end |
|||
end |
|||
for i, x in ipairs(_args) do |
|||
if Infobox.isDefined(x) then |
|||
local _x = mw.text.split(tostring(x), Infobox.splitpoint, true) |
|||
for _,y in ipairs(_x) do |
|||
local temp_smw_data = smwfunc(y) |
|||
if not smw_data_arr_elem[v] then |
|||
smw_data_arr_elem[v] = {} |
|||
end |
|||
table.insert(smw_data_arr_elem[v], temp_smw_data) |
|||
end |
|||
end |
|||
end |
|||
else |
|||
if Infobox.isDefined(_arg) then |
|||
local _targ = mw.text.split(tostring(_arg), Infobox.splitpoint, true) |
|||
for _,y in ipairs(_targ) do |
|||
local temp_smw_data = smwfunc(y) |
|||
if not smw_data_arr_elem[v] then |
|||
smw_data_arr_elem[v] = {} |
|||
end |
|||
table.insert(smw_data_arr_elem[v], temp_smw_data) |
|||
end |
|||
end |
|||
end |
|||
end |
|||
end |
|||
-- if is a switchfo, setup for subobjects |
|||
local smw_data_arr_subobj = {} |
|||
if self._smwSubobjectAppliesTo then |
|||
for i,k in ipairs(self._smwSubobjectAppliesTo) do |
|||
local subobj_data = { |
|||
['Is variant of'] = {pagename}, |
|||
} |
|||
for w,v in pairs(self._smwSubobject) do |
|||
local smwfunc = smw_to_func[w] or smw_to_func.default |
|||
local curarg = self.rargs[w] |
|||
if curarg then |
|||
local argval = curarg.d |
|||
if curarg.switches then |
|||
argval = curarg.switches[i] |
|||
if not Infobox.isDefined(argval) then |
|||
argval = curarg.d |
|||
end |
|||
end |
|||
if Infobox.isDefined(argval) then |
|||
local _x = mw.text.split(tostring(argval), Infobox.splitpoint, true) |
|||
for _, _x1 in ipairs(_x) do |
|||
_x1 = smwfunc(_x1) |
|||
if _x1 ~= 'unknown' then |
|||
if not subobj_data[v] then |
|||
subobj_data[v] = {} |
|||
end |
|||
table.insert(subobj_data[v], _x1) |
|||
end |
|||
end |
|||
end |
|||
end |
|||
end |
|||
for w,v in ipairs(k) do |
|||
local subobj_name = v |
|||
-- can't have a . in the first 5 characters of a subobject identifier |
|||
if mw.ustring.find(mw.ustring.sub(subobj_name,0,5), '%.') then |
|||
self:wikitext('[[Category:Pages with an invalid subobject name]]') |
|||
subobj_name = mw.ustring.gsub(subobj_name, '%.', '') |
|||
end |
|||
if subobj_name == '0' or subobj_name == '' then |
|||
self:wikitext('[[Category:Pages with an invalid subobject name]]') |
|||
subobj_name = 'v_'..subobj_name |
|||
end |
|||
smw_data_arr_subobj[subobj_name] = subobj_data |
|||
end |
|||
end |
|||
end |
|||
local res = mw.smw.set(smw_data_arr) |
|||
local res_subobj = true |
|||
for w,v in pairs(smw_data_arr_subobj) do |
|||
res_subobj = mw.smw.subobject(v, w) |
|||
if not res_subobj == true then |
|||
break |
|||
end |
|||
end |
|||
if not (res == true and res_subobj == true) then |
|||
self.smw_error_tag = mw.html.create('div'):css('display','none'):addClass('infobox-smw-data') |
|||
if not res == true then |
|||
self.smw_error_tag:tag('div'):wikitext('Error setting SMW properties: '+res.error):done() |
|||
end |
|||
if not res_subobj == true then |
|||
self.smw_error_tag:tag('div'):wikitext('Error setting SMW subobject properties: '+res_subobj.error):done() |
|||
end |
|||
end |
|||
if self.setSMWElement then |
|||
if self.smw_error_tag == '' then |
|||
self.smw_error_tag = mw.html.create('div'):css('display','none'):addClass('infobox-smw-data') |
|||
end |
|||
for i,v in pairs(smw_data_arr_elem) do |
|||
for j,k in ipairs(v) do |
|||
if k ~= 'unknown' then |
|||
self.smw_error_tag:tag('span'):wikitext(mw.ustring.format('%s: [[%s::%s]]', i,i,k )) |
|||
end |
|||
end |
|||
end |
|||
end |
|||
if self._smwSubobjectAppliesTo then |
|||
if self.smw_error_tag == '' then |
|||
self.smw_error_tag = mw.html.create('div'):css('display','none'):addClass('infobox-smw-data') |
|||
end |
|||
for w,v in pairs(smw_data_arr_subobj) do |
|||
local subobjdiv = self.smw_error_tag:tag('div') |
|||
subobjdiv:tag('span'):wikitext('SMW Subobject for '..w) |
|||
for j,k in pairs(v) do |
|||
subobjdiv:tag('span'):wikitext(mw.ustring.format('%s: %s', j, table.concat(k, ', '))) |
|||
end |
|||
end |
|||
end |
|||
end |
|||
-- Add view and talk links to infobox |
|||
-- Only done if a name is defined |
|||
if self.infoboxname and not self.bottomlinks.hide then |
|||
local bottom_links = {} |
|||
for _, v in ipairs(self.bottomlinks.links) do |
|||
table.insert(bottom_links, |
|||
string.format( |
|||
table.concat({'[[', |
|||
v[1], |
|||
'|', |
|||
v[2], |
|||
']]'}), |
|||
self.infoboxname, |
|||
self.infoboxname, |
|||
self.infoboxname, |
|||
self.infoboxname, |
|||
self.infoboxname) |
|||
) |
|||
end |
|||
bottom_links = table.concat(bottom_links,' • ') |
|||
self.rtable:tag('tr'):tag('td') |
|||
:addClass('infobox-template-links') |
|||
:attr('colspan', self.bottomlinks.colspan) |
|||
:wikitext(bottom_links) |
|||
:done() |
|||
end |
end |
||
-- Define as finished |
|||
self.__finished = true |
|||
end |
end |
||
--[[ |
--[[ |
||
Function for defining parameters |
|||
Parses all the param values (args_parsed and args_smw) |
|||
-- name : parameter name |
|||
-- func : function to define param, defaults to looking at blanks |
|||
DO NOT DEFINE VERSION HERE |
|||
USE :maxVersion() |
|||
Can be used any number of times for efficient definition |
|||
--]] |
--]] |
||
function Infobox: |
function Infobox:defineParams(...) |
||
for _, v in ipairs(...) do |
|||
-- Calculate the param value for all params and all versions |
|||
-- For every parameter, store its corresponding function to self.params |
|||
for _, param_name in ipairs(self.param_names) do |
|||
if v.name then |
|||
for version=0, self.versions do |
|||
-- If the value is a function or a table (which should define a function) |
|||
if version == 0 then |
|||
if type(v.func) == 'function' or type(v.func) == 'table' then |
|||
version = '' |
|||
self.params[v.name] = v.func |
|||
-- If the value is a string, use the predefined Infobox function of that name |
|||
elseif type(v.func) == 'string' then |
|||
self.params[v.name] = func_map[v.func] or hasContent |
|||
-- Everything else just looks for blanks |
|||
else |
|||
self.params[v.name] = hasContent() |
|||
end |
end |
||
-- |
-- Create a list of all param names |
||
table.insert(self.paramnames,v.name) |
|||
self.args_parsed[param_name..version] = self:parse_param(param_name, version, false) |
|||
-- function to allow duplicated values |
|||
-- Only get the smw value if smw_property is defined |
|||
if |
if v.dupes then |
||
self. |
self.dupeable[v.name] = true |
||
end |
end |
||
end |
end |
||
end |
end |
||
end |
end |
||
--[[ |
--[[ |
||
-- Forces an infobox to only use 1 variant |
|||
Creates the table header |
|||
-- Mainly used by lite infoboxes |
|||
-- This should be run before creation |
|||
--]] |
--]] |
||
function Infobox: |
function Infobox:noSwitch() |
||
self.versions = 1 |
|||
-- Create infobox table |
|||
self. |
self.switchfo = false |
||
:addClass('plainlinks') |
|||
:addClass('infobox') |
|||
:addClass('infobox-'..self.infobox_name) |
|||
for _, class in ipairs(self.classes) do |
|||
local class_name = self:get_param(class, self.default_version) |
|||
if type(class_name) == 'string' then |
|||
self.rtable:addClass('infobox-'..mw.ustring.gsub(class_name, '%s', '_')) |
|||
end |
|||
end |
|||
-- 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 max version |
|||
If multiple versions exist, creates a set of buttons for switching |
|||
-- Adds labels |
|||
-- self.max_buttons : if the number of versions exceeds this value, a dropdown will be created instead |
|||
-- Sees if this needs to be a switch infobox |
|||
-- Returns extra version count (even if already run) |
|||
--]] |
--]] |
||
function Infobox |
function Infobox.maxVersion(box) |
||
-- Only allowed to run once |
|||
if self.versions < 2 then |
|||
if box.versions ~= -1 then |
|||
return |
|||
return box.versions |
|||
end |
end |
||
-- Button caption |
|||
box.labels = {} |
|||
local buttons = self.rtable:tag('caption') |
|||
box.versions = 0 |
|||
:tag('div') |
|||
local smwappliesto = {} |
|||
:addClass('infobox-buttons') |
|||
:attr('data-default-index', self.default_version) |
|||
-- Look for up to 125 variants, defined in order |
|||
-- Dropdown list instead of buttons if too many versions |
|||
for i=1, 125 do |
|||
if self.versions > self.max_buttons then |
|||
-- If variant# exists |
|||
buttons:addClass('infobox-buttons-select') |
|||
if box.args['version'..i] then |
|||
-- Increase version count |
|||
box.versions = box.versions + 1 |
|||
-- Add its label |
|||
local label = box.args['version'..i] or ('Version '..i) |
|||
table.insert(box.labels,label) |
|||
-- add to appliesto |
|||
if box.args['smwname'..i] or box.args['appliesto'..i] then |
|||
table.insert(smwappliesto, mw.text.split(box.args['smwname'..i] or box.args['appliesto'..i], '¦')) |
|||
else |
|||
table.insert(smwappliesto, {label}) |
|||
end |
|||
else |
|||
-- Stop if it doesn't exist |
|||
break |
|||
end |
|||
end |
end |
||
-- Create all the buttons |
|||
-- Define self as a switch infobox if at least 1 other version is found |
|||
for version=1, self.versions do |
|||
if box.versions > 0 then |
|||
local button = buttons:tag('span') |
|||
box.switchfo = true |
|||
:attr('data-switch-index', version) |
|||
box._smwSubobjectAppliesTo = smwappliesto |
|||
:attr('data-switch-anchor', '#'..self.version_names[version]) |
|||
else |
|||
:addClass('button') |
|||
-- single version, check for appliesto |
|||
:wikitext(self.version_names[version]) |
|||
if box.args['smwname'] or box.args['appliesto'] then |
|||
-- 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 |
|||
box._smwSubobjectAppliesTo = {mw.text.split(box.args['smwname'] or box.args['appliesto'], '¦')} |
|||
if self.versions > self.max_buttons then |
|||
button:addClass('hidden') |
|||
end |
end |
||
end |
end |
||
end |
|||
-- versions calculated |
|||
return box.versions |
|||
end |
|||
--[[ |
--[[ |
||
-- Cleans parameters as defined by the above function |
|||
For each version, stores a subobject for all params that have smw_property defined |
|||
-- SHOULD NOT BE RUN UNTIL ALL THINGS ARE DEFINED |
|||
-- Handles switches as well |
|||
-- adds table _add to rargs, a cleaned up version of arguments |
|||
-- d : default value |
|||
-- switches : table of switches (in numerical order) |
|||
-- Functions can be defined with tables |
|||
---- name : name of function |
|||
---- params : table of args to pass to functions |
|||
---- flag : flags for input |
|||
d | #default : use the cleaned parameter first, otherwise passed |
|||
p : use the passed value of parameters |
|||
r | l : use raw (literal) text, rather than values |
|||
-- Defining a single flag will use that flag on all parameters |
|||
-- Defining a table of flags will use the respective flag by position |
|||
--]] |
--]] |
||
function Infobox: |
function Infobox:cleanParams() |
||
-- map of flags to functionality |
|||
for version=1, self.versions do |
|||
local flagmap = { |
|||
-- Generate a subobject name |
|||
r = 'r', |
|||
-- Reminder - subobject name cannot have a . in the first 5 characters |
|||
l = 'r', |
|||
local subobject_name = self.version_names[version] |
|||
d = 'd', |
|||
-- Store each param that has smw_property defined and is not nil |
|||
p = 'p' |
|||
local subobject = {Infobox = self.infobox_name} -- Also store the current Infobox name |
|||
} |
|||
for _, param_name in ipairs(self.param_names) do |
|||
-- For all parameters named |
|||
local property = self.params[param_name].smw_property |
|||
for _, v in ipairs(self.paramnames) do |
|||
if property then |
|||
-- Parameter to add |
|||
local value = self:get_param(self.smw_param(param_name), version) |
|||
local _add = {} |
|||
local catdata = { all_defined = true, one_defined = false } |
|||
subobject[property] = value |
|||
-- If the value of params is a function |
|||
if type(self.params[v]) == 'function' then |
|||
-- Perform that function with the parameter |
|||
_add.d = self.params[v](self.args[v]) |
|||
-- If it's a table, parse it into a function |
|||
elseif type(self.params[v]) == 'table' then |
|||
-- Find the functions name |
|||
local func = self.params[v].name |
|||
if type(func) == 'string' then |
|||
func = func_map[func] |
|||
end |
|||
-- catch all |
|||
if type(func) ~= 'function' then |
|||
func = has_content |
|||
end |
|||
-- Recreate table of args and flags |
|||
local func_args = {} |
|||
local flag = {} |
|||
-- If the flags are NOT a table, turn them into a table |
|||
-- Same size as the parameter table |
|||
-- Every flag will be the same |
|||
if type(self.params[v].flag) ~= 'table' then |
|||
-- Map flags, if unmapped, use default |
|||
local _flag = flagmap[self.params[v].flag] or 'd' |
|||
-- recreate table |
|||
for x=1,#self.params[v].params do |
|||
table.insert(flag,_flag) |
|||
end |
|||
-- If flags are already a table, recreate them in new table |
|||
elseif type(self.params[v].flag) == 'table' then |
|||
local _flag = self.params[v].flag |
|||
-- recreate table |
|||
for x=1,#self.params[v].params do |
|||
-- Map flags, if unmapped, use default |
|||
table.insert(flag,flagmap[_flag[x]] or 'd') |
|||
end |
|||
end |
|||
-- Recreate param table, parsing flags as instructions |
|||
for x, w in ipairs(self.params[v].params) do |
|||
local xarg |
|||
-- By default or defined as 'd' |
|||
-- looks for the cleaned value of the named parameter first |
|||
-- if it doesn't exist, look at the passed value next |
|||
-- if that doesn't exist, use blank |
|||
if flag[x] == 'd' then |
|||
xarg = self.rargs[w] and self.rargs[w].d |
|||
-- compare to nil explicitly because false is a valid value |
|||
if xarg == nil then |
|||
xarg = self.args[w] or '' |
|||
end |
|||
-- Look only at the passed value of the named parameter |
|||
-- if that doesn't exist, use blank |
|||
elseif flag[x] == 'p' then |
|||
xarg = self.args[w] or '' |
|||
-- Don't interpret value as a parameter name, and paste the as is |
|||
elseif flag[x] == 'r' then |
|||
xarg = w |
|||
end |
end |
||
-- Add parsed argument to table |
|||
table.insert(func_args,xarg) |
|||
end |
end |
||
-- Run function |
|||
_add.d = func(unpack(func_args)) |
|||
end |
end |
||
-- Keep a copy for debugging |
|||
if _add.d == nil or _add.d == nil_param then |
|||
self.__smw_debug[subobject_name] = subobject |
|||
-- have to do pagename defaults here to prevent weird behaviour with switch values |
|||
-- Save subobjects if not in mainspace |
|||
if v == 'name' then |
|||
if mw.title.getCurrentTitle():inNamespace(0) then |
|||
_add.d = pagename |
|||
if self.versions == 1 then |
|||
result = mw.smw.set(subobject) |
|||
else |
else |
||
_add.d = edit |
|||
result = mw.smw.subobject(subobject, subobject_name) |
|||
end |
|||
if result ~= true then |
|||
table.insert(self.errors, 'SMW error: '..result.error) |
|||
end |
end |
||
catdata.all_defined = false |
|||
else |
|||
--_add.d is not nil |
|||
catdata.one_defined = true |
|||
end |
end |
||
end |
|||
if self.switchfo then |
|||
end |
|||
-- Table of switches values and count of them |
|||
local _add_switch = {} |
|||
local switches = 0 |
|||
-- Look for up to the maximum number |
|||
for i=1, self.versions do |
|||
local _addarg |
|||
-- see if this param is allowed to have switch |
|||
if v ~= 'image' and v ~= 'examine' and string.find(self.args[v..i] or '','%$%d') then |
|||
local refi = string.match(self.args[v..i],'%$(%d+)') |
|||
_addarg = _add_switch[tonumber(refi)] or nil_param |
|||
else |
|||
-- If the value of params is a function |
|||
if type(self.params[v]) == 'function' then |
|||
-- Perform that function with the parameter at that index |
|||
_addarg = self.params[v](self.args[v..i]) |
|||
-- If it's a table, parse it into a function |
|||
elseif type(self.params[v]) == 'table' then |
|||
-- Find the functions name |
|||
local func = self.params[v].name |
|||
if type(func) == 'string' then |
|||
--[[ |
|||
func = func_map[func] |
|||
Automatically add categories for each param as defined in define_params() |
|||
end |
|||
--]] |
|||
function Infobox:parse_categories() |
|||
-- catch all |
|||
for _, param_name in ipairs(self.param_names) do |
|||
if type(func) ~= 'function' then |
|||
local param = self.params[param_name] |
|||
func = has_content |
|||
local defined = self:is_param_defined(Infobox.param(param_name)) |
|||
end |
|||
if defined == 0 and param.category_never then |
|||
self.categories[param.category_never] = 1 |
|||
-- Recreate table of args and flags |
|||
local func_args = {} |
|||
local flag = {} |
|||
-- If the flags are NOT a table, turn them into a table |
|||
-- Same size as the parameter table |
|||
-- Every flag will be the same |
|||
if type(self.params[v].flag) ~= 'table' then |
|||
-- Map flags, if unmapped, use default |
|||
local _flag = flagmap[self.params[v].flag] or 'd' |
|||
-- recreate table |
|||
for x=1,#self.params[v].params do |
|||
table.insert(flag,_flag) |
|||
end |
|||
-- If flags are already a table, recreate them in new table |
|||
elseif type(self.params[v].flag) == 'table' then |
|||
local _flag = self.params[v].flag |
|||
-- recreate table |
|||
for x=1,#self.params[v].params do |
|||
-- Map flags, if unmapped, use default |
|||
table.insert(flag,flagmap[_flag[x]] or 'd') |
|||
end |
|||
end |
|||
-- Recreate param table, parsing flags as instructions |
|||
for x, w in ipairs(self.params[v].params) do |
|||
local xarg |
|||
-- By default or defined as 'd' |
|||
-- looks for the cleaned value of the named parameter first |
|||
-- if it doesn't exist, look at the passed value next |
|||
-- if that doesn't exist, look at the default |
|||
-- if that doesn't exist, use blank |
|||
if flag[x] == 'd' then |
|||
if self.rargs[w] then |
|||
if self.rargs[w].switches then |
|||
xarg = self.rargs[w].switches[i] |
|||
else |
|||
xarg = self.args[w..i] |
|||
end |
|||
if xarg == nil or xarg == nil_param then |
|||
xarg = self.rargs[w].d |
|||
end |
|||
end |
|||
-- multiple catches in a row just to cover everything |
|||
if xarg == nil or xarg == nil_param then |
|||
xarg = self.args[w..i] |
|||
end |
|||
if xarg == nil or xarg == edit or xarg == nil_param then |
|||
xarg = self.args[w] |
|||
end |
|||
if xarg == nil or xarg == edit or xarg == nil_param then |
|||
xarg = '' |
|||
end |
|||
-- Look only at the passed value of the named parameter |
|||
-- if that doesn't exist, use unnumbered parameter |
|||
-- if that doesn't exist, use blank |
|||
elseif flag[x] == 'p' then |
|||
xarg = self.args[w..i] or self.args[w] or '' |
|||
-- Don't interpret value as a parameter name, and paste the as is |
|||
elseif flag[x] == 'r' then |
|||
xarg = w |
|||
end |
|||
-- Add parsed argument to table |
|||
table.insert(func_args,xarg) |
|||
end |
|||
-- Run function |
|||
_addarg = func(unpack(func_args)) |
|||
end |
|||
end |
|||
-- If not defined, add the nil_param value |
|||
-- An actual nil would cause errors in placement |
|||
-- So it needs to be filled with an actual value |
|||
-- "nil_param" is understood as nil in other functions |
|||
-- Include table in case parameter isn't defined by template |
|||
if _addarg == nil or _addarg == nil_param then |
|||
table.insert(_add_switch, nil_param) |
|||
else |
|||
switches = switches + 1 |
|||
table.insert(_add_switch, _addarg) |
|||
catdata.one_defined = true |
|||
end |
|||
end |
|||
-- If there are actually other values to switch to |
|||
-- Define a switches subtable, otherwise ignore it |
|||
if switches > 0 then |
|||
_add.switches = _add_switch |
|||
end |
|||
end |
end |
||
if defined == 1 and param.category_partial then |
|||
-- Quick fix for names (which defaults to pagename) |
|||
self.categories[param.category_partial] = 1 |
|||
if v == 'name' then |
|||
if _add.d == pagename then |
|||
if _add.switches and _add.switches[1] ~= pagename and _add.switches[1] ~= nil_param then |
|||
_add.d = _add.switches[1] |
|||
end |
|||
end |
|||
end |
end |
||
if defined < 2 and param.category_incomplete then |
|||
-- Parameter cleaning finished, add to table of cleaned args |
|||
self.categories[param.category_incomplete] = 1 |
|||
self.rargs[v] = _add |
|||
-- Category metadata |
|||
-- If every param except default is defined, all_defined = true |
|||
if catdata.all_defined == false then |
|||
if _add.d == edit then |
|||
if _add.switches then |
|||
catdata.all_defined = true |
|||
for _, v in ipairs(_add.switches) do |
|||
if v == nil_param then |
|||
catdata.all_defined = false |
|||
break |
|||
end |
|||
end |
|||
end |
|||
end |
|||
end |
end |
||
if defined == 2 and param.category_complete then |
|||
self.catdata[v] = catdata |
|||
end |
|||
-- mass dupe removal |
|||
-- this needs to be done at the end to keep dependent parameters working |
|||
-- also removes incompatible data types |
|||
for _, v in ipairs(self.paramnames) do |
|||
-- not removed from dupe enabled params parameters |
|||
if not self.dupeable[v] and self.rargs[v] and self.rargs[v].switches then |
|||
-- tells us whether or not we'll need to remove the switch data |
|||
-- switched to false if a switch values does not match the default |
|||
local rmvswitch = true |
|||
for q, z in ipairs(self.rargs[v].switches) do |
|||
-- remove types that don't turn into strings properly |
|||
if type(z) == 'table' or type(z) == 'function' then |
|||
self.rargs[v].switches[q] = nil_param |
|||
-- if it isn't nil or an edit button |
|||
-- change variable to keep the switch data |
|||
elseif z ~= nil_param and z ~= edit then |
|||
rmvswitch = false |
|||
end |
|||
end |
|||
-- remove switch data if everything was a dupe |
|||
if rmvswitch then |
|||
self.rargs[v].switches = nil |
|||
end |
|||
end |
end |
||
end |
end |
||
-- Title parentheses (has to be done here, sadly) |
|||
local _name |
|||
if self.rargs.name then |
|||
_name = self.rargs.name.d |
|||
-- replace html entities to their actual character |
|||
_name = mw.text.decode(_name) |
|||
-- if the page name matches the item name, don't add parentheses |
|||
if _name == mw.title.getCurrentTitle().fullText then |
|||
self.rtable:addClass('no-parenthesis-style') |
|||
end |
|||
end |
|||
end |
end |
||
--[[ |
|||
Function to link internal use parameters with JS class attribution |
|||
-- self:linkParams{ { arg1, arg2 }, ... { arg1a, arg2a } } |
|||
-- arg1: parameter name being linked |
|||
-- arg2: parameter name that holds the classes |
|||
-- THIS FUNCTION SHOULD BE RUN AFTER :cleanParams() |
|||
-- THIS FUNCTION SHOULD BE RUN BEFORE :finish() |
|||
-- The second argument's data should always contain a value (a CSS class name) at every index |
|||
-- This function is cancelled for non switch boxes |
|||
--]] |
|||
function Infobox:linkParams(...) |
|||
if not self.switchfo then |
|||
return |
|||
end |
|||
for _, v in ipairs(...) do |
|||
self.switchfoattr[v[1]] = self.rargs[v[2]] |
|||
end |
|||
end |
|||
--[==========================================[ |
|||
-- Functions for accessing parameters easily |
|||
--]==========================================] |
|||
--[[ |
--[[ |
||
Access the param |
|||
When a parameter is added into the table, add the alternative versions' data into the switch datatable |
|||
-- arg : param name |
|||
-- content : a non-table value (string, number, etc), or Infobox.param(name), Infobox.raw_param(name), Infobox.smw_param(name) |
|||
-- retp : return type |
|||
Returns the name of the parameter in the tag 'data-attr-param' |
|||
d | #default : self.rargs[arg].d -- Default value |
|||
f | full : self.rargs[arg] -- Entire table |
|||
s | switches : self.rargs[arg].switches -- Entire switch table |
|||
s# : self.rargs[arg].switches[#] -- Single switch value at index # |
|||
r : switches[1] or d |
|||
--]] |
--]] |
||
function Infobox: |
function Infobox:param(arg, retp) |
||
-- All parameters |
|||
if self.versions < 2 then |
|||
if arg == 'all' then |
|||
return false |
|||
return self.rargs |
|||
end |
end |
||
-- case-insensitive flagging |
|||
-- Only needed for non-constant params |
|||
retp = tostring(retp):lower() |
|||
if type(content) ~= 'table' then |
|||
local fmap = { |
|||
return false |
|||
d = 'd', default = 'd', s0 = 'd', -- let s-naught count as default (since that's what it is) |
|||
f = 'f', full = 'f', |
|||
s = 's', switch = 's', switches = 's', |
|||
r = 'r' |
|||
} |
|||
local ret_func |
|||
-- quickly see if the parameter is a value greater than 0 |
|||
if retp:match('s[1-9]') then |
|||
ret_func = 's2' |
|||
else |
|||
-- Otherwise map it to the correct flag, or the default |
|||
ret_func = fmap[retp] or fmap.d |
|||
end |
end |
||
-- Only needed if the param changes value between different versions |
|||
-- Fetch parameter |
|||
local first_value = self:get_param(content, 1) |
|||
local |
local param = self.rargs[arg] |
||
-- Return nil if no table found |
|||
for version=2, self.versions do |
|||
if not param then return nil end |
|||
if first_value ~= self:get_param(content, version) then |
|||
all_same = false |
|||
-- Return default |
|||
break |
|||
if ret_func == 'd' then |
|||
end |
|||
return param.d |
|||
end |
end |
||
if all_same then |
|||
-- Return full table |
|||
return false |
|||
if ret_func == 'f' then |
|||
return param |
|||
end |
end |
||
-- Let's build the datatable |
|||
-- Return switch table |
|||
-- datum name: Prepend raw__ or smw__ if not a parsed argument |
|||
if ret_func == 's' then |
|||
local name = content.param_name |
|||
return param.switches |
|||
if content.property == 'args_raw' then |
|||
name = 'raw__' + name |
|||
end |
end |
||
if content.property == 'args_smw' then |
|||
-- Return the first switch, otherwise the default |
|||
name = 'smw__' + name |
|||
if ret_func == 'r' then |
|||
if not param.switches then |
|||
return param.d |
|||
elseif param.switches[1] == nil_param then |
|||
return param.d |
|||
else |
|||
return param.switches[1] |
|||
end |
|||
end |
end |
||
local data_param = self.switch_datatable:tag('span'):attr('data-attr-param', name) |
|||
-- |
-- If s2, reread the param |
||
if ret_func == 's2' then |
|||
for version=1, self.versions do |
|||
-- no switches |
|||
local text = self:get_param(content, version) |
|||
if |
if not param.switches then |
||
return nil |
|||
text = self.params[content.param_name].empty |
|||
end |
|||
-- Parse index by removing the s |
|||
local index = retp:match('s(%d+)') |
|||
-- nil_param |
|||
if param.switches[index] == nil_param then |
|||
return nil |
|||
else |
|||
return param.switches[index] |
|||
end |
end |
||
data_param:tag('span'):attr('data-attr-index', version):wikitext(text) |
|||
end |
end |
||
-- return the 'data-attr-param' name |
|||
return name |
|||
end |
end |
||
--[[ |
|||
Checks if a parameter is defined and not blank |
|||
-- arg : parameter to look at |
|||
-- index : index of switches to look at (defaults to default param) |
|||
-- defining 'all' will look at every possible value for the parameter |
|||
--]] |
|||
function Infobox:paramDefined(arg,index) |
|||
-- Can use cleaned params for switches |
|||
-- but need the passed to identify blanks in the template |
|||
local param = self.rargs[arg] |
|||
local _arg = self.args[arg] |
|||
if string.find(_arg or '','%?action=edit') then |
|||
_arg = '' |
|||
end |
|||
index = index or 0 |
|||
local ret |
|||
-- create a long strong of every value to test for things if 'all' |
|||
if string.lower(index) == 'all' then |
|||
return self.catdata[arg] and (self.catdata[arg].one_defined or self.catdata[arg].all_defined) |
|||
-- index to number otherwise |
|||
else |
|||
index = tonumber(index) or 0 |
|||
if index == 0 then |
|||
if param.switches then |
|||
if Infobox.isDefined(param.switches[1]) then |
|||
ret = param.switches[1] |
|||
else |
|||
ret = _arg |
|||
end |
|||
else |
|||
ret = _arg |
|||
end |
|||
else |
|||
if not param.switches then |
|||
return nil |
|||
end |
|||
if param.switches[index] == nil_param then |
|||
return nil |
|||
end |
|||
ret = param.switches[index] |
|||
end |
|||
end |
|||
return tostring(ret or ''):find('%S') |
|||
end |
|||
--[[ |
--[[ |
||
Function to perform a search on all parameters of a defined name |
|||
Override tostring |
|||
-- param: param name |
|||
-- val: a value or function |
|||
-- functions passed must return either true or false |
|||
-- with true being counted as a match |
|||
--]] |
--]] |
||
function Infobox: |
function Infobox:paramGrep(param,val) |
||
local arg = self.rargs[param] |
|||
-- Create error messages |
|||
-- if no parameters, return nil |
|||
local error_text = '' |
|||
if not arg then |
|||
for _, v in ipairs(self.errors) do |
|||
return nil |
|||
error_text = error_text..'<span class="mw-message-box-error">'..v..'</span>' |
|||
end |
end |
||
-- Create categories |
|||
local |
local ret |
||
local valtype = type(val) |
|||
if mw.title.getCurrentTitle():inNamespace(0) then |
|||
-- start with the default value |
|||
for key, _ in pairs(self.categories) do |
|||
-- if it's a function, run it |
|||
category_text = category_text..'[[Category:'..key..']]' |
|||
if valtype == 'function' then |
|||
ret = val(arg.d) |
|||
-- true means it matched |
|||
if ret == true then |
|||
return ret |
|||
end |
|||
-- switches up here for functions |
|||
if arg.switches then |
|||
for _, v in ipairs(arg.switches) do |
|||
ret = val(v) |
|||
if ret == true then |
|||
return true |
|||
end |
|||
end |
|||
end |
|||
-- if it's just a value, compare the two |
|||
-- only run if types match to avoid errors |
|||
-- compare switches later |
|||
elseif valtype == type(arg.d) then |
|||
-- if a string, make case insensitive |
|||
if valtype == 'string' then |
|||
if string.lower(val) == string.lower(arg.d) then |
|||
return true |
|||
end |
|||
-- everything else just test directly |
|||
elseif val == arg.d then |
|||
return true |
|||
end |
end |
||
end |
end |
||
local dump = '' |
|||
-- switch cases |
|||
if self.args_raw.__dump then |
|||
-- more organized putting them here |
|||
setmetatable(self, nil) |
|||
if arg.switches then |
|||
dump = '<nowiki>'..mw.dumpObject(self)..'</nowiki>' |
|||
for _, v in ipairs(arg.switches) do |
|||
setmetatable(self, Infobox) |
|||
if valtype == type(v) then |
|||
if valtype == 'string' then |
|||
if val:lower() == v:lower() then |
|||
return true |
|||
end |
|||
elseif val == v then |
|||
return true |
|||
end |
|||
end |
|||
end |
|||
end |
end |
||
return tostring(self.rtable) .. tostring(self.switch_datatable) .. error_text .. category_text .. dump |
|||
-- return false in every other case |
|||
return false |
|||
end |
end |
||
------ |
|||
function Infobox.paramRead(arg,val) |
|||
-- if no parameters, return nil |
|||
if not arg then |
|||
return nil |
|||
end |
|||
local ret |
|||
--[[ |
|||
local valtype = type(val) |
|||
Debug function |
|||
-- start with the default value |
|||
--]] |
|||
function |
-- if it's a function, run it |
||
if valtype == 'function' then |
|||
-- Temporarily detach the metatable so we don't override tostring anymore, allowing us to use dumpObject |
|||
ret = val(arg.d) |
|||
setmetatable(self, nil) |
|||
mw.log(mw.dumpObject(self)) |
|||
-- true means it matched |
|||
setmetatable(self, Infobox) |
|||
if ret == true then |
|||
mw.log(tostring(self)) |
|||
return ret |
|||
end |
|||
-- switches up here for functions |
|||
if arg.switches then |
|||
for _, v in ipairs(arg.switches) do |
|||
ret = val(v) |
|||
if ret == true then |
|||
return true |
|||
end |
|||
end |
|||
end |
|||
-- if it's just a value, compare the two |
|||
-- only run if types match to avoid errors |
|||
-- compare switches later |
|||
elseif valtype == type(arg.d) then |
|||
-- if a string, make case insensitive |
|||
if valtype == 'string' then |
|||
if string.lower(val) == string.lower(arg.d) then |
|||
return true |
|||
end |
|||
-- everything else just test directly |
|||
elseif val == arg.d then |
|||
return true |
|||
end |
|||
end |
|||
-- switch cases |
|||
-- more organized putting them here |
|||
if arg.switches then |
|||
for _, v in ipairs(arg.switches) do |
|||
if valtype == type(v) then |
|||
if valtype == 'string' then |
|||
if val:lower() == v:lower() then |
|||
return true |
|||
end |
|||
elseif val == v then |
|||
return true |
|||
end |
|||
end |
|||
end |
|||
end |
|||
-- return false in every other case |
|||
return false |
|||
end |
end |
||
---- |
|||
-- Return collected category data |
|||
function Infobox:categoryData() |
|||
return self.catdata |
|||
end |
|||
-- Override tostring |
|||
function Infobox.tostring(box) |
|||
-- If not finished, finish |
|||
if not box.__finished then |
|||
box:finish() |
|||
end |
|||
-- Make entire html wrapper a string and return it |
|||
local btns = box.switch_buttons_tag |
|||
if box.custom_buttons then |
|||
btns = '' |
|||
end |
|||
if box.args.__dump__ then |
|||
return '<' .. 'pre>'..mw.dumpObject(box) .. '</' .. 'pre>[[Category:Dumping infoboxes]]' |
|||
end |
|||
return tostring(btns) .. tostring(box.rtable) .. table.concat(box.appendStrs, '') .. tostring(box.switch_tag) .. tostring(box.smw_error_tag) |
|||
end |
|||
return Infobox |
return Infobox |
||
-- </nowiki> |