模块:Navbox:修订间差异
(创建页面,内容为“-- This Module is used for making templates based in the Lua language. -- See more details about Lua in w:Help:Lua. -- The Fandom Developer's Wiki hosts Global Lua Modules that can be imported and locally overridden. -- The next line imports the Navbox module from the w:c:dev:Global Lua Modules. local N = require('Dev:Navbox') -- See more details about this module at w:c:dev:Global_Lua_Modules/Navbox -- The last line produces the output for the tem…”) |
无编辑摘要 |
||
第1行: | 第1行: | ||
-- | -------------------------------------------------------------------- | ||
-- | --<pre> Navbox Module | ||
-- | -- | ||
-- | -- * Fully CSS styled (inline styles possible but not default) | ||
-- * Supports unlimited rows | |||
-- | -- | ||
-- By User:Tjcool007 from layton.fandom.com | |||
-------------------------------------------------------------------- | |||
-- The | local p = {} | ||
return | |||
local args = {} -- Arguments passed to template | |||
local navbox -- Actual navbox | |||
--local working = {} | |||
local rownums, skiprows = {}, {} | |||
local hasrows, alt, hasData, isChild = false, false, false, false | |||
local activeSection, sections, cimage, cimageleft | |||
local colspan, rowspan | |||
local showText, hideText = 'Show', 'Hide' | |||
local langCode = mw.getContentLanguage():getCode() | |||
local localization = {} --localized strings table | |||
localization['bn'] = {show = 'দেখান', hide = 'লুকান'} | |||
localization['de'] = {show = 'Ausklappen', hide = 'Einklappen'} | |||
localization['en'] = {show = 'Show', hide = 'Hide'} | |||
localization['es'] = {show = 'Mostrar', hide = 'Ocultar'} | |||
localization['hi'] = {show = 'दिखाएँ', hide = 'छिपाएँ'} | |||
localization['ja'] = {show = '表示', hide = '隠す'} | |||
localization['ru'] = {show = 'показать', hide = 'скрыть'} | |||
localization['pt-br'] = {show = 'Mostrar', hide = 'Esconder'} | |||
localization['zh'] = {show = '显示', hide = '隐藏'} | |||
localization['zh-tw'] = {show = '顯示', hide = '隱藏'} | |||
localization['zh-hk'] = {show = '顯示', hide = '隱藏'} | |||
if localization[langCode] then | |||
showText = localization[langCode]['show'] | |||
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 | |||
titlecell:wikitext( args.title or '{{{title}}}' ) | |||
-- 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 | |||
titlecell:addClass('navbox-title-padleft') | |||
end | |||
end | |||
if args.titleclass then titlerow:addClass( args.titleclass ) end | |||
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 | |||
imagecell:css('width','0%'):wikitext(image) | |||
end | |||
if args[imgtype .. 'class'] then imagecell:addClass( args[imgtype .. 'class'] ) end | |||
if args[imgtype .. 'style'] then imagecell:cssText( args[imgtype .. 'style'] ) end | |||
row:node( imagecell ) | |||
if imgtype == 'image' then | |||
cimage = imagecell | |||
else | |||
cimageleft = imagecell | |||
end | |||
end | |||
--- Closes the currently active section (if any) | |||
local function _closeCurrentSection() | |||
if not activeSection then return end | |||
local row = mw.html.create('tr'):addClass('navbox-section-row') | |||
local cell = mw.html.create('td'):attr('colspan',2) | |||
if not hasrows then | |||
_processImage(row,'imageleft') | |||
end | |||
cell:node(sections[activeSection]) | |||
row:node(cell) | |||
local firstRow = false | |||
if not hasrows then | |||
firstRow = true | |||
hasrows = true | |||
_processImage(row,'image') | |||
end | |||
_addGutter(navbox,not firstRow) | |||
navbox:node(row) | |||
rowspan = rowspan + 1 | |||
activeSection = false | |||
hasData = false | |||
end | |||
--- Handles alternating rows | |||
-- | |||
-- @return Alternatingly returns true or false. Always returns false if alternating rows | |||
-- are disabled with "alternaterows = no" | |||
local function _alternateRow() | |||
if args.alternaterows == 'no' then return false end | |||
if alt then | |||
alt = false | |||
return true | |||
else | |||
alt = true | |||
return false | |||
end | |||
end | |||
--- Process a single Header "row" | |||
-- | |||
-- @param num Number of the row to be processed | |||
local function processHeader(num) | |||
if not args['header'..num] then return end | |||
_closeCurrentSection() | |||
local subtable = mw.html.create('table'):addClass('navbox-section') | |||
local headerrow = mw.html.create('tr') | |||
local header = mw.html.create('th'):addClass('navbox-header'):attr('colspan',2):attr('scope','col'):wikitext( args['header'..num] ) | |||
local collapseme = args['state'..num] or false | |||
local state = false | |||
if collapseme then | |||
-- Look at this one | |||
if collapseme ~= 'plain' then | |||
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 | |||
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 state == 'collapsed' then | |||
subtable:addClass('mw-collapsed') | |||
end | |||
header:addClass('navbox-header-collapsible') | |||
end | |||
if args.headerclass then headerrow:addClass( args.headerclass ) end | |||
if args.headerstyle then header:cssText( args.headerstyle ) end | |||
headerrow:node(header) | |||
subtable:node(headerrow) | |||
sections[num] = subtable | |||
activeSection = num | |||
end | |||
--- Processes a single list row | |||
-- | |||
-- @param num Number of the row to be processed | |||
local function processList(num) | |||
if not args['list'..num] then return end | |||
local row = mw.html.create('tr'):addClass('navbox-row') | |||
if not hasrows and not activeSection then | |||
_processImage(row, 'imageleft') | |||
end | |||
local listcell = mw.html.create('td'):addClass('navbox-list') | |||
local hlistcell = listcell:tag('div'):addClass('hlist') | |||
local data = args['list'..num] | |||
if data:sub(1,1) == '*' then | |||
-- Add newlines to support lists properly | |||
hlistcell | |||
:newline() | |||
:wikitext( data ) | |||
:newline() | |||
else | |||
hlistcell:wikitext( data ) | |||
end | |||
local altRow = _alternateRow() | |||
if altRow then | |||
row:addClass( args.altrowclass or 'alt' ) | |||
local listclass = args.altlistclass or args.listclass or false | |||
if listclass then listcell:addClass( listclass ) end | |||
local liststyle = args.altliststyle or args.liststyle or false | |||
if liststyle then listcell:cssText( liststyle ) end | |||
else | |||
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 | |||
if args['group'..num] then | |||
local groupcell = mw.html.create('th'):addClass('navbox-group'):attr('scope','row'):wikitext( args['group'..num] ) | |||
if altRow then | |||
local groupclass = args.altgroupclass or args.groupclass or false | |||
if groupclass then groupcell:addClass( groupclass ) end | |||
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 | |||
listcell:attr('colspan',2):addClass('no-group') | |||
end | |||
row:node( listcell ) | |||
local firstRow = false | |||
if not hasrows and not activeSection then | |||
firstRow = true | |||
hasrows = true | |||
_processImage(row, 'image') | |||
end | |||
if activeSection then | |||
local parent = sections[activeSection] | |||
if not isChild or not firstRow then | |||
_addGutter(parent) | |||
end | |||
parent:node(row) | |||
hasData = true | |||
else | |||
if not isChild or not firstRow then | |||
_addGutter(navbox,not firstRow) | |||
end | |||
navbox:node( row ) | |||
rowspan = rowspan + 1 | |||
end | |||
end | |||
--- Processes all rows | |||
local function processRows() | |||
sections = {} | |||
for i=1,#rownums do | |||
local num = rownums[i] | |||
if not skiprows[num] then | |||
processHeader(num) | |||
processList(num) | |||
end | |||
end | |||
_closeCurrentSection() | |||
if cimageleft then | |||
cimageleft:attr('rowspan',rowspan) | |||
end | |||
if cimage then | |||
cimage:attr('rowspan',rowspan) | |||
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. | |||
-- | |||
-- @param frame The frame passed to the Module. | |||
local function preProcessArgs(frame) | |||
local tmp = {} | |||
if frame == mw.getCurrentFrame() then | |||
tmp = frame:getParent().args | |||
else | |||
tmp = frame | |||
end | |||
-- Storage tables | |||
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 | |||
colspan = args.image and 3 or 2 | |||
if args.imageleft then colspan = colspan + 1 end | |||
rowspan = 0 | |||
if args.alternaterows == 'swap' then | |||
alt = true | |||
end | |||
for k, v in pairs(nums) do | |||
rownums[#rownums+1] = tonumber(k) | |||
end | |||
table.sort(rownums) | |||
-- Calculate skip rows | |||
local cSection, cSkip | |||
local showall = args.showall | |||
for i=1,#rownums do | |||
local num = rownums[i] | |||
if args['header'..num] then | |||
cSection = true | |||
cSkip = false | |||
local showme = args['show'..num] | |||
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 | |||
------------------------------------------------ | |||
-- MAIN FUNCTIONS | |||
------------------------------------------------ | |||
--- 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 | |||
local border = args.border or trim(args[1]) or '' | |||
isChild = (border == 'child' or border == 'subgroup') | |||
if isChild then | |||
navbox = mw.html.create('table'):addClass('navbox-subgroup') | |||
else | |||
navbox = mw.html.create('table'):addClass('navbox') | |||
if args.state ~= 'plain' then | |||
navbox:addClass('mw-collapsible'):attr('data-expandtext',args['expandtext'] or args['defaultexpandtext'] or showText):attr('data-collapsetext',args['collapsetext'] or args['defaultcollapsetext'] or hideText) | |||
if args.state == 'collapsed' then | |||
navbox:addClass('mw-collapsed') | |||
end | |||
end | |||
end | |||
if args.bodyclass then navbox:addClass(args.bodyclass) end | |||
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 | |||
--- Main module entry point. | |||
-- To be called with {{#invoke:navbox|main}} or directly from another module. | |||
-- | |||
-- @param frame The frame passed to the module via the #invoke. If called from another | |||
-- module directly, this should be a table with the parameter definition. | |||
function p.main(frame) | |||
-- Save the arguments in a local variable so other functions can use them. | |||
preProcessArgs(frame) | |||
return _navbox() | |||
end | |||
return p |
2024年3月20日 (三) 15:51的版本
This module is invoked by the {{Navbox}} template. Navbox templates are not displayed for mobile users.
--------------------------------------------------------------------
--<pre> Navbox Module
--
-- * Fully CSS styled (inline styles possible but not default)
-- * Supports unlimited rows
--
-- By User:Tjcool007 from layton.fandom.com
--------------------------------------------------------------------
local p = {}
local args = {} -- Arguments passed to template
local navbox -- Actual navbox
--local working = {}
local rownums, skiprows = {}, {}
local hasrows, alt, hasData, isChild = false, false, false, false
local activeSection, sections, cimage, cimageleft
local colspan, rowspan
local showText, hideText = 'Show', 'Hide'
local langCode = mw.getContentLanguage():getCode()
local localization = {} --localized strings table
localization['bn'] = {show = 'দেখান', hide = 'লুকান'}
localization['de'] = {show = 'Ausklappen', hide = 'Einklappen'}
localization['en'] = {show = 'Show', hide = 'Hide'}
localization['es'] = {show = 'Mostrar', hide = 'Ocultar'}
localization['hi'] = {show = 'दिखाएँ', hide = 'छिपाएँ'}
localization['ja'] = {show = '表示', hide = '隠す'}
localization['ru'] = {show = 'показать', hide = 'скрыть'}
localization['pt-br'] = {show = 'Mostrar', hide = 'Esconder'}
localization['zh'] = {show = '显示', hide = '隐藏'}
localization['zh-tw'] = {show = '顯示', hide = '隱藏'}
localization['zh-hk'] = {show = '顯示', hide = '隱藏'}
if localization[langCode] then
showText = localization[langCode]['show']
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
titlecell:wikitext( args.title or '{{{title}}}' )
-- 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
titlecell:addClass('navbox-title-padleft')
end
end
if args.titleclass then titlerow:addClass( args.titleclass ) end
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
imagecell:css('width','0%'):wikitext(image)
end
if args[imgtype .. 'class'] then imagecell:addClass( args[imgtype .. 'class'] ) end
if args[imgtype .. 'style'] then imagecell:cssText( args[imgtype .. 'style'] ) end
row:node( imagecell )
if imgtype == 'image' then
cimage = imagecell
else
cimageleft = imagecell
end
end
--- Closes the currently active section (if any)
local function _closeCurrentSection()
if not activeSection then return end
local row = mw.html.create('tr'):addClass('navbox-section-row')
local cell = mw.html.create('td'):attr('colspan',2)
if not hasrows then
_processImage(row,'imageleft')
end
cell:node(sections[activeSection])
row:node(cell)
local firstRow = false
if not hasrows then
firstRow = true
hasrows = true
_processImage(row,'image')
end
_addGutter(navbox,not firstRow)
navbox:node(row)
rowspan = rowspan + 1
activeSection = false
hasData = false
end
--- Handles alternating rows
--
-- @return Alternatingly returns true or false. Always returns false if alternating rows
-- are disabled with "alternaterows = no"
local function _alternateRow()
if args.alternaterows == 'no' then return false end
if alt then
alt = false
return true
else
alt = true
return false
end
end
--- Process a single Header "row"
--
-- @param num Number of the row to be processed
local function processHeader(num)
if not args['header'..num] then return end
_closeCurrentSection()
local subtable = mw.html.create('table'):addClass('navbox-section')
local headerrow = mw.html.create('tr')
local header = mw.html.create('th'):addClass('navbox-header'):attr('colspan',2):attr('scope','col'):wikitext( args['header'..num] )
local collapseme = args['state'..num] or false
local state = false
if collapseme then
-- Look at this one
if collapseme ~= 'plain' then
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
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 state == 'collapsed' then
subtable:addClass('mw-collapsed')
end
header:addClass('navbox-header-collapsible')
end
if args.headerclass then headerrow:addClass( args.headerclass ) end
if args.headerstyle then header:cssText( args.headerstyle ) end
headerrow:node(header)
subtable:node(headerrow)
sections[num] = subtable
activeSection = num
end
--- Processes a single list row
--
-- @param num Number of the row to be processed
local function processList(num)
if not args['list'..num] then return end
local row = mw.html.create('tr'):addClass('navbox-row')
if not hasrows and not activeSection then
_processImage(row, 'imageleft')
end
local listcell = mw.html.create('td'):addClass('navbox-list')
local hlistcell = listcell:tag('div'):addClass('hlist')
local data = args['list'..num]
if data:sub(1,1) == '*' then
-- Add newlines to support lists properly
hlistcell
:newline()
:wikitext( data )
:newline()
else
hlistcell:wikitext( data )
end
local altRow = _alternateRow()
if altRow then
row:addClass( args.altrowclass or 'alt' )
local listclass = args.altlistclass or args.listclass or false
if listclass then listcell:addClass( listclass ) end
local liststyle = args.altliststyle or args.liststyle or false
if liststyle then listcell:cssText( liststyle ) end
else
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
if args['group'..num] then
local groupcell = mw.html.create('th'):addClass('navbox-group'):attr('scope','row'):wikitext( args['group'..num] )
if altRow then
local groupclass = args.altgroupclass or args.groupclass or false
if groupclass then groupcell:addClass( groupclass ) end
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
listcell:attr('colspan',2):addClass('no-group')
end
row:node( listcell )
local firstRow = false
if not hasrows and not activeSection then
firstRow = true
hasrows = true
_processImage(row, 'image')
end
if activeSection then
local parent = sections[activeSection]
if not isChild or not firstRow then
_addGutter(parent)
end
parent:node(row)
hasData = true
else
if not isChild or not firstRow then
_addGutter(navbox,not firstRow)
end
navbox:node( row )
rowspan = rowspan + 1
end
end
--- Processes all rows
local function processRows()
sections = {}
for i=1,#rownums do
local num = rownums[i]
if not skiprows[num] then
processHeader(num)
processList(num)
end
end
_closeCurrentSection()
if cimageleft then
cimageleft:attr('rowspan',rowspan)
end
if cimage then
cimage:attr('rowspan',rowspan)
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.
--
-- @param frame The frame passed to the Module.
local function preProcessArgs(frame)
local tmp = {}
if frame == mw.getCurrentFrame() then
tmp = frame:getParent().args
else
tmp = frame
end
-- Storage tables
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
colspan = args.image and 3 or 2
if args.imageleft then colspan = colspan + 1 end
rowspan = 0
if args.alternaterows == 'swap' then
alt = true
end
for k, v in pairs(nums) do
rownums[#rownums+1] = tonumber(k)
end
table.sort(rownums)
-- Calculate skip rows
local cSection, cSkip
local showall = args.showall
for i=1,#rownums do
local num = rownums[i]
if args['header'..num] then
cSection = true
cSkip = false
local showme = args['show'..num]
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
------------------------------------------------
-- MAIN FUNCTIONS
------------------------------------------------
--- 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
local border = args.border or trim(args[1]) or ''
isChild = (border == 'child' or border == 'subgroup')
if isChild then
navbox = mw.html.create('table'):addClass('navbox-subgroup')
else
navbox = mw.html.create('table'):addClass('navbox')
if args.state ~= 'plain' then
navbox:addClass('mw-collapsible'):attr('data-expandtext',args['expandtext'] or args['defaultexpandtext'] or showText):attr('data-collapsetext',args['collapsetext'] or args['defaultcollapsetext'] or hideText)
if args.state == 'collapsed' then
navbox:addClass('mw-collapsed')
end
end
end
if args.bodyclass then navbox:addClass(args.bodyclass) end
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
--- Main module entry point.
-- To be called with {{#invoke:navbox|main}} or directly from another module.
--
-- @param frame The frame passed to the module via the #invoke. If called from another
-- module directly, this should be a table with the parameter definition.
function p.main(frame)
-- Save the arguments in a local variable so other functions can use them.
preProcessArgs(frame)
return _navbox()
end
return p