Відмінності між версіями «Модуль:Navbox»

м
нема опису редагування
м
м
Рядок 1: Рядок 1:
--------------------------------------------------------------------
--<pre> Navbox Module
--
--
-- This module implements {{Navbox}}
-- * Fully CSS styled (inline styles possible but not default)
-- * Supports unlimited rows
--
--
 
-- By User:Tjcool007 from layton.fandom.com
--------------------------------------------------------------------
local p = {}
local p = {}
 
local navbar = require('Module:Navbar')._navbar
local args = {} -- Arguments passed to template
local getArgs -- lazily initialized
local navbox -- Actual navbox
 
local args
--local working = {}
local border
local rownums, skiprows = {}, {}
local listnums
local hasrows, alt, hasData, isChild = false, false, false, false
local ODD_EVEN_MARKER = '\127_ODDEVEN_\127'
local activeSection, sections, cimage, cimageleft
local RESTART_MARKER = '\127_ODDEVEN0_\127'
local colspan, rowspan
local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127'
 
local showText, hideText = 'Show', 'Hide'
local function striped(wikitext)
-- Return wikitext with markers replaced for odd/even striping.
local langCode = mw.getContentLanguage():getCode()
-- Child (subgroup) navboxes are flagged with a category that is removed
local localization = {} --localized strings table
-- by parent navboxes. The result is that the category shows all pages
localization['en'] = {show = 'Show', hide = 'Hide'}
-- where a child navbox is not contained in a parent navbox.
localization['ru'] = {show = 'показать', hide = 'скрыть'}
local orphanCat = '[[Category:Navbox orphans]]'
localization['zh'] = {show = '显示', hide = '隐藏'}
if border == 'subgroup' and args.orphan ~= 'yes' then
if localization[langCode] then
-- No change; striping occurs in outermost navbox.
    showText = localization[langCode]['show']
return wikitext .. orphanCat
    hideText = localization[langCode]['hide']
end
------------------------------------------------
-- Title
------------------------------------------------
--- Processes the VDE links in the title
--
-- @param titlecell The table cell of the title
local function processVde( titlecell )
if not args.template then return end
titlecell:wikitext('<span class="navbox-vde">'
.. mw.getCurrentFrame():expandTemplate({
title = 'vdelinks',
args = { args.template, ['type'] = 'navbox' }
}) .. '</span>')
end
--- Processes the main title row
local function processTitle()
local titlerow = mw.html.create('tr'):addClass('navbox-title')
local titlecell = mw.html.create('th'):attr('colspan',colspan):attr('scope','col')
if not pcall( processVde, titlecell ) then
titlecell:wikitext( '<b class="navbox-vde error" title="Missing Template:Vdelinks">!!!</b>' )
end
end
local first, second = 'odd', 'even'
if args.evenodd then
titlecell:wikitext( args.title or '{{{title}}}' )
if args.evenodd == 'swap' then
first, second = second, first
-- Padding
local hasTemplate = args.template ~= nil
local hasState = not args.state or args.state ~= 'plain'
if hasTemplate ~= hasState then
if hasTemplate then
titlecell:addClass('navbox-title-padright')
else
else
first = args.evenodd
titlecell:addClass('navbox-title-padleft')
second = first
end
end
end
end
local changer
if first == second then
if args.titleclass then titlerow:addClass( args.titleclass ) end
changer = first
if args.titlestyle then titlecell:cssText( args.titlestyle ) end
titlerow:node(titlecell)
navbox:node(titlerow)
end
local function _addGutter( parent, incRowspan )
parent:tag('tr'):addClass('navbox-gutter'):tag('td'):attr('colspan',2)
if incRowspan then
rowspan = rowspan + 1
end
end
------------------------------------------------
-- Above/Below
------------------------------------------------
--- Processes the above and below rows
--
-- @param rowtype Either 'above' or 'below'
local function processAboveBelow( rowtype )
if not args[rowtype] then return end
local abrow = mw.html.create('tr'):addClass('navbox-'..rowtype)
local abcell = mw.html.create('td'):attr('colspan',colspan):wikitext( args[rowtype] )
if args[rowtype .. 'class'] then abrow:addClass( args[rowtype .. 'class'] ) end
if args[rowtype .. 'style'] then abcell:cssText( args[rowtype .. 'style'] ) end
abrow:node( abcell )
_addGutter( navbox )
navbox:node( abrow )
end
------------------------------------------------
-- Main Rows
------------------------------------------------
--- Processes the images
local function _processImage(row, imgtype)
if not args[imgtype] then return end
local iclass = imgtype == 'image' and 'navbox-image-right' or 'navbox-image-left'
local imagecell = mw.html.create('td'):addClass('navbox-image'):addClass(iclass)
local image = args[imgtype]
if image:sub(1,1) ~= '[' then
local width = args[imgtype .. 'width'] or '100px'
imagecell:css('width',width):wikitext('['..'[' .. image  .. '|' .. width .. '|link=' .. (args[imgtype .. 'link'] or '') .. ']]')
else
else
local index = 0
imagecell:css('width','0%'):wikitext(image)
changer = function (code)
end
if code == '0' then
-- Current occurrence is for a group before a nested table.
if args[imgtype .. 'class'] then imagecell:addClass( args[imgtype .. 'class'] ) end
-- Set it to first as a valid although pointless class.
if args[imgtype .. 'style'] then imagecell:cssText( args[imgtype .. 'style'] ) end
-- The next occurrence will be the first row after a title
-- in a subgroup and will also be first.
row:node( imagecell )
index = 0
if imgtype == 'image' then
return first
cimage = imagecell
end
else
index = index + 1
cimageleft = imagecell
return index % 2 == 1 and first or second
end
end
end
local regex = orphanCat:gsub('([%[%]])', '%%%1')
return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer))  -- () omits gsub count
end
end
 
