Module:Navbox with columns: Difference between revisions
Appearance
Content deleted Content added
Undid revision 1271146036 by Ahecht (talk) -- re-implement consolidated version |
|||
Line 1: | Line 1: | ||
-- This module implements {{Navbox with columns}} |
|||
require('strict') |
|||
local p = {} |
|||
local parentCfg = mw.loadData('Module:Navbox/configuration') |
|||
local thisCfg = mw.loadData('Module:Navbox with columns/configuration') |
|||
local cfg = {} |
|||
for k, v in pairs(thisCfg) do |
|||
if type(v) == 'table' then |
|||
cfg[k] = {} |
|||
if type(parentCfg[k]) == 'table' then |
|||
for kk, vv in pairs(parentCfg[k]) do cfg[k][kk] = vv end |
|||
end |
|||
for kk, vv in pairs(v) do cfg[k][kk] = vv end |
|||
end |
|||
end |
|||
local inArray = require("Module:TableTools").inArray |
|||
local getArgs -- lazily initialized |
|||
local Navbox = require('Module:Navbox/sandbox') |
|||
-- helper functions |
|||
return { |
|||
local andnum = function(s, n) return string.format(cfg.arg[s..'_and_num'], n) end |
|||
_navbox = function (frame) return Navbox._withColumns(frame) end, |
|||
navbox = function (frame) return Navbox['with columns'](frame) end |
|||
} |
|||
local function concatstrings(s) |
|||
local r = table.concat(s, '') |
|||
if r:match('^%s*$') then return nil end |
|||
return r |
|||
end |
|||
local function concatstyles(s) |
|||
local r = '' |
|||
for _, v in ipairs(s) do |
|||
v = mw.text.trim(v, "%s;") |
|||
if not isblank(v) then r = r .. v .. ';' end |
|||
end |
|||
if isblank(r) then return nil end |
|||
return r |
|||
end |
|||
local function getSubgroup(args, listnum, listText, prefix) |
|||
local subArgs = { |
|||
[cfg.arg.border] = cfg.keyword.border_subgroup, |
|||
[cfg.arg.navbar] = cfg.keyword.navbar_plain |
|||
} |
|||
local hasSubArgs = false |
|||
local subgroups = prefix and {prefix} or cfg.keyword.subgroups |
|||
for k, v in pairs(args) do |
|||
k = tostring(k) |
|||
for _, w in ipairs(subgroups) do |
|||
w = w .. listnum .. "_" |
|||
if (#k > #w) and (k:sub(1, #w) == w) then |
|||
subArgs[k:sub(#w + 1)] = v |
|||
hasSubArgs = true |
|||
end |
|||
end |
|||
end |
|||
return hasSubArgs and p._navbox(subArgs) or listText |
|||
end |
|||
-- Main functions |
|||
p._navbox = require('Module:Navbox')._navbox |
|||
function p._withColumns(pargs) |
|||
-- table for args passed to navbox |
|||
local targs = {} |
|||
-- tables of column numbers |
|||
local colheadernums = {} |
|||
local colnums = {} |
|||
local colfooternums = {} |
|||
-- process args |
|||
local passthrough = { |
|||
[cfg.arg.above]=true,[cfg.arg.aboveclass]=true,[cfg.arg.abovestyle]=true, |
|||
[cfg.arg.basestyle]=true, |
|||
[cfg.arg.below]=true,[cfg.arg.belowclass]=true,[cfg.arg.belowstyle]=true, |
|||
[cfg.arg.bodyclass]=true, |
|||
[cfg.arg.evenstyle]=true, |
|||
[cfg.arg.groupclass]=true,[cfg.arg.groupstyle]=true, |
|||
[cfg.arg.image]=true,[cfg.arg.imageclass]=true,[cfg.arg.imagestyle]=true, |
|||
[cfg.arg.imageleft]=true,[cfg.arg.imageleftstyle]=true, |
|||
[cfg.arg.listclass]=true,[cfg.arg.liststyle]=true, |
|||
[cfg.arg.name]=true, |
|||
[cfg.arg.navbar]=true, |
|||
[cfg.arg.oddstyle]=true, |
|||
[cfg.arg.state]=true, |
|||
[cfg.arg.title]=true,[cfg.arg.titleclass]=true,[cfg.arg.titlestyle]=true, |
|||
} |
|||
for k,v in pairs(pargs) do |
|||
if passthrough[k] then |
|||
targs[k] = v |
|||
elseif type(k) == 'string' then |
|||
if k:match(cfg.pattern.listnum) then |
|||
local n = k:match(cfg.pattern.listnum) |
|||
targs[andnum('liststyle', n + 2)] = pargs[andnum('liststyle', n)] |
|||
targs[andnum('group', n + 2)] = pargs[andnum('group', n)] |
|||
targs[andnum('groupstyle', n + 2)] = pargs[andnum('groupstyle', n)] |
|||
if v and inArray(cfg.keyword.subgroups, v) then |
|||
targs[andnum('list', n + 2)] = getSubgroup(pargs, n, v) |
|||
else |
|||
targs[andnum('list', n + 2)] = v |
|||
end |
|||
elseif (k:match(cfg.pattern.colheadernum) and v ~= '') then |
|||
table.insert(colheadernums, tonumber(k:match(cfg.pattern.colheadernum))) |
|||
elseif (k:match(cfg.pattern.colnum) and v ~= '') then |
|||
table.insert(colnums, tonumber(k:match(cfg.pattern.colnum))) |
|||
elseif (k:match(cfg.pattern.colfooternum) and v ~= '') then |
|||
table.insert(colfooternums, tonumber(k:match(cfg.pattern.colfooternum))) |
|||
end |
|||
end |
|||
end |
|||
table.sort(colheadernums) |
|||
table.sort(colnums) |
|||
table.sort(colfooternums) |
|||
-- HTML table for list1 |
|||
local coltable = mw.html.create( 'table' ):attr('class', 'navbox-columns-table') |
|||
local row, col |
|||
local tablestyle = ( (#colheadernums > 0) or (not isblank(pargs[cfg.arg.fullwidth])) ) |
|||
and 'width:100%' |
|||
or 'width:auto; margin-left:auto; margin-right:auto' |
|||
coltable:attr('style', concatstyles({ |
|||
'border-spacing: 0px; text-align:left', |
|||
tablestyle, |
|||
pargs[cfg.arg.coltablestyle] or '' |
|||
})) |
|||
--- Header row --- |
|||
if (#colheadernums > 0) then |
|||
row = coltable:tag('tr') |
|||
for k, n in ipairs(colheadernums) do |
|||
col = row:tag('td'):attr('class', 'navbox-abovebelow') |
|||
col:attr('style', concatstyles({ |
|||
(k > 1) and 'border-left:2px solid #fdfdfd' or '', |
|||
'font-weight:bold', |
|||
pargs[cfg.arg.colheaderstyle] or '', |
|||
pargs[andnum('colheaderstyle', n)] or '' |
|||
})) |
|||
if tonumber(pargs[andnum('colheadercolspan', n)]) then |
|||
col:attr('colspan', pargs[andnum('colheadercolspan', n)]) |
|||
end |
|||
col:wikitext(pargs[andnum('colheader', n)]) |
|||
end |
|||
end |
|||
--- Main columns --- |
|||
row = coltable:tag('tr'):attr('style', 'vertical-align:top') |
|||
for k, n in ipairs(colnums) do |
|||
if k == 1 and isblank(pargs[andnum('colheader', 1)]) |
|||
and isblank(pargs[andnum('colfooter', 1)]) |
|||
and isblank(pargs[cfg.arg.fullwidth]) then |
|||
local nopad = inArray( |
|||
{'off', '0', '0em', '0px'}, |
|||
mw.ustring.gsub(pargs[cfg.arg.padding] or '', '[;%%]', '')) |
|||
if not nopad then |
|||
row:tag('td'):wikitext(' ') |
|||
:attr('style', 'width:'..(pargs[cfg.arg.padding] or '5em')..';') |
|||
end |
|||
end |
|||
col = row:tag('td'):attr('class', 'navbox-list') |
|||
col:attr('style', concatstyles({ |
|||
(k > 1) and 'border-left:2px solid #fdfdfd' or '', |
|||
'padding:0px', |
|||
pargs[cfg.arg.colstyle] or '', |
|||
((n%2 == 0) and pargs[cfg.arg.evencolstyle] or pargs[cfg.arg.oddcolstyle]) or '', |
|||
pargs[andnum('colstyle', n)] or '', |
|||
'width:' .. (pargs[andnum('colwidth', n)] or pargs[cfg.arg.colwidth] or '10em') |
|||
})) |
|||
local wt = pargs[andnum('col', n)] |
|||
if wt and inArray(cfg.keyword.subgroups, wt) then |
|||
local prefix = mw.ustring.gsub(cfg.arg.col_and_num,"%%d","") |
|||
wt = getSubgroup(pargs, n, wt, prefix) |
|||
end |
|||
col:tag('div'):newline():wikitext(wt):newline() |
|||
end |
|||
--- Footer row --- |
|||
if (#colfooternums > 0) then |
|||
row = coltable:tag('tr') |
|||
for k, n in ipairs(colfooternums) do |
|||
col = row:tag('td'):attr('class', 'navbox-abovebelow') |
|||
col:attr('style', concatstyles({ |
|||
(k > 1) and 'border-left:2px solid #fdfdfd' or '', |
|||
'font-weight:bold', |
|||
pargs[cfg.arg.colfooterstyle] or '', |
|||
pargs[andnum('colfooterstyle', n)] or '' |
|||
})) |
|||
if tonumber(pargs[andnum('colfootercolspan', n)]) then |
|||
col:attr('colspan', pargs[andnum('colfootercolspan', n)]) |
|||
end |
|||
col:wikitext(pargs[andnum('colfooter', n)]) |
|||
end |
|||
end |
|||
-- assign table to list1 |
|||
targs[andnum('list', 1)] = tostring(coltable) |
|||
if isblank(pargs[andnum('colheader', 1)]) |
|||
and isblank(pargs[andnum('col', 1)]) |
|||
and isblank(pargs[andnum('colfooter', 1)]) then |
|||
targs[andnum('list', 1)] = targs[andnum('list', 1)] .. |
|||
'[[' .. cfg.pattern.without_first_col .. ']]' |
|||
end |
|||
-- Other parameters |
|||
targs[cfg.arg.border] = pargs[cfg.arg.border] or pargs[1] |
|||
targs[cfg.arg.evenodd] = (not isblank(pargs[cfg.arg.evenodd])) and pargs[cfg.arg.evenodd] or nil |
|||
targs[cfg.arg.list1padding] = '0px' |
|||
targs[andnum('liststyle', 1)] = 'background:transparent;color:inherit;' |
|||
targs[cfg.arg.style] = concatstyles({pargs[cfg.arg.style], pargs[cfg.arg.bodystyle]}) |
|||
targs[cfg.arg.tracking] = 'no' |
|||
return p._navbox(targs) |
|||
end |
|||
-- Template entry points |
|||
function p.navbox (frame, boxtype) |
|||
local function readArgs(args, prefix) |
|||
-- Read the arguments in the order they'll be output in, to make references |
|||
-- number in the right order. |
|||
local _ |
|||
_ = args[prefix .. cfg.arg.title] |
|||
_ = args[prefix .. cfg.arg.above] |
|||
-- Limit this to 20 as covering 'most' cases (that's a SWAG) and because |
|||
-- iterator approach won't work here |
|||
for i = 1, 20 do |
|||
_ = args[prefix .. andnum('group', i)] |
|||
if inArray(cfg.keyword.subgroups, args[prefix .. andnum('list', i)]) then |
|||
for _, v in ipairs(cfg.keyword.subgroups) do |
|||
readArgs(args, prefix .. v .. i .. "_") |
|||
end |
|||
end |
|||
end |
|||
_ = args[prefix .. cfg.arg.below] |
|||
end |
|||
if not getArgs then |
|||
getArgs = require('Module:Arguments').getArgs |
|||
end |
|||
local args = getArgs(frame, {wrappers = {cfg.pattern[boxtype or 'navbox']}}) |
|||
readArgs(args, "") |
|||
return p['_'..(boxtype or 'navbox')](args) |
|||
end |
|||
p['with columns'] = function (frame) |
|||
return p.navbox(frame, 'withColumns') |
|||
end |
|||
local q = {} |
|||
q._navbox = p._withColumns |
|||
q.navbox = p['with columns'] |
|||
return q |
Revision as of 01:46, 24 January 2025
![]() | This module depends on the following other modules: |
Implements {{Navbox with columns}}
Usage
{{#invoke:Navbox with columns|navbox}}
See also