Module:Main page

From MB Wiki
Jump to navigation Jump to search

local p = {}
local h = {}

-- merge args from frame and frame:getParent()
function h.mergeArgs(frame)
    local inputArgs = {}
    
    -- Check if frame.args exists
    if frame.args then
        for k, v in pairs(frame.args) do
            v = mw.text.trim(tostring(v))
            if v ~= '' then
                inputArgs[k] = v
            end
        end
    end
    
    -- Check if frame:getParent() exists and has args
    local parent = frame:getParent()
    if parent and parent.args then
        for k, v in pairs(parent.args) do
            v = mw.text.trim(tostring(v))
            if v ~= '' then
                inputArgs[k] = v
            end
        end
    end
    
    return inputArgs
end

--------------------------------------------------------------------

function p.main(frame)
    if not frame then
        return "Error: No frame provided"
    end
    
    local args = h.mergeArgs(frame)
    
    -- use the rootpage parameter if given, otherwise use the current page name
    local rootpage = args['rootpage'] or mw.title.getCurrentTitle().fullText
    
    local layouts = {'desktop', 'tablet', 'mobile'}
    
    -- Initialize layout arguments if they don't exist
    for _, layout in pairs(layouts) do
        args[layout] = args[layout] or ''
        -- Clean up the layout string
        args[layout] = mw.text.trim(args[layout]):gsub("\n\n+", "\n"):gsub("  +", " "):gsub(" \n", "\n"):gsub("\n ", "\n")
        
        -- Check if columns are consistent in this layout (only if layout is not empty)
        if args[layout] ~= '' then
            local warn = false
            local last_column_count = 0
            local rows = mw.text.split(mw.text.trim(args[layout]), '\n')
            for _, row in pairs(rows) do
                if row ~= '' then
                    local current_column_count = #mw.text.split(row, '%s+')
                    if last_column_count == 0 then
                        last_column_count = current_column_count
                    elseif last_column_count ~= current_column_count then
                        warn = true
                    end
                end
            end
            if warn then
                mw.addWarning('ERROR: the ' .. layout .. ' layout does not have a consistent number of columns in each row. This will result in all the boxes merging into one.')
            end
        end
    end
    
    -- Parse the arguments into CSS variables
    local desktop_var = args['desktop'] ~= '' and "--main-page-layout--desktop: '" .. string.gsub(args['desktop'], '\n', "' '") .. "';" or ''
    local tablet_var = args['tablet'] ~= '' and "--main-page-layout--tablet: '" .. string.gsub(args['tablet'], '\n', "' '") .. "';" or ''
    local mobile_var = args['mobile'] ~= '' and "--main-page-layout--mobile: '" .. string.gsub(args['mobile'], '\n', "' '") .. "';" or ''
    
    -- grid-template-columns overrides
    local desktop_cols = mw.text.trim(string.gsub(args['desktop-columns'] or '', ';', ''))
    local tablet_cols = mw.text.trim(string.gsub(args['tablet-columns'] or '', ';', ''))
    local mobile_cols = mw.text.trim(string.gsub(args['mobile-columns'] or '', ';', ''))
    
    -- Set the variables used by grid-template-columns
    if desktop_cols ~= '' then
        desktop_var = desktop_var .. '--main-page-layout-columns--desktop: '.. desktop_cols ..';'
    end
    if tablet_cols ~= '' then
        tablet_var = tablet_var .. '--main-page-layout-columns--tablet: '.. tablet_cols ..';'
    end
    if mobile_cols ~= '' then
        mobile_var = mobile_var .. '--main-page-layout-columns--mobile: '.. mobile_cols ..';'
    end

    local boxes = {}
    local seen_boxes = {}
    local boxes_in_layout = {}
    local missing_boxes = {}
    
    -- Function to parse layout (moved inside main to access args)
    local function parse_layout(layout)
        if args[layout] and args[layout] ~= '' then
            for _, name in pairs(mw.text.split(mw.text.trim(args[layout]), '%s+')) do
                if name ~= '' then
                    if not seen_boxes[name] then
                        boxes[#boxes + 1] = name
                        seen_boxes[name] = true
                    end
                    boxes_in_layout[layout][name] = true
                end
            end
        end
    end
    
    -- Loop through the layouts to set up the box lists
    for _, layout in pairs(layouts) do
        boxes_in_layout[layout] = {}
        missing_boxes[layout] = {}
        parse_layout(layout)
    end
    
    -- Check for missing boxes in each layout
    for _, layout in pairs(layouts) do
        for _, name in pairs(boxes) do
            if not boxes_in_layout[layout][name] then
                mw.addWarning('WARNING: the "' .. name .. '" box is missing in the ' .. layout .. ' layout. If this is intentional, you can ignore this warning.')
                missing_boxes[layout][name] = true
            end
        end
    end
    
    -- Start our mp-container wrapper
    local output = mw.html.create('div')
    output:attr('id', 'mp-container')
        :cssText(desktop_var .. tablet_var .. mobile_var)
        :attr('data-rootpage', rootpage)
    
    -- Loop through boxes and add the relevant main page subpages
    for _, box in pairs(boxes) do
        -- FIX: Check if VariablesLua exists before using it
        if mw.ext and mw.ext.VariablesLua then
            mw.ext.VariablesLua.vardefine('imp-variable-id', box)
            
            local pre_vardefine = ''
            for _, layout in pairs(layouts) do
                pre_vardefine = pre_vardefine .. (missing_boxes[layout][box] and '0' or '1') .. ','
            end
            
            mw.ext.VariablesLua.vardefine('imp-variable-display-box', pre_vardefine)
        else
            -- Alternative: Use frame:preprocess to set variables
            frame:preprocess('{{#vardefine:imp-variable-id|' .. box .. '}}')
            
            local pre_vardefine = ''
            for _, layout in pairs(layouts) do
                pre_vardefine = pre_vardefine .. (missing_boxes[layout][box] and '0' or '1') .. ','
            end
            
            frame:preprocess('{{#vardefine:imp-variable-display-box|' .. pre_vardefine .. '}}')
        end
        
        local box_page = rootpage .. '/' .. box
        if mw.title.new(box_page).exists then
            output:wikitext(frame:expandTemplate{ title = ':' .. box_page })
        else
            output:wikitext(frame:expandTemplate{ 
                title = 'Main page box/missing', 
                args = { box, rootpage = rootpage }
            })
        end
    end
    
    return tostring(output)
end

-- Add show function for compatibility
function p.show(frame)
    return p.main(frame)
end

return p