local function processItem(item, nowrapitems)
--- Closes the currently active section (if any)
if item:sub(1, 2) == '{|' then
local function _closeCurrentSection()
-- Applying nowrap to lines in a table does not make sense.
if not activeSection then return end
-- Add newlines to compensate for trim of x in |parm=x in a template.
return '\n' .. item ..'\n'
local row = mw.html.create('tr'):addClass('navbox-section-row')
end
local cell = mw.html.create('td'):attr('colspan',2)
if nowrapitems == 'yes' then
local lines = {}
if not hasrows then
for line in (item .. '\n'):gmatch('([^\n]*)\n') do
_processImage(row,'imageleft')
local prefix, content = line:match('^([*:;#]+)%s*(.*)')
if prefix and not content:match('^<span class="nowrap">') then
line = prefix .. '<span class="nowrap">' .. content .. '</span>'
end
table.insert(lines, line)
end
item = table.concat(lines, '\n')
end
end
if item:match('^[*:;#]') then
return '\n' .. item ..'\n'
cell:node(sections[activeSection])
row:node(cell)
local firstRow = false
if not hasrows then
firstRow = true
hasrows = true
_processImage(row,'image')
end
end
return item
_addGutter(navbox,not firstRow)
navbox:node(row)
rowspan = rowspan + 1
activeSection = false
hasData = false
end
end
 
local function renderNavBar(titleCell)
--- Handles alternating rows
 
--
if args.navbar ~= 'off' and args.navbar ~= 'plain' and not (not args.name and mw.getCurrentFrame():getParent():getTitle():gsub('/sandbox$', '') == 'Template:Navbox') then
-- @return Alternatingly returns true or false. Always returns false if alternating rows
titleCell:wikitext(navbar{
--        are disabled with "alternaterows = no"
args.name,
local function _alternateRow()
mini = 1,
if args.alternaterows == 'no' then return false end
fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';background:none transparent;border:none;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none; padding:0;'
if alt then
})
alt = false
return true
else
alt = true
return false
end
end
end
end
 
--- Process a single Header "row"
--
--
--   Title row
-- @param num Number of the row to be processed
--
local function processHeader(num)
local function renderTitleRow(tbl)
if not args['header'..num] then return end
if not args.title then return end
 
_closeCurrentSection()
local titleRow = tbl:tag('tr')
 
