Jump to content

Module:Navbox with columns: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
Remove code that omitted colspan in the final column (the browser can deal with it). Fix column sorting
Tags: Replaced Reverted
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
local p = {
local andnum = function(s, n) return string.format(cfg.arg[s..'_and_num'], n) end
_navbox = function (frame) return Navbox._withColumns(frame) end,
local isblank = function(v) return (v or '') == '' end
navbox = function (frame) return Navbox['with columns'](frame) end
}

return p
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 19:36, 22 January 2025

-- This module implements {{Navbox with columns}}

local Navbox = require('Module:Navbox/sandbox')
local p = {
	_navbox = function (frame) return Navbox._withColumns(frame) end,
	navbox = function (frame) return Navbox['with columns'](frame) end
}
return p