Module:Navbox: Difference between revisions

Jump to navigation Jump to search
m (1 revision)
 
m (1 revision)
 
(13 intermediate revisions by the same user not shown)
Line 6: Line 6:
   
   
local HtmlBuilder = require('Module:HtmlBuilder')
local HtmlBuilder = require('Module:HtmlBuilder')
local Navbar = require('Module:Navbar')
local navbar = require('Module:Navbar')._navbar
local getArgs -- lazily initialized


local args
local args
local frame
local tableRowAdded = false
local tableRowAdded = false
local border
local border
local listnums = {}
local listnums = {}
   
   
function trim(s)
local function trim(s)
     return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))
     return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))
end
end


function addTableRow(tbl)
local function addNewline(s)
    if s:match('^[*:;#]') or s:match('^{|') then
        return '\n' .. s ..'\n'
    else
        return s
    end
end
 
local function addTableRow(tbl)
     -- If any other rows have already been added, then we add a 2px gutter row.
     -- If any other rows have already been added, then we add a 2px gutter row.
     if tableRowAdded then
     if tableRowAdded then
Line 25: Line 33:
                 .css('height', '2px')
                 .css('height', '2px')
                 .tag('td')
                 .tag('td')
                .attr('colspan',2)
     end
     end
      
      
Line 32: Line 41:
end
end


local function renderNavBar(titleCell)
    -- 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 args.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 args.state == 'plain' then spacerSide = 'right' end
    elseif args.navbar == 'plain' or (not args.name and mw.getCurrentFrame():getParent():getTitle() == 'Template:Navbox' and (border == 'subgroup' or border == 'child' or border == 'none')) then
        -- No navbar. Need a spacer on the left to balance out the width of the show/hide link.
        if args.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 args.state == 'plain' then spacerSide = 'right' end
        titleCell.wikitext(navbar{
            args.name,
            mini = 1,
            fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') ..  ';background:none transparent;border:none;'
        })
    end
   
    -- Render the spacer div.
    if spacerSide then
        titleCell
            .tag('span')
                .css('float', spacerSide)
                .css('width', '6em')
                .wikitext(' ')
    end
end


--
--
--  Title row
--  Title row
--
--
function renderTitleRow(tbl)
local function renderTitleRow(tbl)
     if not args.title then return end
     if not args.title then return end
   
   
Line 72: Line 114:
         .attr('colspan', titleColspan)
         .attr('colspan', titleColspan)
   
   
    renderNavBar(titleCell)
    renderNavBar(titleCell)
 
    titleCell
    titleCell
         .tag('div')
         .tag('div')
             .addClass(args.titleclass)
             .addClass(args.titleclass)
             .css('font-size', '110%')
             .css('font-size', '110%')
             .newline()
             .wikitext(addNewline(args.title))
            .wikitext(args.title)
end
end


function renderNavBar(titleCell)
--
    -- Depending on the presence of the navbar and/or show/hide link, we may need to add a spacer div on the left
--   Above/Below rows
    -- or right to keep the title centered.
--
    local spacerSide = nil


     if args.navbar == 'off' then
local function getAboveBelowColspan()
        -- No navbar, and client wants no spacer, i.e. wants the title to be shifted to the left. If there's
     local ret = 2
        -- also no show/hide link, then we need a spacer on the right to achieve the left shift.
     if args.imageleft then ret = ret + 1 end
        if args.state == 'plain' then spacerSide = 'right' end
     if args.image then ret = ret + 1 end
     elseif args.navbar == 'plain' or args.navbar == 'off' or (not args.name and (border == 'subgroup' or border == 'child' or border == 'none')) then
     return ret
        -- No navbar. Need a spacer on the left to balance out the width of the show/hide link.
        if args.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 args.state == 'plain' then spacerSide = 'right' end
 
        titleCell.wikitext(Navbar.navbar({
            args.name,
            mini = 1,
            fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') ..  ';background:none transparent;border:none;'
        }))
    end
      
    -- Render the spacer div.
    if spacerSide then
        titleCell
            .tag('span')
                .css('float', spacerSide)
                .css('width', '6em')
                .wikitext(' ')
    end
end
end


local function renderAboveRow(tbl)
    if not args.above then return end


--
--  Above/Below rows
--
function renderAboveRow(tbl)
    if not args.above then return end
     addTableRow(tbl)
     addTableRow(tbl)
         .tag('td')
         .tag('td')
Line 131: Line 145:
             .attr('colspan', getAboveBelowColspan())
             .attr('colspan', getAboveBelowColspan())
             .tag('div')
             .tag('div')
                 .newline()
                 .wikitext(addNewline(args.above))
                .wikitext(args.above)
end
end


function renderBelowRow(tbl)
local function renderBelowRow(tbl)
     if not args.below then return end
     if not args.below then return end
   
 
     addTableRow(tbl)
     addTableRow(tbl)
         .tag('td')
         .tag('td')
Line 146: Line 159:
             .attr('colspan', getAboveBelowColspan())
             .attr('colspan', getAboveBelowColspan())
             .tag('div')
             .tag('div')
                 .newline()
                 .wikitext(addNewline(args.below))
                .wikitext(args.below)
end
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
--  List rows
--
--
function renderListRow(tbl, listnum)
local function renderListRow(tbl, listnum)
     local row = addTableRow(tbl)
     local row = addTableRow(tbl)
      
      
