Module:Navbox
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Navbox/doc
--------------------------------------------------------------------------------
-- Module:Navbox
-- Navigation box system for linking related articles.
--
-- INSTALLATION:
-- 1. Create page: Module:Navbox
-- 2. Paste this entire file
-- 3. Create TemplateStyles page: Module:Navbox/styles.css
--
-- USAGE:
-- {{#invoke:Navbox|navbox
-- |name = Navbox Name
-- |title = [[Topic]] Navigation
-- |group1 = Category | list1 = [[Link1]] • [[Link2]]
-- }}
--
-- @author Remilia Wiki
-- @license MIT
--------------------------------------------------------------------------------
local p = {}
--------------------------------------------------------------------------------
-- CONFIGURATION
--------------------------------------------------------------------------------
local MAX_GROUPS = 20 -- Maximum number of groups supported
--------------------------------------------------------------------------------
-- UTILITY FUNCTIONS
--------------------------------------------------------------------------------
local function trim(s)
if not s then return nil end
return tostring(s):match("^%s*(.-)%s*$")
end
local function isEmpty(s)
if s == nil then return true end
if type(s) == 'string' then
return trim(s) == ''
end
return false
end
local function hasValue(s)
return not isEmpty(s)
end
local function getArg(args, name, default)
local val = args[name]
if isEmpty(val) then return default end
return trim(val)
end
local function getFrameArgs(frame)
local args = {}
local parentArgs = frame:getParent() and frame:getParent().args or {}
local directArgs = frame.args or {}
for k, v in pairs(directArgs) do args[k] = v end
for k, v in pairs(parentArgs) do args[k] = v end
return args
end
--------------------------------------------------------------------------------
-- NAVBOX
--------------------------------------------------------------------------------
function p.navbox(frame)
local args = getFrameArgs(frame)
local name = getArg(args, 'name')
local title = getArg(args, 'title')
local state = getArg(args, 'state', 'autocollapse')
local above = getArg(args, 'above')
local below = getArg(args, 'below')
local bodyclass = getArg(args, 'bodyclass')
local titleclass = getArg(args, 'titleclass')
local listclass = getArg(args, 'listclass')
if isEmpty(title) then
return '<span class="error">Error: Navbox title required</span>'
end
-- Build the navbox table
local tbl = mw.html.create('table')
:addClass('navbox')
if hasValue(bodyclass) then
tbl:addClass(bodyclass)
end
-- Handle collapse state
if state == 'collapsed' then
tbl:addClass('mw-collapsed')
elseif state == 'expanded' then
tbl:addClass('navbox-expanded')
else
tbl:addClass('mw-collapsible')
end
tbl:attr('cellspacing', '0')
-- Title row
local titleRow = tbl:tag('tr')
local titleCell = titleRow:tag('th')
:addClass('navbox-title')
:attr('colspan', '2')
if hasValue(titleclass) then
titleCell:addClass(titleclass)
end
-- V-T-E links
if hasValue(name) then
local vte = titleCell:tag('div')
:addClass('navbox-vte')
-- Build edit URL using mw.uri (not parser function)
local editUrl = tostring(mw.uri.fullUrl('Template:' .. name, { action = 'edit' }))
vte:wikitext('[')
vte:tag('span')
:addClass('noprint')
:wikitext('[[Template:' .. name .. '|v]]')
vte:wikitext(' · ')
vte:tag('span')
:addClass('noprint')
:wikitext('[[Template talk:' .. name .. '|t]]')
vte:wikitext(' · ')
vte:tag('span')
:addClass('noprint')
:wikitext('[' .. editUrl .. ' e]')
vte:wikitext(']')
end
-- Title text
titleCell:tag('span')
:addClass('navbox-title-text')
:wikitext(title)
-- Above row
if hasValue(above) then
local aboveRow = tbl:tag('tr')
aboveRow:tag('td')
:addClass('navbox-above')
:attr('colspan', '2')
:wikitext(above)
end
-- Group rows
for i = 1, MAX_GROUPS do
local group = getArg(args, 'group' .. i)
local list = getArg(args, 'list' .. i)
if hasValue(list) then
local row = tbl:tag('tr')
if hasValue(group) then
row:tag('th')
:addClass('navbox-group')
:wikitext(group)
local listCell = row:tag('td')
:addClass('navbox-list')
if hasValue(listclass) then
listCell:addClass(listclass)
end
listCell:wikitext(list)
else
-- List without group header spans full width
local listCell = row:tag('td')
:addClass('navbox-list')
:addClass('navbox-list-full')
:attr('colspan', '2')
if hasValue(listclass) then
listCell:addClass(listclass)
end
listCell:wikitext(list)
end
elseif hasValue(group) then
-- Group without list (header row)
local row = tbl:tag('tr')
row:tag('th')
:addClass('navbox-subheader')
:attr('colspan', '2')
:wikitext(group)
end
end
-- Below row
if hasValue(below) then
local belowRow = tbl:tag('tr')
belowRow:tag('td')
:addClass('navbox-below')
:attr('colspan', '2')
:wikitext(below)
end
return tostring(tbl)
end
--------------------------------------------------------------------------------
-- NAVBAR (V-T-E links only)
--------------------------------------------------------------------------------
function p.navbar(frame)
local args = getFrameArgs(frame)
local name = getArg(args, 1) or getArg(args, 'name')
if isEmpty(name) then
return '<span class="error">Error: Template name required</span>'
end
local mini = getArg(args, 'mini') == 'yes' or getArg(args, 'mini') == '1'
local span = mw.html.create('span')
:addClass('navbar')
if mini then
span:addClass('navbar-mini')
span:wikitext('[[Template:' .. name .. '|v]]')
span:wikitext(' · ')
span:wikitext('[[Template talk:' .. name .. '|t]]')
span:wikitext(' · ')
span:wikitext('[{{fullurl:Template:' .. name .. '|action=edit}} e]')
else
span:wikitext('[[Template:' .. name .. '|view]] · ')
span:wikitext('[[Template talk:' .. name .. '|talk]] · ')
span:wikitext('[{{fullurl:Template:' .. name .. '|action=edit}} edit]')
end
return tostring(span)
end
--------------------------------------------------------------------------------
-- HLIST (Horizontal list)
--------------------------------------------------------------------------------
function p.hlist(frame)
local args = getFrameArgs(frame)
local separator = getArg(args, 'separator', ' • ')
local items = {}
for i = 1, 20 do
local item = getArg(args, i)
if hasValue(item) then
table.insert(items, item)
end
end
if #items == 0 then
return ''
end
local span = mw.html.create('span')
:addClass('hlist')
:wikitext(table.concat(items, separator))
return tostring(span)
end
--------------------------------------------------------------------------------
-- FLATLIST (Comma-separated list)
--------------------------------------------------------------------------------
function p.flatlist(frame)
local args = getFrameArgs(frame)
local separator = getArg(args, 'separator', ', ')
local items = {}
for i = 1, 20 do
local item = getArg(args, i)
if hasValue(item) then
table.insert(items, item)
end
end
if #items == 0 then
return ''
end
local span = mw.html.create('span')
:addClass('flatlist')
:wikitext(table.concat(items, separator))
return tostring(span)
end
return p