Module:Navbox: Difference between revisions
From Zoophilia Wiki
Jump to navigationJump to search
meta>Toohool fix for lists in image and imageleft |
meta>Toohool rewrite with htmlbuilder |
||
Line 2: | Line 2: | ||
-- This module will implement {{Navbox}} | -- This module will implement {{Navbox}} | ||
-- | -- | ||
local p = {} | local p = {} | ||
local HtmlBuilder = require('Module:Sandbox/Toohool/HtmlBuilder') | |||
local | local args | ||
local tableRowAdded = false | |||
local border | local border | ||
local listnums = {} | local listnums = {} | ||
function trim(s) | function trim(s) | ||
return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1")) | return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1")) | ||
end | |||
function addTableRow(tbl) | |||
-- If any other rows have already been added, then we add a 2px gutter row. | |||
if tableRowAdded then | |||
tbl | |||
.tag('tr') | |||
.css('height', '2px') | |||
.tag('td') | |||
end | |||
tableRowAdded = true | |||
return tbl.tag('tr') | |||
end | end | ||
function renderTitleRow( | |||
-- | |||
-- Title row | |||
-- | |||
function renderTitleRow(tbl) | |||
if not args.title then return end | if not args.title then return end | ||
local titleRow = addTableRow(tbl) | |||
if args.titlegroup then | |||
titleRow | |||
.tag('th') | |||
.attr('scope', 'row') | |||
.addClass('navbox-group') | |||
.addClass(args.titlegroupclass) | |||
.cssText(args.basestyle) | |||
.cssText(args.groupstyle) | |||
.cssText(args.titlegroupstyle) | |||
.wikitext(args.titlegroup) | |||
end | |||
local titleCell = titleRow.tag('th').attr('scope', 'col') | |||
if args.titlegroup then | if args.titlegroup then | ||
titleCell | |||
.css('border-left', '2px solid #fdfdfd') | |||
.css('width', '100%') | |||
end | end | ||
local | |||
if args.imageleft then | local titleColspan = 2 | ||
if args.image then | if args.imageleft then titleColspan = titleColspan + 1 end | ||
if args.titlegroup then | if args.image then titleColspan = titleColspan + 1 end | ||
if args.titlegroup then titleColspan = titleColspan - 1 end | |||
titleCell | |||
.cssText(args.basestyle) | |||
.cssText(args.titlestyle) | |||
.addClass('navbox-title') | |||
.attr('colspan', titleColspan) | |||
renderNavBar(titleCell) | |||
titleCell | |||
.tag('div') | |||
.addClass(args.titleclass) | |||
.css('font-size', '110%') | |||
.newline() | |||
.wikitext(args.title) | |||
end | |||
function renderNavBar(titleCell) | |||
local addStateLinkPlaceholder = false | |||
if args.navbar == 'plain' or args.navbar == 'off' or (not args.name and (border == 'subgroup' or border == 'child' or border == 'none')) then | if args.navbar == 'plain' or args.navbar == 'off' or (not args.name and (border == 'subgroup' or border == 'child' or border == 'none')) then | ||
if args.navbar == 'off' then | if args.navbar == 'off' then | ||
addStateLinkPlaceholder = (args.state == 'plain') | |||
else | else | ||
addStateLinkPlaceholder = (args.state ~= 'plain') | |||
end | end | ||
else | else | ||
if args.name then | if args.name then | ||
titleCell.wikitext(mw.getCurrentFrame():expandTemplate{ title = 'navbar', args = { | |||
args.name, | args.name, | ||
mini = 1, | mini = 1, | ||
Line 53: | Line 96: | ||
}}) | }}) | ||
else | else | ||
titleCell | |||
.tag('span') | |||
.addClass('error') | |||
.css('float', 'left') | |||
.css('white-space', 'nowrap') | |||
.wikitext('Error: No name provided') | |||
addStateLinkPlaceholder = (args.state == 'plain') | |||
end | end | ||
end | end | ||
if addStateLinkPlaceholder then | |||
titleCell | |||
.tag('span') | |||
.css('float', 'right') | |||
.css('width', '6em') | |||
.wikitext(' ') | |||
end | |||
end | |||
function renderAboveRow( | -- | ||
-- Above/Below rows | |||
-- | |||
function renderAboveRow(tbl) | |||
if not args.above then return end | if not args.above then return end | ||
addTableRow(tbl) | |||
.tag('td') | |||
.addClass('navbox-abovebelow') | |||
.addClass(args.aboveclass) | |||
.cssText(args.basestyle) | |||
.cssText(args.abovestyle) | |||
.attr('colspan', getAboveBelowColspan()) | |||
.tag('div') | |||
.newline() | |||
.wikitext(args.above) | |||
end | end | ||
function renderBelowRow( | |||
function renderBelowRow(tbl) | |||
if not args.below then return end | |||
addTableRow(tbl) | |||
.tag('td') | |||
.addClass('navbox-abovebelow') | |||
.addClass(args.belowclass) | |||
.cssText(args.basestyle) | |||
.cssText(args.belowstyle) | |||
.attr('colspan', getAboveBelowColspan()) | |||
.tag('div') | |||
.newline() | |||
.wikitext(args.below) | |||
end | end | ||
function getAboveBelowColspan( | |||
function getAboveBelowColspan() | |||
local ret = 2 | local ret = 2 | ||
if args.imageleft then ret = ret + 1 end | if args.imageleft then ret = ret + 1 end | ||
Line 83: | Line 155: | ||
return ret | return ret | ||
end | end | ||
function renderFirstListRow( | |||
-- | |||
-- List rows | |||
-- | |||
function renderFirstListRow(tbl) | |||
if not args.list1 then return end | if not args.list1 then return end | ||
local row = addTableRow(tbl) | |||
if args.imageleft then | if args.imageleft then | ||
row | |||
.tag('td') | |||
.addClass('navbox-image') | |||
.addClass(args.imageclass) | |||
.css('width', '0%') | |||
.css('padding', '0px 2px 0px 0px') | |||
.cssText(args.imageleftstyle) | |||
.attr('rowspan', 2 * #listnums - 1) | |||
.tag('div') | |||
.newline() | |||
.wikitext(args.imageleft) | |||
end | end | ||
if args.group1 then | |||
local groupCell = row.tag('th') | |||
groupCell | |||
.attr('scope', 'row') | |||
.addClass('navbox-group') | |||
.addClass(args.groupclass) | |||
.cssText(args.basestyle) | |||
if args.groupwidth then | |||
groupCell.css('width', args.groupwidth) | |||
end | |||
groupCell | |||
.cssText(args.groupstyle) | |||
.cssText(args.group1style) | |||
.wikitext(args.group1) | |||
end | |||
local listCell = row.tag('td') | |||
if args.group1 then | if args.group1 then | ||
listCell | |||
.css('text-align', 'left') | |||
.css('border-left-width', '2px') | |||
.css('border-left-style', 'solid') | |||
else | else | ||
listCell.attr('colspan', 2) | |||
end | end | ||
if not args.groupwidth then | |||
if not args.groupwidth then | |||
listCell.css('width', '100%') | |||
end | end | ||
local evenOdd = args.evenodd or 'odd' | |||
if args.evenodd == 'swap' then evenOdd = 'even' end | |||
listCell | |||
.css('padding', '0px') | |||
.cssText(args.liststyle) | |||
.cssText(args.oddstyle) | |||
.cssText(args.list1style) | |||
.addClass('navbox-list') | |||
.addClass('navbox-' .. evenOdd) | |||
.addClass(args.listclass) | |||
.tag('div') | |||
.css('padding', args.list1padding or args.listpadding or '0em 0.25em') | |||
.newline() | |||
.wikitext(args.list1) | |||
if args.image then | if args.image then | ||
row | |||
.tag('td') | |||
.addClass('navbox-image') | |||
.addClass(args.imageclass) | |||
.css('width', '0%') | |||
.css('padding', '0px 0px 0px 2px') | |||
.cssText(args.imagestyle) | |||
.attr('rowspan', 2 * #listnums - 1) | |||
.tag('div') | |||
.newline() | |||
.wikitext(args.image) | |||
end | |||
end | |||
function renderNthListRow(tbl, listnum) | |||
local row = addTableRow(tbl) | |||
if args['group' .. listnum] then | |||
local groupCell = row.tag('th') | |||
groupCell | |||
.attr('scope', 'row') | |||
.addClass('navbox-group') | |||
.addClass(args.groupclass) | |||
.cssText(args.basestyle) | |||
if args.groupwidth then | |||
groupCell.css('width', args.groupwidth) | |||
end | |||
groupCell | |||
.cssText(args.groupstyle) | |||
.cssText(args['group' .. listnum .. 'style']) | |||
.wikitext(args['group' .. listnum]) | |||
end | end | ||
local listCell = row.tag('td') | |||
if args['group' .. listnum] then | if args['group' .. listnum] then | ||
listCell | |||
.css('text-align', 'left') | |||
.css('border-left-width', '2px') | |||
.css('border-left-style', 'solid') | |||
else | else | ||
listCell.attr('colspan', 2) | |||
end | |||
if not args.groupwidth then | |||
listCell.css('width', '100%') | |||
end | end | ||
local isOdd = (listnum % 2) == 1 | local isOdd = (listnum % 2) == 1 | ||
local rowstyle = args.evenstyle | local rowstyle = args.evenstyle | ||
if isOdd then rowstyle = args.oddstyle end | if isOdd then rowstyle = args.oddstyle end | ||
local evenOdd | |||
if args.evenodd == 'swap' then | |||
if isOdd then evenOdd = 'even' else evenOdd = 'odd' end | |||
else | |||
if isOdd then evenOdd = args.evenodd or 'odd' else evenOdd = args.evenodd or 'even' end | |||
end | |||
listCell | |||
.css('padding', '0px') | |||
.cssText(args.liststyle) | |||
.cssText(rowstyle) | |||
.cssText(args['list' .. listnum .. 'style']) | |||
.addClass('navbox-list') | |||
.addClass('navbox-' .. evenOdd) | |||
.addClass(args.listclass) | |||
.tag('div') | |||
.css('padding', args.listpadding or '0em 0.25em') | |||
.newline() | |||
.wikitext(args['list' .. listnum]) | |||
end | end | ||
function | |||
-- | |||
-- Main navbox tables | |||
-- | |||
function renderMainTable() | |||
local tbl = HtmlBuilder.create('table') | |||
.attr('cellspacing', 0) | |||
.addClass('nowraplinks') | |||
.addClass(args.bodyclass) | |||
if args.title and (args.state ~= 'plain' and args.state ~= 'off') then | if args.title and (args.state ~= 'plain' and args.state ~= 'off') then | ||
tbl | |||
.addClass('collapsible') | |||
.addClass(args.state or 'autocollapse') | |||
end | end | ||
tbl.css('border-spacing', 0) | |||
if border == 'subgroup' or border == 'child' or border == 'none' then | if border == 'subgroup' or border == 'child' or border == 'none' then | ||
tbl | |||
else | .addClass('navbox-subgroup') | ||
.cssText(args.bodyStyle) | |||
.cssText(args.style) | |||
else -- regular navobx - 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) | |||
renderTitleRow( | renderTitleRow(tbl) | ||
renderAboveRow( | renderAboveRow(tbl) | ||
renderFirstListRow( | renderFirstListRow(tbl) | ||
-- render lists 2 through N | -- render lists 2 through N | ||
for i, listnum in ipairs(listnums) do | for i, listnum in ipairs(listnums) do | ||
if listnum > 1 then | if listnum > 1 then | ||
renderNthListRow( | renderNthListRow(tbl, listnum) | ||
end | end | ||
end | end | ||
renderBelowRow(tbl) | |||
return tbl | |||
end | |||
function p._navbox(navboxArgs) | |||
args = navboxArgs | |||
for k, v in pairs(args) do | |||
local listnum = ('' .. k):match('^list(%d+)$') | |||
if listnum then table.insert(listnums, tonumber(listnum)) end | |||
end | |||
table.sort(listnums) | |||
border = trim(args.border or args[1] or '') | |||
-- render the main body of the navbox | |||
local tbl = renderMainTable() | |||
-- render the appropriate wrapper around the navbox, depending on the border param | |||
local res = HtmlBuilder.create() | |||
if border == 'subgroup' or border == 'child' then | if border == 'subgroup' or border == 'child' then | ||
res | |||
.tag('/div', {unclosed = true}) | |||
.done() | |||
.node(tbl) | |||
.tag('div', {unclosed = true}) | |||
elseif border ~= 'none' then | elseif border ~= 'none' then | ||
res | |||
.tag('table') | |||
.attr('cellspacing', 0) | |||
.addClass('navbox') | |||
.css('border-spacing', 0) | |||
.cssText(args.bodystyle) | |||
.cssText(args.style) | |||
.tag('tr') | |||
.tag('td') | |||
.css('padding', '2px') | |||
.node(tbl) | |||
end | end | ||
-- TODO: add tracking categories | -- TODO: add tracking categories | ||
return | return tostring(res) | ||
end | end | ||
function p.navbox(frame) | function p.navbox(frame) | ||
return p._navbox(frame:getParent().args) | return p._navbox(frame:getParent().args) | ||
end | end | ||
return p | return p |
Revision as of 04:36, 1 March 2013
This Lua module is used on approximately 4,150,000 pages, or roughly 61747% of all pages. To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them. |
This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
This module depends on the following other modules: |
Related pages |
---|
This module implements the {{Navbox}} template. Please see the template page for usage instructions.
Tracking/maintenance categories
- Category:Navigational boxes without horizontal lists (1)
- Category:Navboxes using background colours (18)
- Category:Potentially illegible navboxes (0)
- Category:Navboxes using borders (0)
--
-- This module will implement {{Navbox}}
--
local p = {}
local HtmlBuilder = require('Module:Sandbox/Toohool/HtmlBuilder')
local args
local tableRowAdded = false
local border
local listnums = {}
function trim(s)
return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))
end
function addTableRow(tbl)
-- If any other rows have already been added, then we add a 2px gutter row.
if tableRowAdded then
tbl
.tag('tr')
.css('height', '2px')
.tag('td')
end
tableRowAdded = true
return tbl.tag('tr')
end
--
-- Title row
--
function renderTitleRow(tbl)
if not args.title then return end
local titleRow = addTableRow(tbl)
if args.titlegroup then
titleRow
.tag('th')
.attr('scope', 'row')
.addClass('navbox-group')
.addClass(args.titlegroupclass)
.cssText(args.basestyle)
.cssText(args.groupstyle)
.cssText(args.titlegroupstyle)
.wikitext(args.titlegroup)
end
local titleCell = titleRow.tag('th').attr('scope', 'col')
if args.titlegroup then
titleCell
.css('border-left', '2px solid #fdfdfd')
.css('width', '100%')
end
local titleColspan = 2
if args.imageleft then titleColspan = titleColspan + 1 end
if args.image then titleColspan = titleColspan + 1 end
if args.titlegroup then titleColspan = titleColspan - 1 end
titleCell
.cssText(args.basestyle)
.cssText(args.titlestyle)
.addClass('navbox-title')
.attr('colspan', titleColspan)
renderNavBar(titleCell)
titleCell
.tag('div')
.addClass(args.titleclass)
.css('font-size', '110%')
.newline()
.wikitext(args.title)
end
function renderNavBar(titleCell)
local addStateLinkPlaceholder = false
if args.navbar == 'plain' or args.navbar == 'off' or (not args.name and (border == 'subgroup' or border == 'child' or border == 'none')) then
if args.navbar == 'off' then
addStateLinkPlaceholder = (args.state == 'plain')
else
addStateLinkPlaceholder = (args.state ~= 'plain')
end
else
if args.name then
titleCell.wikitext(mw.getCurrentFrame():expandTemplate{ title = 'navbar', args = {
args.name,
mini = 1,
fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';background:none transparent;border:none;'
}})
else
titleCell
.tag('span')
.addClass('error')
.css('float', 'left')
.css('white-space', 'nowrap')
.wikitext('Error: No name provided')
addStateLinkPlaceholder = (args.state == 'plain')
end
end
if addStateLinkPlaceholder then
titleCell
.tag('span')
.css('float', 'right')
.css('width', '6em')
.wikitext(' ')
end
end
--
-- Above/Below rows
--
function renderAboveRow(tbl)
if not args.above then return end
addTableRow(tbl)
.tag('td')
.addClass('navbox-abovebelow')
.addClass(args.aboveclass)
.cssText(args.basestyle)
.cssText(args.abovestyle)
.attr('colspan', getAboveBelowColspan())
.tag('div')
.newline()
.wikitext(args.above)
end
function renderBelowRow(tbl)
if not args.below then return end
addTableRow(tbl)
.tag('td')
.addClass('navbox-abovebelow')
.addClass(args.belowclass)
.cssText(args.basestyle)
.cssText(args.belowstyle)
.attr('colspan', getAboveBelowColspan())
.tag('div')
.newline()
.wikitext(args.below)
end
function getAboveBelowColspan()
local ret = 2
if args.imageleft then ret = ret + 1 end
if args.image then ret = ret + 1 end
return ret
end
--
-- List rows
--
function renderFirstListRow(tbl)
if not args.list1 then return end
local row = addTableRow(tbl)
if args.imageleft then
row
.tag('td')
.addClass('navbox-image')
.addClass(args.imageclass)
.css('width', '0%')
.css('padding', '0px 2px 0px 0px')
.cssText(args.imageleftstyle)
.attr('rowspan', 2 * #listnums - 1)
.tag('div')
.newline()
.wikitext(args.imageleft)
end
if args.group1 then
local groupCell = row.tag('th')
groupCell
.attr('scope', 'row')
.addClass('navbox-group')
.addClass(args.groupclass)
.cssText(args.basestyle)
if args.groupwidth then
groupCell.css('width', args.groupwidth)
end
groupCell
.cssText(args.groupstyle)
.cssText(args.group1style)
.wikitext(args.group1)
end
local listCell = row.tag('td')
if args.group1 then
listCell
.css('text-align', 'left')
.css('border-left-width', '2px')
.css('border-left-style', 'solid')
else
listCell.attr('colspan', 2)
end
if not args.groupwidth then
listCell.css('width', '100%')
end
local evenOdd = args.evenodd or 'odd'
if args.evenodd == 'swap' then evenOdd = 'even' end
listCell
.css('padding', '0px')
.cssText(args.liststyle)
.cssText(args.oddstyle)
.cssText(args.list1style)
.addClass('navbox-list')
.addClass('navbox-' .. evenOdd)
.addClass(args.listclass)
.tag('div')
.css('padding', args.list1padding or args.listpadding or '0em 0.25em')
.newline()
.wikitext(args.list1)
if args.image then
row
.tag('td')
.addClass('navbox-image')
.addClass(args.imageclass)
.css('width', '0%')
.css('padding', '0px 0px 0px 2px')
.cssText(args.imagestyle)
.attr('rowspan', 2 * #listnums - 1)
.tag('div')
.newline()
.wikitext(args.image)
end
end
function renderNthListRow(tbl, listnum)
local row = addTableRow(tbl)
if args['group' .. listnum] then
local groupCell = row.tag('th')
groupCell
.attr('scope', 'row')
.addClass('navbox-group')
.addClass(args.groupclass)
.cssText(args.basestyle)
if args.groupwidth then
groupCell.css('width', args.groupwidth)
end
groupCell
.cssText(args.groupstyle)
.cssText(args['group' .. listnum .. 'style'])
.wikitext(args['group' .. listnum])
end
local listCell = row.tag('td')
if args['group' .. listnum] then
listCell
.css('text-align', 'left')
.css('border-left-width', '2px')
.css('border-left-style', 'solid')
else
listCell.attr('colspan', 2)
end
if not args.groupwidth then
listCell.css('width', '100%')
end
local isOdd = (listnum % 2) == 1
local rowstyle = args.evenstyle
if isOdd then rowstyle = args.oddstyle end
local evenOdd
if args.evenodd == 'swap' then
if isOdd then evenOdd = 'even' else evenOdd = 'odd' end
else
if isOdd then evenOdd = args.evenodd or 'odd' else evenOdd = args.evenodd or 'even' end
end
listCell
.css('padding', '0px')
.cssText(args.liststyle)
.cssText(rowstyle)
.cssText(args['list' .. listnum .. 'style'])
.addClass('navbox-list')
.addClass('navbox-' .. evenOdd)
.addClass(args.listclass)
.tag('div')
.css('padding', args.listpadding or '0em 0.25em')
.newline()
.wikitext(args['list' .. listnum])
end
--
-- Main navbox tables
--
function renderMainTable()
local tbl = HtmlBuilder.create('table')
.attr('cellspacing', 0)
.addClass('nowraplinks')
.addClass(args.bodyclass)
if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
tbl
.addClass('collapsible')
.addClass(args.state or 'autocollapse')
end
tbl.css('border-spacing', 0)
if border == 'subgroup' or border == 'child' or border == 'none' then
tbl
.addClass('navbox-subgroup')
.cssText(args.bodyStyle)
.cssText(args.style)
else -- regular navobx - bodyStyle and style will be applied to the wrapper table
tbl
.addClass('navbox-inner')
.css('background', 'transparent')
.css('color', 'inherit')
end
tbl.cssText(args.innerstyle)
renderTitleRow(tbl)
renderAboveRow(tbl)
renderFirstListRow(tbl)
-- render lists 2 through N
for i, listnum in ipairs(listnums) do
if listnum > 1 then
renderNthListRow(tbl, listnum)
end
end
renderBelowRow(tbl)
return tbl
end
function p._navbox(navboxArgs)
args = navboxArgs
for k, v in pairs(args) do
local listnum = ('' .. k):match('^list(%d+)$')
if listnum then table.insert(listnums, tonumber(listnum)) end
end
table.sort(listnums)
border = trim(args.border or args[1] or '')
-- render the main body of the navbox
local tbl = renderMainTable()
-- render the appropriate wrapper around the navbox, depending on the border param
local res = HtmlBuilder.create()
if border == 'subgroup' or border == 'child' then
res
.tag('/div', {unclosed = true})
.done()
.node(tbl)
.tag('div', {unclosed = true})
elseif border ~= 'none' then
res
.tag('table')
.attr('cellspacing', 0)
.addClass('navbox')
.css('border-spacing', 0)
.cssText(args.bodystyle)
.cssText(args.style)
.tag('tr')
.tag('td')
.css('padding', '2px')
.node(tbl)
end
-- TODO: add tracking categories
return tostring(res)
end
function p.navbox(frame)
return p._navbox(frame:getParent().args)
end
return p