Module:Navbox

-- <nowiki>
--
-- Implements 
--
local p = {}
local tnavbar = require( 'Module:Tnavbar' )
local yesno = require( 'Module:Yesno' )
--
-- Helper for inserting a new row into the navbox
--
local function insertRow( tbl )
 return tbl
 :tag( 'tr' )
end
--
-- Creates the navbox table
--
local function createTbl( args )
 local tbl = mw.html.create( 'table' )
 tbl
 :addClass( yesno( args.subgroup ) and 'navbox-subgroup' or 'navbox' )
 :addClass( 'nowraplinks' )
 if not yesno( args.subgroup ) and
 ( args.state == 'collapsed' or
 args.state == 'uncollapsed' or
 args.state == 'autocollapse' or
 -- defaults to autocollapse
 args.state == nil )
 then
 tbl
 :addClass( 'mw-collapsible' )
 if args.state ~= 'uncollapsed' then
 tbl
 :addClass( 'mw-collapsed' )
 end
 end
 if yesno( args.collapsible ) then
 tbl
 :addClass( 'navbox-collapsible' )
 -- remove this after site css updates
 -- -Cqm 2014/08/12
 :css( {
 border = '0',
 ['margin-top'] = '-2px'
 } )
 end
 if args.style then
 tbl
 :cssText( args.style )
 end
 -- manually set collapse/expand messages
 -- bug causing the default database messages to be used
 tbl
 :attr( {
 ['data-expandtext'] = 'show',
 ['data-collapsetext'] = 'hide'
 } )
 return tbl
end
--
-- Wrapper for Module:Tnavbar
--
local function navbar( args )
 return tnavbar._collapsible( { [1] = args.title, [2] = args.name } )
end
--
-- Creates the header (what you see when the navbox is collapsed)
--
local function header( tbl, args )
 local div = insertRow( tbl )
 :tag( 'th' )
 :attr( 'colspan', '2' )
 :addClass( 'navbox-title' )
 :tag( 'div' )
 -- @todo move this to site css so we can simplify this (hook off a class)
 -- to something like div:wikitext( args.name and navbar( args ) or args.title )
 -- which can be appended to the above and returned straight away
 if args.name then
 div
 :css( 'padding-right', args.state == 'plain' and '6em' or '0' )
 :wikitext( navbar( args ) )
 else
 div
 :css( 'padding-left', args.state == 'plain' and '0' or '6em' )
 :wikitext( args.title )
 end
 return div
 :allDone()
end
--
-- Inserts a row into the navbox
--
local function row( tbl, gtitle, group, gtype, style )
 local tr = insertRow( tbl )
 local td
 if gtitle then
 td = tr
 :tag( 'td' )
 :addClass( 'navbox-group' )
 -- @todo move to site css
 -- no reason for it to be here
 :css( 'width', '15%' )
 :wikitext( gtitle )
 :done()
 :tag( 'td' )
 else
 td = tr
 :tag( 'td' )
 :attr( 'colspan', '2' )
 end
 --[[
 Experimental list styling
 This is unlikely to be implemented in the near future due to it requiring extra css to work
 and wikiamobile currently not supporting that css.
 As an example, it lets you do the following instead if using all the time
 | group3 =
 * 
 * 
 * 
 ]]
 if mw.ustring.match( group, '^%s*%*' ) then
 td
 :newline()
 -- trim whitespace on bullets
 local spl = mw.text.split( group, '\n' )
 for i = 1, #spl do
 spl[i] = mw.text.trim( spl[i] )
 end
 group = table.concat( spl, '\n' ) 
 end
 td
 :addClass( 'navbox-list' )
 :wikitext( group )
 if gtype and mw.ustring.lower( gtype ) == 'subgroup' then
 td
 :css( {
 padding = '0',
 ['border-bottom'] = '0'
 } )
 end
 if style then
 td
 :cssText( style )
 end
 return td
 :allDone()
end
--
-- Inserts a footer into the navbox
--
local function footer( tbl, args )
 local th = insertRow( tbl )
 :tag( 'th' )
 :attr( 'colspan', '2' )
 :addClass( 'navbox-footer' )
 :wikitext( args.footer )
 if args.fstyle then
 th
 :cssText( args.fstyle )
 end
 return th
 :allDone()
end
--
-- Adds Category:Navigational templates to navbox template pages
--
local function categories()
 local title = mw.title.getCurrentTitle()
 local page = title.text
 local ns = title.nsText
 if ns == 'Template' then
 -- sort in category by pagename
 return '' .. page .. ''
 else
 return ''
 end
end
--
-- Adds Template:Navbox/doc to navbox template pages
--
local function docs( frame, args )
 local title = mw.title.getCurrentTitle()
 local base = title.baseText
 local ns = title.nsText
 -- not if a subpage of Template:Navbox
 if base ~= 'Navbox' and
 -- in template ns
 ns == 'Template' and
 -- not a navbox group within a navbox
 not yesno( args.subgroup ) and
 -- not a collapsible navbox within a navbox
 not yesno( args.collapsible ) and
 -- not if the doc argument is set to "no"
 ( args.doc == nil or yesno( args.doc ) )
 then
 return frame:expandTemplate{ title = 'Navbox/doc' }
 else
 return ''
 end
end
--
-- Main navbox method accessed through #invoke
--
function p.navbox( frame )
 local parent = frame:getParent()
 local _args = parent.args
 local args = {}
 local wkCss = ''
 local wkDiv = ''
 local j
 -- preserves parser function behaviour where an empty string is considered undefined
 -- or nil in lua's case
 for k, v in pairs( _args ) do
 if v ~= then
 args[k] = v
 end
 end
 local tbl = createTbl( args )
 if not yesno( args.subgroup ) then
 tbl = header( tbl, args )
 -- css for wikiamobile, found on MediaWiki:Wk-style-navbox
 --
 -- it's here so it works for the apps as well as the wikiamobile skin
 -- as there is no system message found on every app page
 -- or not one that I can reliably say is used anyway
 --
 -- .wkPage is pretty much the only class common to both the skin and the apps
 -- that is a parent to #mw-content-text (the content area)
 wkCss = frame:preprocess( '<verbatim>wk-style-navbox</verbatim>' )
 -- close div opened in MediaWiki:Wk-style-navbox
 -- workaround for wikiamobile wide table container
 -- can be found at MediaWiki:Wk-style-divclose
 wkDiv = frame:preprocess( '<verbatim>wk-style-divclose</verbatim>' )
 end
 -- insert up to 20 rows
 --
 -- 20 is a limit inherited from wikipedia when we copied this over
 -- and we've never had a reason to extend it
 for i = 1, 20 do
 j = tostring( i )
 if args['group' .. j] then
 tbl = row( tbl, args['gtitle' .. j], args['group' .. j], args['gtype' .. j], args['style' .. j] )
 else
 break
 end
 end
 if args.footer then
 tbl = footer( tbl, args )
 end
 tbl = tostring( tbl )
 local cats = categories()
 local docs = docs( frame, args )
 return wkCss .. tbl .. cats .. docs .. wkDiv
end
return p