模組:NavboxV2
维基百科,自由的 encyclopedia
更多信息 项目, {{Navbox}}系列,参考基准 ...
关闭
更多信息 {{Navbox}}系列, 本模板 ...
{{Navbox}}系列 | 本模板 |
---|---|
{{Navbox
|name = Navbox/doc
|state = expanded
|image = {{{image}}}
|imageleft = {{{imageleft}}}
|title = {{{title}}}
|above = {{{above}}}
|group1 = {{{group1}}}
|list1 = {{Navbox subgroup
| title = {{{list1-title}}}
| above = {{{list1-above}}}
| below = {{{list1-below}}}
| imageleft = {{{list1-imageleft}}}
| image = {{{list1-image}}}
| group1 = {{{list1-group1}}}
| list1 = {{{list1-list1}}}
| group2 = {{{list1-group2}}}
| list2 = {{{list1-list2}}}
}}
|group2 = {{{group2}}}
|list2 = {{Navbox subgroup
| group1 = {{{list2-group1}}}
| list1 = {{{list2-list1}}}
| group2 = {{{list2-group2}}}
| list2 = {{{list2-list2}}}
}}
|below = {{{below}}}
}}
|
{{NavboxV2
|name = Navbox/doc
|state = expanded
|image = {{{image}}}
|imageleft = {{{imageleft}}}
|title = {{{title}}}
|above = {{{above}}}
<!-- list1 -->
|group1 = {{{group1}}}
<!-- list1-sub-->
|list1-type =vertical <!--作为list1的子Navbox层,全部相应参数加上对应前缀“list1-”,下同,如此类推 -->
|list1-border=child
|list1-title = {{{list1-title}}}
|list1-above = {{{list1-above}}}
|list1-below = {{{list1-below}}}
|list1-imageleft = {{{list1-imageleft}}}
|list1-image = {{{list1-image}}}
|list1-group1 = {{{list1-group1}}}
|list1-list1 = {{{list1-list1}}}
|list1-group2 = {{{list1-group2}}}
|list1-list2 = {{{list1-list2}}}
<!-- list2 -->
|group2 = {{{group2}}}
<!-- list2-sub-->
|list2-type =vertical <!--作为list2的子Navbox层,全部相应参数加上对应前缀“list2-”,下同,如此类推 -->
|list2-border=child
|list2-group1 = {{{list2-group1}}}
|list2-list1 = {{{list2-list1}}}
|list2-group2 = {{{list2-group2}}}
|list2-list2 = {{{list2-list2}}}
<!--end-->
|below = {{{below}}}
}}
|
关闭
![]() | 此模块被引用於約31,000個頁面。 為了避免造成大規模的影響,所有對此模块的編輯應先於沙盒或測試樣例上測試。 測試後無誤的版本可以一次性地加入此模块中,但是修改前請務必於討論頁發起討論。 模板引用數量會自動更新。 |
![]() | 此模板不能在维基百科的移动视图中显示,只能在桌面版显示。请阅读文档以获得解释。 |
这是{{NavboxV2}}的Lua实现代码。
简介
合并了{{Navbox}}相关的一系列模板。融合了{{Navbox}}的行式、{{Navbox subgroup}}的子代模块包含、{{Navbox with columns}}的列式,{{Navbox with collapsible groups}})的折叠行式。
改写自模块:Navbox(oldid=42280913)。
设计用途
在Category:引用模板后大小超过限制的页面中,有相当一部分页面是由于{{Navbox}}模板超载导致。
- 根据WP:模板限制中“嵌套展开”的说法,相同页面的多次嵌套调用是会被分次统计的(例如:页面A嵌入页面B,页面B嵌入页面C,页面C相对页面A统计到的展开字节数是被计算了2次)。而现在Navbox的子代块、列式,折叠行式的实现都是基于Navbox行式的模板调用或类似样式结构迭代,这样就符合内部多次调用Navbox的条件,页面很容易会超过模版展开后大小的限制。
- 其次,实际上Lua的运行限制条件相当宽裕,50MB的内存限制,10秒的运行时限制,很多页面实际使用只在十分之一左右或以下,可以被大量压榨性能。
所以将Navbox所有的实现全部以Lua实现,希望能腾出解释器运行量到Lua运行量,降低解析器触发展开后大小限制的可能。
效果
- 在对于包含一层子Navbox的情况,展开后大小下降最多有50~60%左右。
对比例子
参数
与{{Navbox}}系列模板基本兼容。但新增部分参数填入:
type
:Navbox的类型,对应值为vertical
(对应{{Navbox}})、horizontal
(对应{{Navbox with columns}})、vertical_collapsible
(对应{{Navbox with collapsible groups}}),默认值为vertical
。border
:Navbox的隐藏参数,用于控制Navbox的边框机制,来使子Navbox能被嵌入到父Navbox的值字段(例如list
、col
等)中,实际对应{{Navbox subgroup}}或{{Navbox|child}}的实现机制。对应值为child
、subgroup
任一个。
- 在本模板添加子Navbox层时,必须传入这两个参数,这是本模板区分是否存在子Navbox层的依赖。本模板首层Navbox层无需添加
border
,按需添加type
。
- 在本模板添加子Navbox层时,必须传入这两个参数,这是本模板区分是否存在子Navbox层的依赖。本模板首层Navbox层无需添加
removeGroupPadding
:用于区别{{Navbox|child}}和{{Navbox subgroup}},后者在Groupn字段的单元格增加一组padding的配置,适用于子Navbox层。任意值,存在则可,为移除该padding配置(对应{{Navbox|child}})。
方便复制的代码:
| <list/content>-type = vertical | horizontal | vertical_collapsible | <list/content>-border = child| subgroup | <list/content>-removeGroupPadding = 1
自{{Navbox}}系列模板转换
将原有嵌入{{Navbox}}系列模板的值字段listn
(其他类同)改为listn-
,并作为相应嵌套子Navbox模板的参数的前缀来加入,使这些模板嵌套转换为扁平化的一层模板参数。
转换注意
由于{{Navbox}}系列的实现较为复杂和涉及自我嵌套,本模板的实现也为此做了对应兼容性调整,可能会出现一些参数被过度透传(可能在样式控制部分,原因是原有设计通过控制参数传入来隔离,而本设计为了使参数扁平化,导致部分这些参数无法隔离)。而且模板参数非常依赖命名规律,在转换替换前,请进行testcase检查,确认转换后能与原来的样式、功能基本一致,才应用转换。如果出现问题,请保留案例并联系本模板维护编辑协助处理,或者放弃。
虽然可以在值字段(例如list
、col
等)重新嵌入{{Navbox}}系列模板,但这和原有做法一样,失去了本模板降低解析器限制的作用,不建议这样做。
上述文档嵌入自Module:NavboxV2/doc。 (编辑 | 历史) 编者可以在本模块的沙盒 (编辑 | 差异)和测试样例 (创建)页面进行实验。 本模块的子页面。 |
--
-- This module will implement {{Navbox}}
--
local p = {}
-- Context start
local _NavboxContext = {}
local NavboxContextNewObj = function(_prefix, _level, _type, _parent)
return {
['prefix'] = _prefix,
['level'] = _level,
['type'] = _type,
['_Context'] = {}
}
end
local NavboxContextMetaFunction = {
__index = function(_obj, key)
local _key = tostring(key)
if _key == 'prefix' or _key == 'level' or _key == 'type' then
return rawget(_obj, _key)
else
return rawget(_obj, '_Context')[_key]
end
end,
__newindex = function(_obj, key, val)
local _key = tostring(key)
if _key == 'prefix' or _key == 'level' or _key == 'type' then
rawset(_obj, _key, val)
else
rawget(_obj, '_Context')[_key] = val
end
end,
__tostring = function(_obj)
local output = {}
table.insert(output, 'prefix=' .. _obj['prefix'])
table.insert(output, 'level=' .. _obj['level'])
table.insert(output, 'type=' .. _obj['type'])
for k, v in pairs(_obj._Context) do
local t_v = v
if t_v == nil then
t_v = ''
elseif type(t_v) == 'table' then
t_v = tableToString(t_v)
end
table.insert(output, k .. '=' .. t_v)
end
return 'context:{\n' .. table.concat(output, ",\n") .. '\n}'
end
}
_NavboxContext.new = function(prefix, level, t_type)
local _prefix = prefix or ""
local _level = level or 1
local _type = t_type or ''
local newobj = NavboxContextNewObj(_prefix, _level, _type)
setmetatable(newobj, NavboxContextMetaFunction)
return newobj
end
-- Context end
local navbarFunc = require('Module:Navbar')._navbar
local NavboxContext = _NavboxContext
local getArgs -- lazily initialized
local DEBUG = false
p.NavboxContext = NavboxContext
-- 全局性参数锚
local args
-- 常量定义 (Constant Define)
local Limit = {
vertical = 35,
horizontal = {col = 20, list = 10}, --原Navbox with columns为6个list,放宽至10
vertical_collapsible = 20,
child = 10
}
local NavType = {
V = "vertical" -- 垂直,list
,
H = "horizontal" -- 水平,col
,
VC = "vertical_collapsible" -- 折叠垂直
}
local MainTemplateName = 'Template:NavboxV2'
---------------------------------------------------------------
--
-- 工具箱方法 (Util Function)
--
local trim = function(s)
return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))
end
local addNewline = function(s)
if mw.ustring.match(s,'^[*:;#]') or mw.ustring.match(s,'^{|') then
return '\n' .. s .. '\n'
else
return s
end
end
---数组除重
local removeDump = function(arr)
local _t1, _t2 = {}, {}
for _, val in pairs(arr) do _t1[val] = true end
for key, _ in pairs(_t1) do table.insert(_t2, key) end
return _t2
end
function tableToString(_table)
local outputs = {}
if _table == nil then
table.insert(outputs, '<nil>')
elseif type(_table) == 'table' then
for k, v in pairs(_table) do
local output
if type(v) == 'table' then
output = tableToString(v)
else
output = tostring(v)
end
table.insert(outputs, tostring(k) .. "=" .. output)
end
end
return '{' .. table.concat(outputs, ",") .. '}'
end
function debugLog(...)
if DEBUG then
if #arg == 1 then
mw.log(tostring(arg[1]))
--mw.log("--------------------")
else
for k, v in pairs(arg) do
local pass = false or tostring(k) == 'n'
if not pass then
local _v = v
if type(v) == 'table' then
_v = tableToString(v)
end
mw.log(tostring(_v))
end
end
end
end
end
---------------------------------------------------------------
--
-- 功能性方法 (Functional Function)
--
---获得有效的类型
local getValidType = function(input, defVal)
return (NavType.V == input or NavType.H == input or NavType.VC == input) and input or defVal
end
---检查border判断是不是子Navbox
local borderIsChild = function(border)
return (border == 'subgroup' or border == 'child')
end
-- 前缀生成
function makePrefix(oldPrefix,thisLevel)
return oldPrefix == "" and thisLevel or (oldPrefix .. '-' ..thisLevel)
end
---获得参数
local getArg = function(_prefix, _argKey, defVal, context, _contextKey)
local contextKey = _contextKey or _argKey
if context and contextKey and context[contextKey] then
-- debugLog('getArg By Context',contextKey)
return context[contextKey]
else
local prefix = _prefix ~= nil and _prefix or ""
local key = (_argKey == nil and _prefix ~= nil) and _prefix or _argKey
local argsKey = makePrefix(prefix, key)
-- debugLog('getArg By InputArg',argsKey)
return args[argsKey] or defVal
end
end
---子Navbox参数组判断
local checkHaveChild = function(prefix, valuekey)
return (
getValidType(getArg(prefix, valuekey .. '-type'), nil) and
borderIsChild(getArg(prefix, valuekey .. '-border'))
) == true
end
---获得listnum
local getListnum = function(prefix, limit, contentEqList)
debugLog("getListnum", {['prefix'] = prefix, ['limit'] = limit})
prefix = mw.ustring.gsub(prefix,'(-)', '%%-')
local listnums = {}
local middle = (prefix == "" and "" or "%-")
local listKeyMatch , contentKeyMatch=
'^' .. prefix .. middle .. 'list(%d+)',
'^' .. prefix .. middle .. 'content(%d+)'
local listKeyMatchEnd , listKeyMatchSub , contentKeyMatchEnd , contentKeyMatchSub =
listKeyMatch .. '$' , listKeyMatch .. '%-' ,
contentKeyMatch .. '$' , contentKeyMatch .. '%-'
for k, v in pairs(args) do
k = '' .. k
-- debugLog("getListnum,k=",k)
local listnum =
(
mw.ustring.match(k,listKeyMatch..'$') or
mw.ustring.match(k,listKeyMatch..'%-')
) or
(
contentEqList and ( -- VerticalCollapsibleTable 的 Content适配
mw.ustring.match(k,contentKeyMatch..'$') or
mw.ustring.match(k,contentKeyMatch..'%-')
) or nil
)
if listnum and tonumber(listnum) <= limit then
listnum = tonumber(listnum)
table.insert(listnums, listnum)
end
end
listnums = removeDump(listnums)
table.sort(listnums)
debugLog('list:', listnums)
debugLog('getListnum End')
return listnums
end
---参数检查和摇匀
function p.shakeArgs(prefix, level, _type)
local _
local list_limit = 0
_type = _type or getArg(prefix, "type")
_ = getArg(prefix, "title")
_ = getArg(prefix, "above")
if _type == NavType.H then
list_limit = Limit.horizontal.list
for i = 1, Limit.horizontal.col do
_ = getArg(prefix, "col" .. tostring(i) .. "header")
--[[if checkHaveChild(prefix, "col" .. tostring(i) .. "header") then
p.shakeArgs(makePrefix(prefix,"col" .. tostring(i) .. "header" ), level + 1)
end ]]
_ = getArg(prefix, "col" .. tostring(i))
if checkHaveChild(prefix, "col" .. tostring(i)) then
p.shakeArgs(makePrefix(prefix, "col" .. tostring(i)), level + 1)
end
_ = getArg(prefix, "col" .. tostring(i) .. "footer")
--[[if checkHaveChild(prefix, "col" .. tostring(i) .. "footer") then
p.shakeArgs(makePrefix(prefix, "col" .. tostring(i) .."footer" ), level + 1)
end ]]
end
elseif _type == NavType.V then
list_limit = Limit.vertical
elseif _type == NavType.VC then
list_limit = Limit.vertical_collapsible
end
for i = 1, list_limit do
_ = getArg(prefix, "group" .. tostring(i))
_ = getArg(prefix, "list" .. tostring(i))
if checkHaveChild(prefix, "list" .. tostring(i)) then
p.shakeArgs(makePrefix(prefix, "list" .. tostring(i)), level + 1)
end
if checkHaveChild(prefix, "content" .. tostring(i)) then
p.shakeArgs(makePrefix(prefix, "content" .. tostring(i)), level + 1)
end
end
_ = getArg(prefix, "below")
end
---------------------------------------------------------------
--
-- 元素渲染方法 (Element Render)
--
---创建表头
local function createNavTableHeader(context)
debugLog('render TableHeader', context)
local prefix = context.prefix
local state, title, border = getArg(prefix, "state", nil, context),
getArg(prefix, "title"),
getArg(prefix, "border", nil, context)
debugLog('render TableHeader args', {
['prefix'] = prefix,
['state'] = state,
['title'] = title,
['border'] = border
})
local rootTable =
mw.html.create('table')
:attr('cellspacing', 0)
:addClass('nowraplinks')
:addClass(getArg(prefix, "bodyclass", nil, context))
:css('border-spacing', 0)
if title and (state ~= 'plain' and state ~= 'off') then
if state == 'collapsed' then state = 'mw-collapsed' end -- mw-collapsible 对应 展开模式
rootTable
:addClass('mw-collapsible')
:addClass(state or 'autocollapse')
end
if borderIsChild(border) or border == 'none' then
rootTable
:addClass('navbox-subgroup')
:cssText(getArg(prefix,"bodystyle", nil,context))
:cssText(getArg(prefix, "style", nil, context))
else -- regular navobx - bodystyle and style will be applied to the wrapper table
rootTable
:addClass('navbox-inner')
:css('background', 'transparent')
:css('color', 'inherit')
end
rootTable:cssText(getArg(prefix, "innerstyle"))
debugLog('render TableHeader End')
return rootTable
end
---分割行 (SplitRow)
local function renderSplitRow(rootTable, context)
local colspan = context.splitRowcolspan or context.totalColspan
debugLog('render SplitRow', {
['needAddSplitRow'] = context.needAddSplitRow,
['colspan'] = colspan
}, context)
if context.needAddSplitRow then
rootTable
:tag('tr')
:css('height', '2px')
:tag('td')
:attr('colspan',colspan)
end
context.splitRowcolspan = colspan
context.needAddSplitRow = true
end
---创建三键导航
local function renderNavBar(titleCell, context)
local prefix = context.prefix
local navbar, state, border, name, titlestyle =
getArg(prefix, "navbar", nil, context),
getArg(prefix, "state", nil, context),
getArg(prefix, "border", nil, context),
getArg(prefix, "name"),
getArg(prefix, 'titlestyle', nil, context)
debugLog('render Navbar', {
['prefix'] = prefix,
['navbar'] = navbar,
['state'] = state,
['border'] = border,
['name'] = name,
['titlestyle'] = titlestyle
}, context)
-- Depending on the presence of the navbar and/or show/hide link, we may need to add a spacer div on the left
-- or right to keep the title centered.
local spacerSide = nil
if navbar == 'off' then
-- No navbar, and client wants no spacer, i.e. wants the title to be shifted to the left. If there's
-- also no show/hide link, then we need a spacer on the right to achieve the left shift.
if state == 'plain' then spacerSide = 'right' end
elseif navbar == 'plain' or (
(not name) and
mw.getCurrentFrame():getParent():getTitle() == MainTemplateName and
(borderIsChild(border) or border == 'none')
) then
-- No navbar. Need a spacer on the left to balance out the width of the show/hide link.
if state ~= 'plain' then spacerSide = 'left' end
else
-- Will render navbar (or error message). If there's no show/hide link, need a spacer on the right
-- to balance out the width of the navbar.
if state == 'plain' then spacerSide = 'right' end
titleCell
:wikitext(navbarFunc {
name,
mini = 1,
fontstyle = table.concat({
'color:inherit',
getArg(prefix, 'basestyle', nil, context) or '',
(titlestyle or ''),
'background:none transparent;border:none'
}, ';')
})
end
-- Render the spacer div.
if spacerSide then
titleCell
:tag('span')
:addClass("spacer")
:css('float', spacerSide)
:css('position', 'absolute')
:css(spacerSide, '1em')
:css('margin-' ..(spacerSide == 'left' and 'right' or'left'), '0.5em')
:css('padding-' .. spacerSide, '0.2em')
:wikitext(' ')
end
debugLog('render Navbar End')
end
---标题行
local function renderTitleRow(rootTable, context)
local prefix = context.prefix
local title = getArg(prefix, "title", nil, context)
if not title then return end
debugLog('render TitleRow', {
['prefix'] = prefix,
['title'] = title
},context)
local basestyle = getArg(prefix, "basestyle", nil, context)
renderSplitRow(rootTable, context)
local titleRow = rootTable:tag('tr')
local titlegroup = getArg(prefix, "titlegroup")
local needTitleGroup = titlegroup and (not context.notNeedTitlegroup)
if needTitleGroup then
titleRow
:tag('th')
:attr('scope', 'row')
:addClass('navbox-group')
:addClass(getArg(prefix, "titlegroupclass"))
:cssText(basestyle)
:cssText(getArg(prefix, "groupstyle", nil, context))
:cssText(getArg(prefix,"titlegroupstyle"))
:wikitext(titlegroup)
end
local titleCell = titleRow:tag('th'):attr('scope', 'col')
local titleColspan = context.totalColspan
if needTitleGroup then
titleCell
:css('border-left', '2px solid #fdfdfd')
:css('width', '100%')
titleColspan = titleColspan - 1
end
titleCell
:cssText(basestyle)
:cssText(getArg(prefix, "titlestyle", nil, context))
:addClass('navbox-title')
:addClass(getArg(prefix, "titleclass", nil, context))
:attr('colspan',titleColspan)
renderNavBar(titleCell, context)
titleCell
:tag('div')
:css('font-size', '110%')
:wikitext(addNewline(title))
debugLog('render TitleRow End')
end
---上列
local function renderAboveRow(rootTable, context)
local prefix = context.prefix
local above = getArg(prefix, "above")
if not above then return end
debugLog('render AboveRow', {['prefix'] = prefix}, context)
renderSplitRow(rootTable, context)
local Colspan = context.totalColspan
local AboveRow = rootTable:tag('tr')
AboveRow
:tag('td')
:addClass('navbox-abovebelow')
:addClass(getArg(prefix,"aboveclass"))
:cssText(getArg(prefix, "basestyle"))
:cssText(getArg(prefix,"abovestyle"))
:attr('colspan', Colspan)
:tag('div')
:wikitext(addNewline(above))
debugLog('render AboveRow End')
end
---下列
local function renderBelowRow(rootTable, context)
local prefix = context.prefix
local below = getArg(prefix, "below")
if not below then return end
debugLog('render BelowRow', {['prefix'] = prefix}, context)
renderSplitRow(rootTable, context)
local Colspan = context.totalColspan
local BelowRow = rootTable:tag('tr')
BelowRow
:tag('td')
:addClass('navbox-abovebelow')
:addClass(getArg(prefix,"belowclass"))
:cssText(getArg(prefix, "basestyle"))
:cssText(getArg(prefix,"belowstyle"))
:attr('colspan', Colspan)
:tag('div')
:wikitext(addNewline(below))
debugLog('render BelowRow End')
end
---------------------------------------------------------------
-- 数据列的方法生成器
local function _renderColRow_FunctionBuilder(rootTable, context, nodeFunc)
debugLog("_renderColRow_FunctionBuilder builded", {['context'] = context})
return function(listCellDivToWrite, divNotClose)
debugLog(debug.traceback('FunctionInrenderColRow'),
{['context'] = context, ['divNotClose'] = divNotClose})
if not divNotClose then
listCellDivToWrite:done() -- div end
:node(rootTable and
nodeFunc(rootTable, context) or
nodeFunc(context)
)
:tag('div'):done()
else
listCellDivToWrite:node(nodeFunc(rootTable, context))
end
end
end
---数据行,统一的实现
local function _renderListRow(rootTable, context, OtherListFunction)
renderSplitRow(rootTable, context)
local prefix, level = context.prefix, context.level
local listnum = context.listnum or 1
local isFirst, isOdd = (listnum == 1), (listnum % 2) == 1
local ImageRowspan = 2 * context.totalRowspan - 1 + (context['imageCellCompensate'] or 0)
local notNeedImage, notNeedGroup = context.notNeedImage,context.notNeedGroup
debugLog('ValueRow Implement', {
['prefix'] = prefix,
['listnum'] = listnum,
['ImageRowspan'] = ImageRowspan,
['HaveOtherListFunction'] = tostring(not not OtherListFunction),
['notNeedImage'] = notNeedImage,
['notNeedGroup'] = notNeedGroup
}, context)
local listRow = rootTable:tag('tr')
local groupCell, listCell
-- image
local imageLeft, image, insertImage =
getArg(prefix, "imageleft", nil, context),
getArg(prefix, "image", nil, context),
false
-- CollapsibleListRow 适配
if context.notImageLeftCell then imageLeft = nil end
if context.notImageCell then image = nil end
if isFirst and (not notNeedImage) then
if imageLeft then
debugLog('imageLeftRow', {['imageLeft'] = imageLeft})
listRow
:tag('td')
:addClass('navbox-image')
:addClass(getArg(prefix, "imageclass", nil, context))
:css('width', '0%')
:css('padding', '0px 2px 0px 0px')
:cssText(getArg(prefix,"imageleftstyle",nil, context))
:attr('rowspan', ImageRowspan)
:tag('div')
:wikitext(addNewline(imageLeft))
:done() -- div done
:done() -- td done
end
if image then insertImage = true end
end
-- group start
local needGroup,haveGroupWidth = false , false
do
local group, groupwidth, grouppadding, removeGroupPadding =
getArg(prefix,"group" ..listnum,nil,context),
((group and getArg(prefix,"groupwidth")) or nil),
(getArg(prefix,"grouppadding") or '0em 0.75em;'),
(getArg(prefix,'removeGroupPadding', false) and level > 1)
local navboxSubgroupMark =
borderIsChild(getArg(prefix, "border")) and
(getArg(prefix, 'type') == NavType.V) and
(not removeGroupPadding) --针对(列式子组合)T:Navbox subgroup的适配
if group and not notNeedGroup then needGroup = true end
if groupwidth then haveGroupWidth = true end
if needGroup then
debugLog('groupTh', {['group'] = group})
groupCell = listRow
:tag('th')
:attr('scope', 'row')
:addClass('navbox-group')
:addClass(getArg(prefix, "groupclass", nil, context))
:cssText(getArg(prefix, "basestyle"))
:css(((groupwidth and {['width'] = groupwidth}) or {}))
:cssText(navboxSubgroupMark and 'padding-left:0em;padding-right:0em;' or '')
:cssText(getArg(prefix, "groupstyle"))
:cssText(getArg(prefix,'group' ..listnum ..'style'))
local tempEle = groupCell
if navboxSubgroupMark then
groupCell:cssText("padding-left:0em;padding-right:0em;")
tempEle = tempEle:tag("div"):css("padding", grouppadding)
end
tempEle:wikitext(group)
end
end
-- group end
-- list start
do
local listHaveChild = checkHaveChild(prefix, 'list' .. listnum)
local contentHaveChild = context.contentEqList and checkHaveChild(prefix, 'content' .. listnum)
listCell = listRow:tag('td')
if needGroup then
listCell
:css('text-align', 'left')
:css('border-left-width', '2px')
:css('border-left-style', 'solid')
else
listCell:attr('colspan', 2)
end
if not haveGroupWidth then listCell:css('width', '100%') end
local evenOdd = getArg(prefix, "evenodd")
evenOdd = (
evenOdd == 'swap' and
(isOdd and 'even' or 'odd') or
(isOdd and (evenOdd or 'odd') or (evenOdd or 'even'))
)
local evenOddStyle = (isOdd and getArg(prefix, "evenstyle")) or getArg(prefix, "oddstyle")
if context.lockEvenOdd then -- CollapsibleListRow 适配
evenOdd = 'odd'
end
if context.noEvenOddStyle then -- CollapsibleListRow 适配
evenOddStyle = ''
end
local list1padding = (notNeedGroup) and
getArg(prefix, "list1padding", nil, context) or
'0em 0.25em'
local listNpadding = (isFirst and list1padding) or
(getArg(prefix, "listpadding", nil, context) or
'0em 0.25em')
local listNstyle = -- ((not notNeedGroup))
(isFirst and getArg(prefix, 'list1style', '', context)) or
getArg(prefix, 'list' .. listnum .. 'style', '')
local liststyle = getArg(prefix, "liststyle", '', context)
listCell
:css('padding', '0px')
:cssText(liststyle)
:cssText(evenOddStyle)
:cssText(listNstyle)
:addClass('navbox-list')
:addClass('navbox-' ..evenOdd)
:addClass(getArg(prefix, "listclass"))
local tempdiv = listCell:tag('div'):css('padding', listNpadding)
if OtherListFunction then
debugLog('ValueRow OtherListFunction', {
['otherListFunctionDivNotClose'] = context.otherListFunctionDivNotClose
})
OtherListFunction(tempdiv, context.otherListFunctionDivNotClose)
elseif (listHaveChild or contentHaveChild) and level <= Limit.child then
local listKeyName = 'list'
if contentHaveChild then listKeyName = 'content' end
local childPrefix= makePrefix(prefix, listKeyName ..listnum)
local childContext = NavboxContext.new(
childPrefix,
level + 1,
getValidType(getArg(childPrefix,'type'),NavType.V)
)
debugLog('ValueRow NewChild', childContext)
tempdiv
:done() -- div end
:node(p.renderNavTable(childContext))
:tag('div'):done()
else
local list_str = getArg(prefix, 'list' .. listnum, '')
local content_str = getArg(prefix, 'content' .. listnum, '') -- VerticalCollapsibleTable 的 Content适配
if not context.contentEqList then
content_str = ''
end
debugLog('ValueRow listnum', {['listnum'] = listnum})
tempdiv:wikitext(addNewline(table.concat({list_str,content_str},"")))
end
end
-- list end
if insertImage then
debugLog('imageRow', {['image'] = image})
listRow
:tag('td')
:addClass('navbox-image')
:addClass(getArg(prefix,"imageclass",nil, context))
:css('width', '0%')
:css('padding', '0px 0px 0px 2px')
:cssText(getArg(prefix, "imagestyle", nil, context))
:attr('rowspan',ImageRowspan)
:tag('div')
:wikitext(addNewline(image))
end
debugLog('ValueRow Implement End')
end
---数据行,垂直式的具体实现
local function renderListRow(rootTable, context)
debugLog('render ListRow', context)
_renderListRow(rootTable, context)
debugLog('render ListRow End')
end
---------------------------------------------------------------
---数据列,水平式的具体实现 (ColRow)
local function _renderColRow(rootTable, context)
local prefix, level = context.prefix, context.level
local fullwidth = getArg(prefix, "fullwidth")
local col1header, col1, col1footer =
getArg(prefix, 'col1header'),
getArg(prefix, 'col1'),
getArg(prefix, 'col1footer')
debugLog('ColRow Implement', {['prefix'] = prefix}, context)
-- new table root
rootTable = mw.html.create('table')
rootTable
:addClass("navbox-columns-table")
:attr("cellspacing", "0")
:cssText("text-align:left;")
:cssText((col1header or fullwidth) and "width:100%;" or
"width:auto;margin-left:auto;margin-right:auto;")
:cssText(getArg(prefix,"coltablestyle"))
local headerTR, colbodyTR, footerTR = nil, nil, nil
context.needAddSplitRow = false
context.splitRowcolspan = 1
-- header
if col1header then
renderSplitRow(rootTable, context)
debugLog('ColRow Header', {})
headerTR = rootTable:tag('tr')
for colnum = 1, Limit.horizontal.col do
debugLog('ColRow Header', colnum)
local isFirst, isOdd = colnum == 1, (colnum % 2) == 1
local colheaderkey = 'col' .. colnum .. 'header'
local colNheader = isFirst and col1header or getArg(prefix, colheaderkey)
if headerTR and colNheader then
debugLog('ColRow Herder Cell', {['colnum'] = colnum})
local headerNCell = headerTR:tag('td')
headerNCell
:addClass('navbox-abovebelow')
:cssText(isFirst and "" or "border-left:2px solid #fdfdfd;")
:cssText(getArg(prefix, "colheaderstyle"))
:cssText(getArg(prefix,colheaderkey ..'style'))
:attr((colnum ~= Limit.horizontal.col and
{['colspan'] = getArg(prefix, colheaderkey .. 'colspan', 1)}) or
{})
--[[ if checkHaveChild(prefix,colheaderkey) and level<= Limit.child then
local childContext=NavboxContext.new(colheaderkey ,level+1 ,NavType.H,context)
debugLog('ColRow Herder NewChild',childContext)
headerNCell:node(p.renderNavTable(childContext):allDone())
else]]
-- debugLog('ColRow Herder Cell',{['colnum']=colnum})
headerNCell:wikitext(addNewline("'''" .. colNheader .. "'''"))
-- end
end
end
debugLog('ColRow Header End', {['colnum'] = colnum})
end
-- col
local col1havechild = checkHaveChild(prefix, "col1")
if col1 or col1havechild then
renderSplitRow(rootTable, context)
debugLog('ColRow Body', {['col1havechild'] = col1havechild})
colbodyTR = rootTable:tag('tr'):cssText('vertical-align:top;')
if not (col1header or col1footer or fullwidth) then
local padding, test0 = getArg(prefix, "padding"), nil
if padding then
padding = trim(padding)
test0 = mw.ustring.find(padding,'^0[%%%a]?[%a]?[;]?$')
end
if test0 ~= nil or padding == 'off' then
else
colbodyTR
:tag('td')
:css("width", padding or '5em')
:wikitext(' ')
:done()
end
end
for colnum = 1, Limit.horizontal.col do
debugLog('ColRow Body', colnum)
local isFirst, isOdd = colnum == 1, (colnum % 2) == 1
local colkey = 'col' .. colnum
local colN = isFirst and col1 or getArg(prefix, colkey)
local colNhavechild = isFirst and col1havechild or checkHaveChild(prefix, colkey)
if colN or colNhavechild then
local oddevenstyle = getArg(prefix, isOdd and 'oddcolstyle' or'evencolstyle')
local colNCell = colbodyTR
:tag('td')
:css("padding", "0px")
:cssText(((not isFirst) and "border-left:2px solid #fdfdfd;") or '')
:cssText(getArg(prefix, 'colstyle'))
:cssText(oddevenstyle)
:cssText(getArg(prefix, colkey .. 'style'))
:css('width',
(getArg(prefix, colkey .. 'width') or
getArg(prefix, 'colwidth')) or
'10em')
if checkHaveChild(prefix, colkey) and level <= Limit.child then
local childContext =
NavboxContext.new(
makePrefix(prefix , colkey),
level + 1,
getValidType(getArg(prefix, 'type'), NavType.H)
)
debugLog('ColRow Body NewChild', childContext)
colNCell
:tag('div'):done()
:node(p.renderNavTable(childContext):allDone())
:tag('div'):done()
else
debugLog('ColRow Body Cell', {['colnum'] = colnum})
colNCell:tag('div'):wikitext(addNewline('\n'..colN..'\n'))
end
end
debugLog('ColRow Body End', {['colnum'] = colnum})
end
end
-- footer
if col1footer then
renderSplitRow(rootTable, context)
debugLog('ColRow footer', {})
footerTR = rootTable:tag('tr')
for colnum = 1, Limit.horizontal.col do
debugLog('ColRow footer', colnum)
local isFirst, isOdd = colnum == 1, (colnum % 2) == 1
local colfooterkey = 'col' .. colnum .. 'footer'
local colNfooter = isFirst and col1footer or getArg(prefix, colfooterkey)
if colNfooter then
debugLog('ColRow footer Cell', {['colnum'] = colnum})
local footerNCell = footerTR:tag('td')
footerNCell
:addClass('navbox-abovebelow')
:cssText(isFirst and "" or "border-left:2px solid #fdfdfd;")
:cssText(getArg(prefix, "colfooterstyle"))
:cssText(getArg(prefix, colfooterkey ..'style'))
:attr((colnum ~= Limit.horizontal.col and
{['colspan'] = getArg(prefix,colfooterkey .. 'colspan', 1)}) or
{})
--[[ if checkHaveChild(prefix,colfooterkey) and level<= Limit.child then
local childContext=NavboxContext.new(colfooterkey ,level+1 ,NavType.H,context)
debugLog('ColRow footer NewChild',childContext)
footerNCell:node(p.renderNavTable(childContext):allDone())
else]]
-- debugLog('ColRow footer Cell',{['colnum']=colnum})
footerNCell:wikitext(addNewline("'''" .. colNfooter .. "'''"))
-- end
end
end
debugLog('ColRow footer End', {['colnum'] = colnum})
end
debugLog('ColRow Implement End')
return rootTable:allDone()
end
-- 数据列,具体实现
local function renderColRow(rootTable, context)
debugLog('renderColRow', {['context'] = context})
context.notNeedGroup = true
context['list1padding'] = '0px'
context['list1style'] = "background:transparent;color:inherit;"
context['otherListFunctionDivNotClose'] = true
context['imageCellCompensate'] = 2
_renderListRow(
rootTable,
context,
_renderColRow_FunctionBuilder(rootTable,context,_renderColRow)
)
-- clean up
context.notNeedGroup = nil
context['list1padding'] = nil
context['list1style'] = nil
context['otherListFunctionDivNotClose'] = nil
context['imageCellCompensate'] = nil
debugLog('renderColRow End')
end
---------------------------------------------------------------
-- 折叠行式的子Nabox
local function _renderSmallNavboxInCollapsibleListRow(rootTable, context)
local prefix, level = context.prefix, context.level
debugLog('_renderSmallNavboxInCollapsibleListRow',
{['prefix'] = prefix},
{['context'] = context})
local listnum = context.listnum
-- 部分需要压制传入的样式
context.bodyclass = ''
context.titleclass = ''
context.groupclass = ''
context.imageclass = ''
context.bodystyle = ''
context.style = ''
context.basestyle = ''
context.imagestyle = ''
context.imageleftstyle = ''
-- 传入renderNavBar,renderTitleRow
context.navbar = 'plain'
context.border = 'child'
local selected, abbrN, state =
getArg(prefix, 'selected'),
getArg(prefix, 'abbr' .. listnum),
'uncollapsed'
if selected ~= nil and selected == abbrN then
state = 'uncollapsed'
else
state = getArg(prefix, 'state' .. listnum, 'collapsed')
end
context.state = state
-- 传入renderTitleRow
-- context.titleEqGroup=true
context.notNeedTitlegroup = true
context.titlestyle = table.concat({
(getArg(prefix, 'basestyle', '')),
(getArg(prefix, 'groupstyle', '')),
(getArg(prefix, 'secttitlestyle', '')),
(getArg(prefix, 'group' .. listnum .. 'style', '')),
(getArg(prefix, 'sect' .. listnum .. 'titlestyle', ''))
}, ';')
context.title = (getArg(prefix, 'group' .. listnum, '')) ..
(getArg(prefix, 'sect' .. listnum, '')) ..
(getArg(prefix, 'section' .. listnum, ''))
-- 传入renderListRow
context.contentEqList = true
context.notNeedGroup = true
context.liststyle = table.concat({
(getArg(prefix, 'liststyle', '')),
(getArg(prefix, 'contentstyle', '')),
(getArg(prefix, 'list' .. listnum .. 'style', '')),
(getArg(prefix, 'content' .. listnum .. 'style', ''))
}, ';')
local totalColspan = 2 -- title,above,below
local totalRowspan = 1 -- image,imageleft
-- 传入image
local imageLeft, image = getArg(prefix, "imageleft" .. listnum, nil,context, 'imageleft'),
getArg(prefix,"image" ..listnum,nil, context,'image')
if imageLeft then
totalColspan = totalColspan + 1
context.imageleft = imageLeft
else
context.notImageLeftCell = true -- CollapsibleListRow 适配
end
if image then
totalColspan = totalColspan + 1
context.image = image
else
context.notImageCell = true -- CollapsibleListRow 适配
end
context.totalColspan = totalColspan
context.totalRowspan = totalRowspan
context.splitRowcolspan = totalColspan
context.lockEvenOdd = true -- CollapsibleListRow 适配
debugLog(
'SmallNavboxInCollapsibleListRow Implement',
'listnum=' .. listnum,
context)
-- start
local rootTable2 = createNavTableHeader(context)
renderTitleRow(rootTable2, context)
-- only 1 list
local otherListFunction
local listHaveChild = checkHaveChild(prefix, 'list' .. listnum)
local contentHaveChild = context.contentEqList and
checkHaveChild(prefix, 'content' .. listnum)
if (listHaveChild or contentHaveChild) and level <= Limit.child then
local listKeyName = 'list'
if contentHaveChild then listKeyName = 'content' end
local childPrefix = makePrefix(prefix , listKeyName .. listnum)
local childContext = NavboxContext.new(
childPrefix,
level + 1,
getValidType(getArg(childPrefix, 'type'),NavType.V)
)
debugLog('SmallNavboxInCollapsibleListRow NewChild', childContext)
otherListFunction = _renderColRow_FunctionBuilder(
nil,
childContext,
p.renderNavTable)
end
context.noEvenOddStyle = true
_renderListRow(rootTable2, context, otherListFunction)
context.noEvenOddStyle = nil
debugLog('_renderSmallNavboxInCollapsibleListRow End')
return rootTable2:allDone()
end
---折叠行具体实现
local function renderCollapsibleListRow(rootTable, context)
local prefix, level = context.prefix, context.level
debugLog('renderCollapsibleListRow', {
['prefix'] = prefix},
{['context'] = context})
context.notNeedGroup = true
local listnum = context.listnum
local context_function
if getArg(prefix, 'group' .. listnum) or
getArg(prefix, 'sect' .. listnum) or
getArg(prefix, 'section' .. listnum)
then
local grandChild_context = NavboxContext.new(prefix, level)
grandChild_context.notNeedGroup = true
grandChild_context.listpadding = getArg(prefix, 'listpadding')
grandChild_context.listnum = listnum
context_function = _renderColRow_FunctionBuilder(
rootTable,
grandChild_context,
_renderSmallNavboxInCollapsibleListRow)
debugLog('renderCollapsibleListRow function generate', {
['context'] = context,
['grandChild_context'] = grandChild_context
})
end
context.noEvenOddStyle = true
debugLog('renderCollapsibleListRow renderListRow', {['context'] = context})
_renderListRow(rootTable, context, context_function)
context.noEvenOddStyle = nil
debugLog('renderCollapsibleListRow End')
end
---------------------------------------------------------------
--
-- Tracking categories
--
-- 没有使用水平列表的导航框
local function needsHorizontalLists(context)
local prefix = context.prefix
local border, listclass, bodyclass, tracking =
context.border or getArg(prefix, 'border'),
context.listclass or getArg(prefix, 'listclass'),
context.bodyclass or getArg(prefix, 'bodyclass'),
getArg(prefix, 'tracking')
debugLog('needsHorizontalLists',
{['border']=border,['listclass']=listclass,['bodyclass']=bodyclass,['tracking']=tracking})
if borderIsChild(border) or tracking == 'no' then
return false
end
local listClasses = {
'plainlist', 'hlist', 'hlist hnum', 'hlist hwrap',
'hlist vcard', 'vcard hlist', 'hlist vevent', 'hlist hlist-pipe',
'hlist hlist-hyphen'}
for i, cls in ipairs(listClasses) do
if listclass == cls or bodyclass == cls then return false end
end
return true
end
-- 使用背景颜色的导航框
local function hasBackgroundColors(context)
local prefix = context.prefix
local titlestyle, groupstyle, basestyle =
context.titlestyle or getArg(prefix, 'titlestyle'),
context.groupstyle or getArg(prefix, 'groupstyle'),
context.basestyle or getArg(prefix, 'basestyle')
debugLog('hasBackgroundColors',
{['titlestyle']=titlestyle,['groupstyle']=groupstyle,['basestyle']=basestyle})
return
mw.ustring.match(titlestyle or '', 'background') or
mw.ustring.match(groupstyle or '', 'background') or
mw.ustring.match(basestyle or '', 'background')
end
-- name參數和實際不同的導航框
local function argNameAndRealTitleAreDifferent(context)
local prefix = context.prefix
local border, name, tracking, navbar =
getArg(prefix, 'border', nil, context),
getArg(prefix, 'name', nil, context),
getArg(prefix, 'tracking'),
getArg(prefix, 'navbar', nil, context)
debugLog('argNameAndRealTitleAreDifferent',
{['border']=border,['name']=name,['tracking']=tracking,['navbar']=navbar})
if borderIsChild(border) or tracking == 'no' or navbar == 'plain' or navbar == 'off' then
return false
end
if name ~= mw.title.getCurrentTitle().text then return true end
return false
end
local catCheckList = {
['needsHorizontalLists'] = {
['catkey'] = 'needsHorizontalLists',
['catCheckFunc'] = needsHorizontalLists,
['catName'] = '没有使用水平列表的导航框'
},
['hasBackgroundColors'] = {
['catkey'] = 'hasBackgroundColors',
['catCheckFunc'] = hasBackgroundColors,
['catName'] = '使用背景颜色的导航框'
},
['argNameAndRealTitleAreDifferent'] = {
['catkey'] = 'argNameAndRealTitleAreDifferent',
['catCheckFunc'] = argNameAndRealTitleAreDifferent,
['catName'] = 'name參數和實際不同的導航框'
}
}
-- 检查并获得需要的分类
local function getTrackingCategories(context)
local cats = _G['globalCatList'] or {}
for catkey, checkObj in pairs(catCheckList) do
if checkObj['catCheckFunc'](context) then
table.insert(cats, checkObj['catkey'])
end
end
debugLog('getTrackingCategories',{['level']=context.level,['catList']=cats})
_G['globalCatList'] = cats
end
-- 生成分类
local function renderTrackingCategories(builder, context)
local title = mw.title.getCurrentTitle()
if DEBUG == false then
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 --
end
getTrackingCategories(context)
debugLog('renderTrackingCategories',{['level']=context.level})
--[[local catList = {}
local workContext = context
repeat
local workCatList = workContext['catList'] or {}
for _, catKey in ipairs(workCatList) do
table.insert(catList, catKey)
end
debugLog('renderTrackingCategories.1',catList)
catList = removeDump(catList)
if workContext.level == 1 then
debugLog('renderTrackingCategories.2',catList)
workContext['globalCatList']=catList
end
workContext = workContext.parent
until (workContext == NavboxContext.END )]]
if context.level ==1 then
local catList=_G['globalCatList'] or {}
catList = removeDump(catList)
for i, cat in ipairs(catList) do
builder:wikitext('[[Category:' .. catCheckList[cat]['catName'] ..']]')
end
end
end
---------------------------------------------------------------
--
-- SubType Implement
--
---水平式
local function renderHorizontalTable(context)
debugLog('render Horizontal NavTable', context)
local prefix, level = context.prefix, context.level
local rootTable = createNavTableHeader(context)
local listnums = getListnum(prefix, Limit.horizontal.list)
local totalColspan = 2 -- title,above,below
local totalRowspan = #listnums -- image,imageleft
if getArg(prefix, "imageleft", nil, context) then
totalColspan = totalColspan + 1
end
if getArg(prefix, "image", nil, context) then
totalColspan = totalColspan + 1
end
context.totalColspan = totalColspan
context.totalRowspan = totalRowspan
-- context.splitRowcolspan = totalColspan
renderTitleRow(rootTable, context)
renderAboveRow(rootTable, context)
if listnums == nil or #listnums == 0 then -- 没有list的话,只有col
debugLog('render Horizontal NavTable,no list', {listnums})
context.listnum = 1
renderColRow(rootTable, context)
-- context.notNeedImage=true
context.splitRowcolspan = totalColspan
else
debugLog('render Horizontal NavTable,have list with col', {listnums})
for i, listnum in ipairs(listnums) do
context.listnum = listnum
if listnum == 1 then
-- 一行Col
renderColRow(rootTable, context)
context.notNeedImage = true
context.splitRowcolspan = totalColspan
else
context.notNeedImage = nil
end
_renderListRow(rootTable, context)
end
end
renderBelowRow(rootTable, context)
renderTrackingCategories(rootTable, context)
debugLog('render Horizontal NavTable End')
return rootTable
end
---垂直式
local function renderVerticalTable(context)
debugLog('render Vertical NavTable', context)
local prefix, level = context.prefix, context.level
local rootTable = createNavTableHeader(context)
local listnums = getListnum(prefix, Limit.vertical)
local totalColspan = 2 -- title,above,below
local totalRowspan = #listnums -- image,imageleft
if getArg(prefix, "imageleft", nil, context) then
totalColspan = totalColspan + 1
end
if getArg(prefix, "image", nil, context) then
totalColspan = totalColspan + 1
end
context.totalColspan = totalColspan
context.totalRowspan = totalRowspan
-- context.splitRowcolspan = totalColspan
renderTitleRow(rootTable, context)
renderAboveRow(rootTable, context)
for i, listnum in ipairs(listnums) do
context.listnum = listnum
renderListRow(rootTable, context)
end
renderBelowRow(rootTable, context)
renderTrackingCategories(rootTable, context)
debugLog('render Vertical NavTable End')
return rootTable
end
---垂直折叠式
local function renderVerticalCollapsibleTable(context)
debugLog('render VerticalCollapsible NavTable', context)
local prefix, level = context.prefix, context.level
local rootTable = createNavTableHeader(context)
local listnums = getListnum(prefix, Limit.vertical,
( --[[context.contentEqList or ]] true) -- VerticalCollapsibleTable 的 Content适配
)
local totalColspan = 2 -- title,above,below
local totalRowspan = #listnums -- image,imageleft
if getArg(prefix, "imageleft", nil, context) then
totalColspan = totalColspan + 1
end
if getArg(prefix, "image", nil, context) then
totalColspan = totalColspan + 1
end
context.totalColspan = totalColspan
context.totalRowspan = totalRowspan
-- context.splitRowcolspan = totalColspan
renderTitleRow(rootTable, context)
renderAboveRow(rootTable, context)
for i, listnum in ipairs(listnums) do
context.listnum = listnum
renderCollapsibleListRow(rootTable, context)
end
renderBelowRow(rootTable, context)
renderTrackingCategories(rootTable, context)
debugLog('render VerticalCollapsible NavTable End')
return rootTable
end
---Type Selector
function p.renderNavTable(context)
local navtype = context.type
debugLog('render NavTable')
debugLog('Type=' .. navtype)
local result
if navtype == NavType.H then
result = renderHorizontalTable(context)
elseif navtype == NavType.VC then
result = renderVerticalCollapsibleTable(context)
else
result = renderVerticalTable(context)
end
debugLog('render NavTable End')
return result
end
-- Main Funtion
function p._navbox(context)
debugLog('Navbox mainfuntion', context)
local prefix, level = context.prefix, context.level
local rootTable
--[[
适配list内再嵌套单独Navbox的情况,部分Navbox可以单独或者再嵌入使用
原生的Navbox的各种实现机制就是Navbox嵌套
]]
local border = trim(getArg(prefix, 'border') or getArg(prefix, '1') or '')
debugLog("_Navbox.border", border)
if border == 'none' then
rootTable = p.renderNavTable(context):allDone()
elseif borderIsChild(border) then
-- Navbox的值段直接嵌套单独Navbox的情况
rootTable = mw.html.create()
rootTable
:wikitext('</div>')
:node(p.renderNavTable(context):allDone())
:wikitext('<div>')
else
rootTable = mw.html.create('table')
rootTable
:attr('cellspacing', 0)
:addClass('navbox')
:css('border-spacing', 0)
:cssText(getArg(prefix, 'bodystyle'))
:cssText(getArg(prefix, 'style'))
:tag('tr')
:tag('td')
:css('padding', '2px')
:node(p.renderNavTable(context):allDone())
end
debugLog('Navbox mainfuntion End')
return rootTable
end
function p.navbox(frame)
if not getArgs then getArgs = require('Module:Arguments').getArgs end
local modelArgs = getArgs(frame, {frameOnly = true})
DEBUG = (modelArgs['DEBUG']=='true') or DEBUG
MainTemplateName = modelArgs['MainTemplateName'] or MainTemplateName
args = getArgs(frame, {wrappers = MainTemplateName, trim = true})
DEBUG = (args['DEBUG']=='true') or DEBUG
debugLog('Navbox start')
--debugLog('getArgs done,', args)
local prefix, level = "", 1
local navType = getValidType(
getArg(prefix, 'type') or modelArgs['type'], NavType.V)
-- Read the arguments in the order they'll be output in, to make references number in the right order.
p.shakeArgs(prefix, level, navType)
local L0Context = NavboxContext.new(prefix, level, navType)
local rootNode = p._navbox(L0Context)
debugLog('rootnode build done, Navbox end')
return tostring(rootNode:allDone())
end
return p