Line 174: Line 178:
                 .attr('rowspan', 2 * #listnums - 1)
                 .attr('rowspan', 2 * #listnums - 1)
                 .tag('div')
                 .tag('div')
                     .newline()
                     .wikitext(addNewline(args.imageleft))
                    .wikitext(args.imageleft)
     end
     end
   
   
Line 222: Line 225:
         if isOdd then evenOdd = args.evenodd or 'odd' else evenOdd = args.evenodd or 'even' end
         if isOdd then evenOdd = args.evenodd or 'odd' else evenOdd = args.evenodd or 'even' end
     end
     end
   
 
     listCell
     listCell
         .css('padding', '0px')
         .css('padding', '0px')
Line 233: Line 236:
         .tag('div')
         .tag('div')
             .css('padding', (listnum == 1 and args.list1padding) or args.listpadding or '0em 0.25em')
             .css('padding', (listnum == 1 and args.list1padding) or args.listpadding or '0em 0.25em')
             .newline()
             .wikitext(addNewline(args['list' .. listnum]))
            .wikitext(args['list' .. listnum])


     if listnum == 1 and args.image then
     if listnum == 1 and args.image then
Line 246: Line 248:
                 .attr('rowspan', 2 * #listnums - 1)
                 .attr('rowspan', 2 * #listnums - 1)
                 .tag('div')
                 .tag('div')
                     .newline()
                     .wikitext(addNewline(args.image))
                    .wikitext(args.image)
     end
     end
end
end
Line 255: Line 256:
--  Tracking categories
--  Tracking categories
--
--
function renderTrackingCategories(builder)
    local frame = mw.getCurrentFrame()
   
    if not frame then return end
   
    local s = frame:preprocess('{{#ifeq:{{NAMESPACE}}|{{ns:10}}|1|0}}{{SUBPAGENAME}}')
    if mw.ustring.sub(s, 1, 1) == '0' then return end -- not in template space
    local subpage = mw.ustring.lower(mw.ustring.sub(s, 2))
    if subpage == 'doc' or subpage == 'sandbox' or subpage == 'testcases' then return end
   
    for i, cat in ipairs(getTrackingCategories()) do
        builder.wikitext('[[Category:' .. cat .. ']]')
    end
end


function getTrackingCategories()
local function needsHorizontalLists()
    local cats = {}
    if needsHorizontalLists() then table.insert(cats, 'Navigational boxes without horizontal lists') end
    if hasBackgroundColors() then table.insert(cats, 'Navboxes using background colours') end
    return cats
end
 
function needsHorizontalLists()
     if border == 'child' or border == 'subgroup'  or args.tracking == 'no' then return false end
     if border == 'child' or border == 'subgroup'  or args.tracking == 'no' then return false end
      
      
     local listClasses = {'plainlist', 'hlist', 'hlist hnum', 'hlist hwrap', 'hlist vcard', 'vcard hlist'}
     local listClasses = {'plainlist', 'hlist', 'hlist hnum', 'hlist hwrap', 'hlist vcard', 'vcard hlist', 'hlist vevent'}
     for i, cls in ipairs(listClasses) do
     for i, cls in ipairs(listClasses) do
         if args.listclass == cls or args.bodyclass == cls then
         if args.listclass == cls or args.bodyclass == cls then
Line 290: Line 270:
end
end


function hasBackgroundColors()
local function hasBackgroundColors()
     return args.titlestyle or args.groupstyle
     return mw.ustring.match(args.titlestyle or '','background') or mw.ustring.match(args.groupstyle or '','background') or mw.ustring.match(args.basestyle or '','background')
end
end


local function getTrackingCategories()
    local cats = {}
    if needsHorizontalLists() then table.insert(cats, 'Navigational boxes without horizontal lists') end
    if hasBackgroundColors() then table.insert(cats, 'Navboxes using background colours') end
    return cats
end
local function renderTrackingCategories(builder)
    local title = mw.title.getCurrentTitle()
    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
   
    for i, cat in ipairs(getTrackingCategories()) do
        builder.wikitext('[[Category:' .. cat .. ']]')
    end
end


--
--
--  Main navbox tables
--  Main navbox tables
--
--
function renderMainTable()
local function renderMainTable()
     local tbl = HtmlBuilder.create('table')
     local tbl = HtmlBuilder.create('table')
         .attr('cellspacing', 0)
         .attr('cellspacing', 0)
Line 381: Line 378:
   
   
function p.navbox(frame)
function p.navbox(frame)
     -- ParserFunctions considers the empty string to be false, so to preserve the previous
     if not getArgs then
    -- behavior of {{navbox}}, change any empty arguments to nil, so Lua will consider
    getArgs = require('Module:Arguments').getArgs
     -- them false too.
     end
     local args = {}
     args = getArgs(frame, {wrappers = 'Template:Navbox'})
    local parent_args = frame:getParent().args;


     -- Out of order parsing bug.
     -- Read the arguments in the order they'll be output in, to make references number in the right order.
     local temp;
     local _
     temp = parent_args.title;
     _ = args.title
     temp = parent_args.above;
     _ = args.above
     for i = 1, 20 do
     for i = 1, 20 do
         temp = parent_args["group" .. tostring(i)];
         _ = args["group" .. tostring(i)]
         temp = parent_args["list" .. tostring(i)];
         _ = args["list" .. tostring(i)]
     end     
     end     
     temp = parent_args.below;
     _ = args.below
   
 
    for k, v in pairs(parent_args) do
        if v ~= '' then
            args[k] = v
        end
    end
     return p._navbox(args)
     return p._navbox(args)
end
end
   
   
return p
return p