mNo edit summary |
No edit summary |
||
(5 intermediate revisions by the same user not shown) | |||
Line 345: | Line 345: | ||
end |
end |
||
+ | |||
− | listcell:tag('div') |
+ | local hlistcell = listcell:tag('div') |
:css('padding', listpadding) |
:css('padding', listpadding) |
||
+ | |||
− | + | local data = args['list'..num] |
|
+ | |||
+ | local srchpat = args['stripbegin' .. num] or args.stripbegin |
||
+ | |||
+ | if srchpat and srchpat ~= "" then |
||
+ | srchpat = string.gsub(srchpat, "([%^%$%(%)%.%+%-%?])", "%%%1") |
||
+ | data = string.gsub(data, "%[%[(" .. srchpat .. "%s*)([^%]|]-)%]%]", "[[%1%2|%2]]") |
||
+ | data = string.gsub(data, "%[%[([^%]]-|)(" .. srchpat .. "%s*)([^%]|]-)%]%]", "[[%1%3]]") |
||
+ | end |
||
+ | |||
+ | srchpat = args['stripend' .. num] or args.stripend |
||
+ | |||
+ | if srchpat and srchpat ~= "" then |
||
+ | srchpat = string.gsub(srchpat, "([%^%$%(%)%.%+%-%?])", "%%%1") |
||
+ | data = string.gsub(data, "%[%[([^%]]-|[^%]]-)(%s*" .. srchpat .. ")%]%]", "[[%1]]") |
||
+ | data = string.gsub(data, "%[%[([^%]%|]-)(%s*" .. srchpat .. ")%]%]", "[[%1%2|%1]]") |
||
+ | end |
||
+ | |||
+ | if data:match('^[*:;#]') then |
||
+ | -- Add newlines to support lists properly |
||
+ | hlistcell |
||
+ | :newline() |
||
+ | :wikitext( data ) |
||
+ | :newline() |
||
+ | else |
||
+ | hlistcell:wikitext( data ) |
||
+ | end |
||
local firstRow = false |
local firstRow = false |
Revision as of 00:38, 9 February 2020
Description
This module is the Lua back-end for {{Navbox}}.
Usage
{{#invoke:Navbox|main|<parameter list>}}
For parameter details see Template:Navbox/doc
--------------------------------------------------------------------
--<pre> Navbox Module
--
-- * Fully CSS styled (inline styles possible but not default)
-- * Supports unlimited rows
-- * Supports collapsible groups (just set parameter withcollapsiblegroups)
--
-- By User:Effan_R from disneymagickingdomswiki.fandom.com
-- Adapted from Navbox Module by User:Tjcool007 from layton.wikia.com
--------------------------------------------------------------------
local p = {}
local args = {} -- Arguments passed to template
local navbox -- Actual navbox
local rownums = {}
local hasrows, alt, altg, isChild = false, false, false, false
local cimage, cimageleft
local colspan, rowspan
local spacer = false
------------------------------------------------
-- Title
------------------------------------------------
--- Processes the VDE links in the title
--
-- @param titlecell The table cell of the title
local function processVde( titlecell )
if not args.name then return end
titlecell:wikitext(mw.getCurrentFrame():expandTemplate({
title = 'Navbar',
args = { args.name,
['fontstyle'] = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';border:none;',
['mini'] = 1
}
}))
end
--- Processes the main title row
local function processTitle()
-- Nothing to do if no title --
if not args.title then return end
local titleRow = navbox:tag('tr')
if args.titlegroup then
titleRow:tag('td')
:addClass('navbox-group')
:wikitext(args.titlegroup)
if args.titlegroupstyle then titlerow:cssText(args.titlegroupstyle) end
end
local titleCell = titleRow:tag('th')
if args.titlegroup then
titleCell:css('border-left', '2px solid #fdfdfd')
:css('width', '100%')
end
titleCell:addClass('navbox-title')
:attr('colspan', colspan)
if args.basestyle then titleCell:cssText(args.basestyle) end
if args.titlestyle then titleCell:cssText(args.titlestyle) end
local titlebar = titleCell:tag('div')
titlebar:css('width', '6em')
if not args.name and isChild or args.navbar == 'plain' or args.navbar == 'off' then
if args.navbar == 'off' then
if args.state == 'plain' then
titlebar:css('float', 'right')
:wikitext(' ')
end
else
if args.state ~= 'plain' then
titlebar:css('float', 'left')
:css('text-align', 'left')
:wikitext(' ')
end
end
else
titlebar:css('float', 'left')
:css('text-align', 'left')
processVde(titlebar)
end
titleCell
:tag('span')
:addClass(args.titleclass)
:css('font-size', (isChild and '100%' or '110%'))
:wikitext(args.title)
spacer = true
end
--- Processes the group title row
local function processGroupTitle(parent, num)
-- Nothing to do if no group # --
if not args['group' .. num] then return end
local titleRow = parent:tag('tr')
local titleCell = titleRow:tag('th')
titleCell:addClass('navbox-title')
:attr('colspan', colspan)
if args.basestyle then titleCell:cssText(args.basestyle) end
if args.groupstyle then titleCell:cssText(args.groupstyle) end
if args['group' .. num .. 'style'] then
titleCell:cssText(args['group' .. num .. 'style'])
end
local titlebar = titleCell:tag('div')
titlebar:css('width', '6em')
:css('float', 'left')
:css('text-align', 'left')
:wikitext(' ')
titleCell
:tag('span')
:css('font-size', '100%')
:wikitext(args['group' .. num])
spacer = true
end
------------------------------------------------
-- Gutter
------------------------------------------------
--- Add gutter between rows
--
-- @param parent node, inRowspan to increment image rowspan
local function _addGutter( parent, incRowspan )
if spacer then
local gutterCell = parent:tag('tr'):css('height', '2px')
gutterCell:tag('td')
end
if incRowspan then
rowspan = rowspan + 1
end
spacer = false
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')
local abcell = mw.html.create('td')
abcell:addClass('navbox-abovebelow')
:attr('colspan', colspan)
if args[rowtype .. 'class'] then abcell:addClass(args[rowtype .. 'class']) end
if args.basestyle then abcell:cssText(args.basestyle) end
if args[rowtype .. 'style'] then abcell:cssText(args[rowtype .. 'style']) end
abcell:tag('div')
:wikitext(args[rowtype])
abrow:node(abcell)
_addGutter( navbox )
navbox:node( abrow )
spacer = true
end
------------------------------------------------
-- Main Rows
------------------------------------------------
--- Processes the images
local function _processImage(row, imgtype)
if not args[imgtype] then return end
local imagecell = row:tag('td')
:addClass('navbox-image')
imagecell:css('width', '0%')
:css('padding', '0px 0px 0px 2px')
if args.imageclass then imagecell:addClass(args.imageclass) end
if args.imagestyle then imagecell:cssText(args.imagestyle) end
local imagediv = imagecell:tag('div')
:wikitext(args[imgtype])
if imgtype == 'image' then
cimage = imagecell
else
cimageleft = imagecell
end
end
--- Handles Odd Even Groups
--
-- @return Alternatingly returns true (odd) or false (even). Returns fixed value of
-- true (odd) or false (even) if specified by args.evenodd
local function _evenoddGroup()
if args.evenodd == 'even' then return false end
if args.evenodd == 'odd' then return true end
altg = not altg
return altg
end
--- Handles Odd Even rows
--
-- @return Alternatingly returns true (odd) or false (even). Returns fixed value of
-- true (odd) or false (even) if specified by args.evenodd
local function _evenoddRow()
if args.evenodd == 'even' then return false end
if args.evenodd == 'odd' then return true end
alt = not alt
return alt
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')
local listrow = row
if not hasrows then
_processImage(row, 'imageleft')
end
local listpadding = args['list' .. num .. 'padding'] or args.listpadding or '0em 0.25em'
if args['group'..num] then
if args.withcollapsiblegroups then
-- convert Group to collapsible title row --
_addGutter(navbox)
local altGroup = _evenoddGroup()
local headercell = row:tag('td')
:addClass('navbox-list')
:attr('colspan', 2)
:css('padding', '0px')
if altGroup then
headercell:addClass('navbox-odd')
if args.oddstyle then headercell:cssText(args.oddstyle) end
else
headercell:addClass('navbox-even')
if args.evenstyle then headercell:cssText(args.evenstyle) end
end
if args.listclass then headercell:addClass(args.listclass) end
if args.liststyle then headercell:cssText(args.liststyle) end
if args['list' .. num .. 'style'] then headercell:cssText(args['list' .. num .. 'style']) end
if not args.groupwidth then headercell:css('width', '100%') end
headercell:tag('div')
:css('padding', listpadding)
local headertable = headercell:tag('table')
headertable:addClass('navbox-subgroup')
if args.bodystyle then headertable:cssText(args.bodystyle) end
if args.style then headertable:cssText(args.style) end
headertable:addClass('nowraplinks')
:addClass('mw-collapsible')
:attr('cellspacing', '0')
:attr('data-expandtext', 'show')
:attr('data-collapsetext', 'hide')
:css('border-spacing', 0)
if args.bodyclass then headertable:addClass(args.bodyclass) end
if args.innerstyle then headertable:cssText(args.innerstyle) end
if args.selected ~= args['abbr' .. num] then
if args['state' .. num] then
headertable:addClass(args['state' .. num])
else
headertable:addClass('mw-collapsed')
end
end
processGroupTitle(headertable, num)
_addGutter(headertable)
alt = (args.evenodd == 'swap')
listrow = headertable:tag('tr')
else
local groupcell = row:tag('th')
:addClass('navbox-group')
:attr('scope','row')
:wikitext( args['group'..num] )
if args.groupclass then groupcell:addClass( args.groupclass ) end
if args.groupstyle then groupcell:cssText( args.groupstyle ) end
if args.basestyle then groupcell:cssText( args.basestyle ) end
if args['group' .. num .. 'style'] then groupcell:cssText(args['group' .. num .. 'style']) end
if args.groupwidth then groupcell:css('width', args.groupwidth) end
end
end
local altRow = _evenoddRow()
local listcell = listrow:tag('td')
:addClass('navbox-list')
:css('padding', '0px')
if altRow then
listcell:addClass('navbox-odd')
if args.oddstyle then listcell:cssText(args.oddstyle) end
else
listcell:addClass('navbox-even')
if args.evenstyle then listcell:cssText(args.evenstyle) end
end
if not args.withcollapsiblegroups and args.listclass then listcell:addClass(args.listclass) end
if args.liststyle then listcell:cssText(args.liststyle) end
if args['list' .. num .. 'style'] then listcell:cssText(args['list' .. num .. 'style']) end
if not args.groupwidth then listcell:css('width', '100%') end
if not args.withcollapsiblegroups and args['group'..num] then
listcell:css('text-align', 'left')
:css('border-left-width', '2px')
:css('border-left-style', 'solid')
else
listcell:attr('colspan',2)
end
local hlistcell = listcell:tag('div')
:css('padding', listpadding)
local data = args['list'..num]
local srchpat = args['stripbegin' .. num] or args.stripbegin
if srchpat and srchpat ~= "" then
srchpat = string.gsub(srchpat, "([%^%$%(%)%.%+%-%?])", "%%%1")
data = string.gsub(data, "%[%[(" .. srchpat .. "%s*)([^%]|]-)%]%]", "[[%1%2|%2]]")
data = string.gsub(data, "%[%[([^%]]-|)(" .. srchpat .. "%s*)([^%]|]-)%]%]", "[[%1%3]]")
end
srchpat = args['stripend' .. num] or args.stripend
if srchpat and srchpat ~= "" then
srchpat = string.gsub(srchpat, "([%^%$%(%)%.%+%-%?])", "%%%1")
data = string.gsub(data, "%[%[([^%]]-|[^%]]-)(%s*" .. srchpat .. ")%]%]", "[[%1]]")
data = string.gsub(data, "%[%[([^%]%|]-)(%s*" .. srchpat .. ")%]%]", "[[%1%2|%1]]")
end
if data:match('^[*:;#]') then
-- Add newlines to support lists properly
hlistcell
:newline()
:wikitext( data )
:newline()
else
hlistcell:wikitext( data )
end
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
spacer = true
end
--- Processes all rows
local function processRows()
for i=1,#rownums do
processList(rownums[i])
end
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 == '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
if args.titlegroup then colspan = colspan - 1 end
rowspan = 0
alt = (args.evenodd == 'swap')
altg = alt
for k, v in pairs(nums) do
rownums[#rownums+1] = tonumber(k)
end
table.sort(rownums)
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' or border == 'none')
if isChild then
navbox = mw.html.create('table')
navbox:addClass('navbox-subgroup')
if args.bodystyle then navbox:cssText(args.bodystyle) end
if args.style then navbox:cssText(args.style) end
else
navbox = mw.html.create('table')
navbox:addClass('navbox-inner')
:css('background', 'transparent')
:css('color', 'inherit')
end
navbox:addClass('nowraplinks')
:addClass(args.bodyclass)
:attr('cellspacing', '0')
:attr('data-expandtext', 'show')
:attr('data-collapsetext', 'hide')
:css('border-spacing', 0)
:cssText(args.innerstyle)
if args.title then
if args.state ~= 'plain' and args.stat ~= 'off' then
navbox:addClass('mw-collapsible')
if args.state then navbox:addClass(args.state) end
end
end
-- Process...
spacer = false
processTitle()
processAboveBelow('above')
processRows()
processAboveBelow('below')
-- Wrapper Table --
if not isChild then
local wrapper = mw.html.create('table')
wrapper:addClass('navbox')
:attr('cellspacing', '0')
:css('border-spacing', 0)
if args.bodystyle then wrapper:cssText(args.bodystyle) end
if args.style then wrapper:cssText(args.style) end
local wrapperrow = wrapper:tag('tr')
wrapperrow:tag('td')
:css('padding', '2px')
:node(navbox)
return tostring(wrapper)
else
local wrapper = mw.html.create('')
wrapper:wikitext('</div>')
wrapper:node(navbox)
wrapper:wikitext('<div>')
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