local subtable = mw.html.create('table'):addClass('navbox-section')
if args.titlegroup then
local headerrow = mw.html.create('tr')
titleRow
local header = mw.html.create('th'):addClass('navbox-header'):attr('colspan',2):attr('scope','col'):wikitext( args['header'..num] )
:tag('th')
:attr('scope', 'row')
local collapseme = args['state'..num] or false
:addClass('navbox-group')
local state = false
:addClass(args.titlegroupclass)
:cssText(args.basestyle)
if collapseme then
:cssText(args.groupstyle)
-- Look at this one
:cssText(args.titlegroupstyle)
if collapseme ~= 'plain' then
:wikitext(args.titlegroup)
state = collapseme == 'expanded' and 'expanded' or 'collapsed'
end
else
-- Look at default
local collapseall = args.defaultstate or false
if collapseall then
state = collapseall == 'expanded' and 'expanded' or 'collapsed'
end
end
end
 
local titleCell = titleRow:tag('th'):attr('scope', 'col')
if state then
 
subtable:addClass('mw-collapsible'):attr('data-expandtext',args['expandtext'..num] or args['defaultexpandtext'] or showText):attr('data-collapsetext',args['collapsetext'..num] or args['defaultcollapsetext'] or hideText)
if args.titlegroup then
if state == 'collapsed' then
titleCell
subtable:addClass('mw-collapsed')
:css('border-left', '2px solid #fdfdfd')
end
:css('width', '100%')
header:addClass('navbox-header-collapsible')
end
end
 
local titleColspan = 2
if args.headerclass then headerrow:addClass( args.headerclass ) end
if args.imageleft then titleColspan = titleColspan + 1 end
if args.headerstyle then header:cssText( args.headerstyle ) end
if args.image then titleColspan = titleColspan + 1 end
if args.titlegroup then titleColspan = titleColspan - 1 end
headerrow:node(header)
 
subtable:node(headerrow)
titleCell
:cssText(args.basestyle)
sections[num] = subtable
:cssText(args.titlestyle)
activeSection = num
:addClass('navbox-title')
:attr('colspan', titleColspan)
 
renderNavBar(titleCell)
 
titleCell
:tag('div')
-- id for aria-labelledby attribute
:attr('id', mw.uri.anchorEncode(args.title))
:addClass(args.titleclass)
:css('font-size', '114%')
:css('margin', '0 4em')
:wikitext(processItem(args.title))
end
 
--
--  Above/Below rows
--
 
local function getAboveBelowColspan()
local ret = 2
if args.imageleft then ret = ret + 1 end
if args.image then ret = ret + 1 end
return ret
end
 
local function renderAboveRow(tbl)
if not args.above then return end
 
tbl:tag('tr')
:tag('td')
:addClass('navbox-abovebelow')
:addClass(args.aboveclass)
:cssText(args.basestyle)
:cssText(args.abovestyle)
:attr('colspan', getAboveBelowColspan())
:tag('div')
-- id for aria-labelledby attribute, if no title
:attr('id', args.title and nil or mw.uri.anchorEncode(args.above))
:wikitext(processItem(args.above, args.nowrapitems))
end
 
local function renderBelowRow(tbl)
if not args.below then return end
 
tbl:tag('tr')
:tag('td')
:addClass('navbox-abovebelow')
:addClass(args.belowclass)
:cssText(args.basestyle)
:cssText(args.belowstyle)
:attr('colspan', getAboveBelowColspan())
:tag('div')
:wikitext(processItem(args.below, args.nowrapitems))
end
end
 
--
--- Processes a single list row
--   List rows
--
--
local function renderListRow(tbl, index, listnum)
-- @param num Number of the row to be processed
local row = tbl:tag('tr')
local function processList(num)
 
