Module:NavboxUpgraded

From Ikwipedia
Revision as of 08:30, 22 November 2024 by EnWikiAdmin (talk | contribs)

Documentation for this module may be created at Module:NavboxUpgraded/doc

-- Module:NavboxUpgraded
require('strict')
local p = {}
local cfg = mw.loadData('Module:Navbox/configuration')
local inArray = require("Module:TableTools").inArray
local getArgs -- lazily initialized
local format = string.format

-- Load the stylesheet using the configuration's templatestyles
mw.getCurrentFrame():extensionTag(cfg.templatestyles)


-- Recursive function to process subgroups
local function renderSubgroups(args, groupPrefix)
    local html = mw.html.create()
    for i = 1, 10 do
        local subgroup = args[groupPrefix .. '_group' .. i]
        local sublist = args[groupPrefix .. '_list' .. i]
        if subgroup or sublist then
            local container = html:tag('div')
                :addClass('navbox-subgroup')
                :css('margin-left', '1em') -- Indent for nesting
                :css('padding', '0.25em')

            -- Subgroup heading
            if subgroup then
                container:tag('div')
                    :addClass('navbox-group')
                    :css('background-color', '#e6e6ff') -- Lighter shade
                    :css('padding', '0.25em 1em')
                    :css('font-weight', 'bold')
                    :wikitext(subgroup)
            end

            -- Subgroup list
            if sublist then
                if sublist:lower() == 'subgroup' then
                    -- Recursively render nested subgroups
                    local childArgs = {}
                    for k, v in pairs(args) do
                        local prefix = groupPrefix .. '_list' .. i .. '_'
                        if k:sub(1, #prefix) == prefix then
                            childArgs[k:sub(#prefix + 1)] = v
                        end
                    end
                    local nestedSubgroup = renderSubgroups(childArgs, groupPrefix .. '_list' .. i)
                    container:wikitext(nestedSubgroup)
                else
                    container:tag('ul')
                        :addClass('navbox-list')
                        :css('padding-left', '1.5em')
                        :css('list-style', 'disc')
                        :wikitext(sublist)
                end
            end
            html:node(container)
        end
    end
    return tostring(html)
end

-- Function to generate the desktop navbox
function p._navboxDesktop(args)
    local navbox = mw.html.create('table')
    navbox
        :addClass('navbox-upgraded') -- Updated class
        :css('width', '100%')
        :css('margin', 'auto')
        :css('clear', 'both')
        :css('border', '1px solid #a2a9b1')
        :css('padding', '1px')
        :css('font-size', '88%')
        :css('text-align', 'center')

    -- Handle title
    if args.title then
        local titleRow = navbox:tag('tr')
        local titleCell = titleRow:tag('th')
        titleCell
            :attr('colspan', '2')
            :addClass('navbox-title')
            :css('background-color', '#ccf')
            :css('padding', '0.25em 1em')
            :wikitext(args.title)
    end

    -- Handle above
    if args.above then
        local aboveRow = navbox:tag('tr')
        local aboveCell = aboveRow:tag('td')
        aboveCell
            :attr('colspan', '2')
            :addClass('navbox-abovebelow')
            :css('background-color', '#ddf')
            :css('padding', '0.25em 1em')
            :wikitext(args.above)
    end

    -- Handle groups and lists
    local rowIndex = 0
    for i = 1, 10 do
        local group = args['group' .. i]
        local list = args['list' .. i]
        if group or list then
            rowIndex = rowIndex + 1
            local row = navbox:tag('tr')

            -- Apply striped classes
            if rowIndex % 2 == 1 then
                row:attr('class', 'navbox-odd')
            else
                row:attr('class', 'navbox-even')
            end

            -- Group heading
            if group then
                local groupCell = row:tag('th')
                groupCell
                    :addClass('navbox-group')
                    :css('text-align', 'right')
                    :css('background-color', '#ddf') -- Parent shade
                    :css('padding', '0.25em 1em')
                    :wikitext(group)
            end

            -- Group content
            if list then
                local listCell = row:tag('td')
                    :addClass('navbox-list')

                -- Apply list classes if specified
                if args.listclass then
                    listCell:addClass(args.listclass) -- e.g., 'hlist' or 'plainlist'
                end

                -- Render subgroups or standard lists
                if list:lower() == 'subgroup' then
                    -- Process subgroup
                    local childArgs = {}
                    for k, v in pairs(args) do
                        local prefix = 'list' .. i .. '_'
                        if k:sub(1, #prefix) == prefix then
                            childArgs[k:sub(#prefix + 1)] = v
                        end
                    end
                    local subgroupContent = renderSubgroups(childArgs, 'list' .. i)
                    listCell:wikitext(subgroupContent)
                else
                    listCell:tag('ul')
                        :addClass('navbox-list')
                        :css('list-style', 'disc')
                        :css('padding-left', '1.5em')
                        :wikitext(list)
                end
            end
        end
    end

    -- Handle below
    if args.below then
        local belowRow = navbox:tag('tr')
        local belowCell = belowRow:tag('td')
        belowCell
            :attr('colspan', '2')
            :addClass('navbox-abovebelow')
            :css('background-color', '#ddf')
            :css('padding', '0.25em 1em')
            :wikitext(args.below)
    end

    return tostring(navbox)
end




-- Function to generate the mobile navbox
function p._navboxMobile(args)
    local navbox = mw.html.create('div')
    navbox
        :addClass('navbox-mobile')
        :css('width', '100%')
        :css('margin', 'auto')
        :css('clear', 'both')
        :css('border', '1px solid #a2a9b1')
        :css('padding', '1px')
        :css('font-size', '88%')
        :css('text-align', 'center')

    -- Handle title
    if args.title then
        navbox:tag('div')
            :addClass('navbox-title-mobile')
            :css('background-color', '#ccf')
            :css('padding', '0.25em 1em')
            :wikitext(args.title)
    end

    -- Handle above
    if args.above then
        navbox:tag('div')
            :addClass('navbox-abovebelow-mobile')
            :css('background-color', '#ddf')
            :css('padding', '0.25em 1em')
            :wikitext(args.above)
    end

    -- Handle groups and lists
    for i = 1, 10 do
        local group = args['group' .. i]
        local list = args['list' .. i]
        if group or list then
            if group then
                navbox:tag('div')
                    :addClass('navbox-group-mobile')
                    :css('background-color', '#ddf') -- Parent shade
                    :css('padding', '0.25em 1em')
                    :css('font-weight', 'bold')
                    :wikitext(group)
            end
            if list then
                navbox:tag('div')
                    :addClass('navbox-list-mobile')
                    :css('background-color', '#f7f7f7')
                    :css('padding', '0.25em 1em')
                    :tag('ul')
                        :css('list-style', 'disc') -- Bullets
                        :css('padding-left', '1.5em')
                        :wikitext(list)
            end
        end
    end

    -- Handle below
    if args.below then
        navbox:tag('div')
            :addClass('navbox-abovebelow-mobile')
            :css('background-color', '#ddf')
            :css('padding', '0.25em 1em')
            :wikitext(args.below)
    end

    return tostring(navbox)
end


local function add_navbox_styles()
    local html = mw.html.create()
    
    -- Helper function to add a stylesheet link
    local function add_stylesheet(path)
        html:tag('link')
            :attr('rel', 'stylesheet')
            :attr('href', path)
            :attr('type', 'text/css')
    end

    -- Assuming cfg.templatestyles contains space-separated CSS file paths
    if type(cfg.templatestyles) == 'string' and cfg.templatestyles ~= '' then
        for stylePath in cfg.templatestyles:gmatch("[^%s]+") do
            add_stylesheet(stylePath)
        end
    end

    if type(cfg.hlist_templatestyles) == 'string' and cfg.hlist_templatestyles ~= '' then
        for stylePath in cfg.hlist_templatestyles:gmatch("[^%s]+") do
            add_stylesheet(stylePath)
        end
    end

    if type(cfg.plainlist_templatestyles) == 'string' and cfg.plainlist_templatestyles ~= '' then
        for stylePath in cfg.plainlist_templatestyles:gmatch("[^%s]+") do
            add_stylesheet(stylePath)
        end
    end

    return html:done()
end




-- Main function
function p.navbox(frame)
    if not getArgs then
        getArgs = require('Module:Arguments').getArgs
    end
    local args = getArgs(frame)
    local desktopNavbox = p._navboxDesktop(args)
    local mobileNavbox = p._navboxMobile(args)

    local res = mw.html.create('div')
    res:node(add_navbox_styles()) -- Add styles at the beginning of the div
    res
        :tag('div')
            :addClass('nomobile')
            :wikitext(desktopNavbox) -- Do not include `add_navbox_styles()` here
            :done()
        :tag('div')
            :addClass('onlymobile')
            :wikitext(mobileNavbox) -- Do not include `add_navbox_styles()` here
            :done()

    return tostring(res)
end


return p