if not args['list'..num] then return end
if index == 1 and args.imageleft then
row
local row = mw.html.create('tr'):addClass('navbox-row')
:tag('td')
:addClass('noviewer')
if not hasrows and not activeSection then
:addClass('navbox-image')
_processImage(row, 'imageleft')
:addClass(args.imageclass)
:css('width', '1px')               -- Minimize width
:css('padding', '0px 2px 0px 0px')
:cssText(args.imageleftstyle)
:attr('rowspan', #listnums)
:tag('div')
:wikitext(processItem(args.imageleft))
end
end
 
if args['group' .. listnum] then
local listcell = mw.html.create('td'):addClass('navbox-list')
local groupCell = row:tag('th')
local hlistcell = listcell:tag('div'):addClass('hlist')
 
-- id for aria-labelledby attribute, if lone group with no title or above
local data = args['list'..num]
if listnum == 1 and not (args.title or args.above or args.group2) then
groupCell
if data:sub(1,1) == '*' then
:attr('id', mw.uri.anchorEncode(args.group1))
-- Add newlines to support lists properly
end
hlistcell
 
:newline()
groupCell
:wikitext( data )
:attr('scope', 'row')
:newline()
:addClass('navbox-group')
else
:addClass(args.groupclass)
hlistcell:wikitext( data )
:cssText(args.basestyle)
:css('width', args.groupwidth or '1%') -- If groupwidth not specified, minimize width
 
groupCell
:cssText(args.groupstyle)
:cssText(args['group' .. listnum .. 'style'])
:wikitext(args['group' .. listnum])
end
end
 
local listCell = row:tag('td')
local altRow = _alternateRow()
 
if altRow then
if args['group' .. listnum] then
row:addClass( args.altrowclass or 'alt' )
listCell
:css('text-align', 'left')
local listclass = args.altlistclass or args.listclass or false
:css('border-left-width', '2px')
if listclass then listcell:addClass( listclass ) end
:css('border-left-style', 'solid')
local liststyle = args.altliststyle or args.liststyle or false
if liststyle then listcell:cssText( liststyle ) end
else
else
listCell:attr('colspan', 2)
if args.rowclass then row:addClass( args.rowclass ) end
if args.listclass then listcell:addClass( args.listclass ) end
if args.liststyle then listcell:cssText( args.liststyle ) end
end
end
 
if not args.groupwidth then
if args['group'..num] then
listCell:css('width', '100%')
local groupcell = mw.html.create('th'):addClass('navbox-group'):attr('scope','row'):wikitext( args['group'..num] )
end
 
if altRow then
local rowstyle  -- usually nil so cssText(rowstyle) usually adds nothing
local groupclass = args.altgroupclass or args.groupclass or false
if index % 2 == 1 then
if groupclass then groupcell:addClass( groupclass ) end
rowstyle = args.oddstyle
local groupstyle = args.altgroupstyle or args.groupstyle or false
if groupstyle then groupcell:cssText( groupstyle ) end
else
if args.groupclass then groupcell:addClass( args.groupclass ) end
if args.groupstyle then groupcell:cssText( args.groupstyle ) end
end
row:node( groupcell )
else
else
rowstyle = args.evenstyle
listcell:attr('colspan',2):addClass('no-group')
end
end
 
local listText = args['list' .. listnum]
row:node( listcell )
local oddEven = ODD_EVEN_MARKER
if listText:sub(1, 12) == '</div><table' then
local firstRow = false
-- Assume list text is for a subgroup navbox so no automatic striping for this row.
if not hasrows and not activeSection then
oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd'
firstRow = true
hasrows = true
_processImage(row, 'image')
end
end
listCell
:css('padding', '0px')
if activeSection then
:cssText(args.liststyle)
local parent = sections[activeSection]
:cssText(rowstyle)
if not isChild or not firstRow then
:cssText(args['list' .. listnum .. 'style'])
_addGutter(parent)
:addClass('navbox-list')
end
:addClass('navbox-' .. oddEven)
parent:node(row)
:addClass(args.listclass)
hasData = true
:addClass(args['list' .. listnum .. 'class'])
else
:tag('div')
if not isChild or not firstRow then
:css('padding', (index == 1 and args.list1padding) or args.listpadding or '0em 0.25em')
_addGutter(navbox,not firstRow)
:wikitext(processItem(listText, args.nowrapitems))
 
if index == 1 and args.image then
row
:tag('td')
:addClass('noviewer')
:addClass('navbox-image')
:addClass(args.imageclass)
:css('width', '1px')              -- Minimize width
:css('padding', '0px 0px 0px 2px')
:cssText(args.imagestyle)
:attr('rowspan', #listnums)
:tag('div')
:wikitext(processItem(args.image))
end
end
 
 
--
--  Tracking categories
--
 
local function needsHorizontalLists()
if border == 'subgroup' or args.tracking == 'no' then
return false
end
local listClasses = {
['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true,
['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true,
['hlist vevent'] = true,
}
return not (listClasses[args.listclass] or listClasses[args.bodyclass])
end
 
local function hasBackgroundColors()
for _, key in ipairs({'titlestyle', 'groupstyle', 'basestyle', 'abovestyle', 'belowstyle'}) do
if tostring(args[key]):find('background', 1, true) then
return true
end
end
navbox:node( row )
rowspan = rowspan + 1
end
end
end
end
 
local function hasBorders()
--- Processes all rows
for _, key in ipairs({'groupstyle', 'basestyle', 'abovestyle', 'belowstyle'}) do
local function processRows()
if tostring(args[key]):find('border', 1, true) then
sections = {}
return true
for i=1,#rownums do
local num = rownums[i]
if not skiprows[num] then
processHeader(num)
processList(num)
end
end
end
end
end
_closeCurrentSection()
 
local function isIllegible()
if cimageleft then
local styleratio = require('Module:Color contrast')._styleratio
cimageleft:attr('rowspan',rowspan)
 
for key, style in pairs(args) do
if tostring(key):match("style$") then
if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then
return true
end
end
end
end
return false
if cimage then
end
cimage:attr('rowspan',rowspan)
 
local function getTrackingCategories()
local cats = {}
if needsHorizontalLists() then table.insert(cats, 'Navigational boxes without horizontal lists') end
if hasBackgroundColors() then table.insert(cats, 'Navboxes using background colours') end
if isIllegible() then table.insert(cats, 'Potentially illegible navboxes') end
if hasBorders() then table.insert(cats, 'Navboxes using borders') end
return cats
end
 
local function renderTrackingCategories(builder)
local title = mw.title.getCurrentTitle()
if title.namespace ~= 10 then return end -- not in template space
local subpage = title.subpageText
if subpage == 'doc' or subpage == 'sandbox' or subpage == 'testcases' then return end
 
for _, cat in ipairs(getTrackingCategories()) do
builder:wikitext('[[Category:' .. cat .. ']]')
end
end
end
end
 
------------------------------------------------
-- ARGUMENTS PREPROCESSOR
-- * Extracts arguments from frame and stores them in args table
-- * At the same time, checks for valid row numbers
------------------------------------------------
--- Preprocessor for the arguments.
-- Will fill up the args table with the parameters from the frame grouped by their type.
--
--
--   Main navbox tables
-- @param frame The frame passed to the Module.
--
local function preProcessArgs(frame)
local function renderMainTable()
local tmp = {}
local tbl = mw.html.create('table')
:addClass('nowraplinks')
if frame == mw.getCurrentFrame() then
:addClass(args.bodyclass)
tmp = frame:getParent().args
 
else
if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
tmp = frame
if args.state == 'collapsed' then args.state = 'mw-collapsed' end
end
tbl
:addClass('mw-collapsible')
-- Storage tables
:addClass(args.state or 'autocollapse')
local nums = {}
-- Loop over all the args
for k,v in pairs(tmp) do
-- Skip empty args, which are useless
if v ~= '' then
local cat,num = tostring(k):match('^(%a+)([1-9]%d*)$')
if cat == 'header' or cat == 'list' then
nums[num] = true
end
args[k] = v -- Simple copy
end
end
end
 
tbl:css('border-spacing', 0)
colspan = args.image and 3 or 2
if border == 'subgroup' or border == 'none' then
if args.imageleft then colspan = colspan + 1 end
tbl
rowspan = 0
:addClass('navbox-subgroup')
   
:cssText(args.bodystyle)
if args.alternaterows == 'swap' then
:cssText(args.style)
alt = true
else -- regular navbox - bodystyle and style will be applied to the wrapper table
tbl
:addClass('navbox-inner')
:css('background', 'transparent')
:css('color', 'inherit')
end
end
tbl:cssText(args.innerstyle)
 
for k, v in pairs(nums) do
renderTitleRow(tbl)
rownums[#rownums+1] = tonumber(k)
renderAboveRow(tbl)
for i, listnum in ipairs(listnums) do
renderListRow(tbl, i, listnum)
end
end
renderBelowRow(tbl)
 
table.sort(rownums)
return tbl
end
-- Calculate skip rows
 
local cSection, cSkip
function p._navbox(navboxArgs)
local showall = args.showall
args = navboxArgs
for i=1,#rownums do
listnums = {}
local num = rownums[i]
 
if args['header'..num] then
for k, _ in pairs(args) do
cSection = true
if type(k) == 'string' then
cSkip = false
local listnum = k:match('^list(%d+)$')
local showme = args['show'..num]
if listnum then table.insert(listnums, tonumber(listnum)) end
if showme == 'no' then
cSkip = true
elseif showme == 'auto' or (showme ~= 'yes' and showall ~= 'yes') then
if not args['list'..num] then
local nextNum = rownums[i+1]
cSkip = not nextNum or args['header'..nextNum] -- If next has a header -> skip
end
end
end
if cSection and cSkip then
skiprows[num] = true
end
end
end
end
table.sort(listnums)
end
 
border = mw.text.trim(args.border or args[1] or '')
------------------------------------------------
if border == 'child' then
-- MAIN FUNCTIONS
border = 'subgroup'
------------------------------------------------
--- Processes the arguments to create the navbox.
--
-- @return A string with HTML that is the navbox.
local function _navbox()
-- Create the root HTML element
local trim = function(s)
return s and mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1") or ''
end
end
 
local border = args.border or trim(args[1]) or ''
-- render the main body of the navbox
isChild = (border == 'child' or border == 'subgroup')
local tbl = renderMainTable()
 
if isChild then
-- render the appropriate wrapper around the navbox, depending on the border param
navbox = mw.html.create('table'):addClass('navbox-subgroup')
local res = mw.html.create()
if border == 'none' then
local nav = res:tag('div')
:attr('role', 'navigation')
:node(tbl)
-- aria-labelledby title, otherwise above, otherwise lone group
if args.title or args.above or (args.group1 and not args.group2) then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title or args.above or args.group1))
else
nav:attr('aria-label', 'Navbox')
end
elseif border == 'subgroup' then
-- We assume that this navbox is being rendered in a list cell of a parent navbox, and is
-- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the
-- padding being applied, and at the end add a <div> to balance out the parent's </div>
res
:wikitext('</div>')
:node(tbl)
:wikitext('<div>')
else
else
local nav = res:tag('div')
navbox = mw.html.create('table'):addClass('navbox')
:attr('role', 'navigation')
:addClass('navbox')
if args.state ~= 'plain' then
:addClass(args.navboxclass)
navbox:addClass('mw-collapsible'):attr('data-expandtext',args['expandtext'] or args['defaultexpandtext'] or showText):attr('data-collapsetext',args['collapsetext'] or args['defaultcollapsetext'] or hideText)
:cssText(args.bodystyle)
if args.state == 'collapsed' then
:cssText(args.style)
navbox:addClass('mw-collapsed')
:css('padding', '3px')
end
:node(tbl)
-- aria-labelledby title, otherwise above, otherwise lone group
if args.title or args.above or (args.group1 and not args.group2) then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title or args.above or args.group1))
else
nav:attr('aria-label', 'Navbox')
end
end
end
end
 
if (args.nocat or 'false'):lower() == 'false' then
if args.bodyclass then navbox:addClass(args.bodyclass) end
renderTrackingCategories(res)
if args.bodystyle then navbox:cssText(args.bodystyle) end
-- Process...
if not isChild then
processTitle()
processAboveBelow('above')
processRows()
processAboveBelow('below')
return tostring(navbox)
else
processRows()
local wrapper = mw.html.create('')
wrapper:wikitext('</div>')
wrapper:node(navbox)
wrapper:wikitext('<div class="hlist">')
return tostring(wrapper)
end
end
return striped(tostring(res))
end
end
 
function p.navbox(frame)
--- Main module entry point.
if not getArgs then
-- To be called with {{#invoke:navbox|main}} or directly from another module.
getArgs = require('Module:Arguments').getArgs
--
end
-- @param frame The frame passed to the module via the #invoke. If called from another
args = getArgs(frame, {wrappers = {'Template:Navbox'}})
--              module directly, this should be a table with the parameter definition.
 
function p.main(frame)
-- Read the arguments in the order they'll be output in, to make references number in the right order.
-- Save the arguments in a local variable so other functions can use them.
local _
preProcessArgs(frame)
_ = args.title
_ = args.above
return _navbox()
for i = 1, 20 do
_ = args["group" .. tostring(i)]
_ = args["list" .. tostring(i)]
end
_ = args.below
 
return p._navbox(args)
end
end
 
return p
return p