Module:MBNavbox: Difference between revisions

From MB Wiki
Jump to navigation Jump to search
(Created page with "local p = {} function p.main(frame) local args = frame:getParent().args -- Color values extracted from your CSS local colors = { -- Light theme (default) theme_border_color = '#a1e9dc', theme_accent_label_color = '#ffffff', teal_600 = '#2c7a7b', teal_800 = '#234e52', teal_050 = '#e6fffa', teal_100 = '#b2f5ea', teal_200 = '#81e6d9', teal_700 = '#285e61', teal_900 = '#1d4044',...")
 
mNo edit summary
 
Line 1: Line 1:
local p = {}
local p = {}
-- Helper function to check if a file exists (requires expensive function overhead,
-- so we usually just assume the naming convention: Item Name.png)
local function getIcon(item)
    return string.format('[[File:%s.png|22px|link=%s|alt=%s]]', item, item, item)
end


function p.main(frame)
function p.main(frame)
     local args = frame:getParent().args
     local args = frame:getParent().args
    local title = args.title or 'Character Info'
      
      
     -- Color values extracted from your CSS
     -- MB Theme Colors (Map these to your Rarity/Tiers)
     local colors = {
     local theme = {
         -- Light theme (default)
         bg = '#1a1a1a',           -- Deep dark background
        theme_border_color = '#a1e9dc',
         header = '#2c7a7b',       -- Default Teal
        theme_accent_label_color = '#ffffff',
         border = '#a1e9dc',       -- Glowing border
         teal_600 = '#2c7a7b',
         text = '#f5fdfb'
         teal_800 = '#234e52',
        teal_050 = '#e6fffa',
        teal_100 = '#b2f5ea',
        teal_200 = '#81e6d9',
        teal_700 = '#285e61',
        teal_900 = '#1d4044',
        theme_page_background_color = '#f5fdfb',
        theme_page_background_color_secondary = '#e8f5f3',
        theme_link_color = '#007d7a',
        theme_link_color_hover = '#005652',
        theme_accent_color = '#38b2ac',
        gray_300 = '#e2e8f0',
       
        -- Dark theme colors for reference (can be added if needed)
         dark_theme_border_color = '#4d6872',
        dark_teal_700 = '#285e61',
        dark_teal_900 = '#1d4044',
        dark_card_bg_main = '#2a363d',
        dark_card_bg_sub = '#3a464d',
        dark_teal_200 = '#81e6d9',
        dark_teal_100 = '#b2f5ea'
     }
     }
      
      
     -- Create main container
     -- Handle Rarity/Tier coloring
     local navbox = mw.html.create('table')
     if args.tier == '7' or args.tier == 'Noble' then
        :addClass('navbox')
         theme.header = 'linear-gradient(135deg, #38b2ac 0%, #2c7a7b 100%)'
        :css('width', '100%')
         theme.border = '#81e6d9'
        :css('border-spacing', '0')
        :css('border', '2px solid ' .. colors.theme_border_color)
        :css('border-radius', '8px')
         :css('background', colors.theme_page_background_color_secondary)
        :css('margin', '16px 0')
        :css('overflow', 'hidden')
        :css('box-shadow', '0 1px 3px rgba(0, 0, 0, 0.12)')
        :attr('role', 'navigation')
         :attr('aria-labelledby', (args.name or 'navbox') .. '-title')
   
    -- Add custom class if provided
    if args.class then
        navbox:addClass(args.class)
     end
     end
      
 
     -- Title row
     -- Container
     if args.title then
    local container = mw.html.create('table')
         local titleRow = mw.html.create('tr')
        :addClass('mb-navbox')
        :css({
            ['width'] = '100%',
            ['background'] = theme.bg,
            ['border'] = '2px solid ' .. theme.border,
            ['border-radius'] = '8px',
            ['color'] = theme.text,
            ['border-collapse'] = 'separate',
            ['border-spacing'] = '2px',
            ['margin'] = '10px 0'
        })
 
     -- Title Bar
    container:tag('tr'):tag('th')
        :attr('colspan', '2')
        :css({
            ['background'] = theme.header,
            ['padding'] = '10px',
            ['font-size'] = '1.1em',
            ['text-shadow'] = '1px 1px 2px #000'
        })
        :wikitext(title)
 
    -- Row Logic (Smarter Loop)
    local i = 1
     while args['group' .. i] or args['list' .. i] do
        local groupName = args['group' .. i] or ''
         local listData = args['list' .. i] or ''
          
          
         local titleCell = mw.html.create('th')
         local row = container:tag('tr')
            :attr('colspan', '2')
            :attr('id', (args.name or 'navbox') .. '-title')
            :attr('scope', 'col')
            :css('text-align', 'center')
            :css('font-weight', '700')
            :css('font-size', '18px')
            :css('padding', '8px 12px')
            :css('background', 'linear-gradient(135deg, ' .. colors.teal_600 .. ' 0%, ' .. colors.teal_800 .. ' 100%)')
            :css('color', colors.theme_accent_label_color)
            :css('border-bottom', '1px solid ' .. colors.theme_border_color)
            :css('text-shadow', '0 1px 2px rgba(0,0,0,0.2)')
            :css('letter-spacing', '0.5px')
            :wikitext(args.title)
          
          
         titleRow:node(titleCell)
         -- Group Header (Left side)
         navbox:node(titleRow)
         row:tag('td')
    end
            :addClass('mb-group')
   
            :css({
    -- Build table body
                ['background'] = 'rgba(255,255,255,0.05)',
    local tbody = mw.html.create('tbody')
                ['width'] = '150px',
   
                ['font-weight'] = 'bold',
    -- Process groups and lists
                ['padding'] = '8px',
    local hasContent = false
                ['border-right'] = '1px solid ' .. theme.border .. '33'
   
            })
    -- Method 1: Check for numbered groups/lists
             :wikitext(groupName)
    for i = 1, 10 do
        if args['group' .. i] or args['list' .. i] then
             hasContent = true
              
              
            -- Group row if present
        -- List Content (Right side)
            if args['group' .. i] then
        local listCell = row:tag('td')
                local groupRow = mw.html.create('tr')
            :addClass('mb-content')
                    :css('background', colors.teal_050)
            :css('padding', '8px')
                    :css('border-bottom', '1px solid ' .. colors.theme_border_color .. '80') -- 80 = 50% opacity
 
               
        -- SMART PARSER: Check if we should auto-icon
                local groupCell = mw.html.create('th')
        if args.auto_icons == 'yes' then
                    :attr('scope', 'row')
            local items = mw.text.split(listData, ',%s*') -- Split by comma
                    :css('text-align', 'center')
            local formattedItems = {}
                    :css('vertical-align', 'top')
            for _, item in ipairs(items) do
                    :css('width', '1%')
                -- Remove bullets if present to clean string
                    :css('white-space', 'nowrap')
                local cleanItem = item:gsub('^%s*%*%s*', '')
                    :css('padding', '4px 16px')
                 table.insert(formattedItems, getIcon(cleanItem) .. ' [[' .. cleanItem .. ']]')
                    :css('color', colors.teal_800)
                    :css('font-weight', '600')
                    :css('font-size', '14px')
                    :css('text-transform', 'uppercase')
                    :css('letter-spacing', '0.5px')
                    :css('border-right', '1px solid ' .. colors.theme_border_color .. '80')
                    :wikitext(args['group' .. i])
               
                groupRow:node(groupCell)
                tbody:node(groupRow)
            end
           
            -- List row
            if args['list' .. i] then
                local listRow = mw.html.create('tr')
               
                local listCell = mw.html.create('td')
                    :css('padding', '8px 12px')
                    :css('vertical-align', 'top')
                    :css('background', colors.theme_page_background_color)
                    :css('color', '#1a2a2a') -- From your --theme-page-text-color
                    :css('line-height', '1.6')
               
                -- Set colspan if no group for this item
                if not args['group' .. i] then
                    listCell:attr('colspan', '2')
                end
               
                -- Process list content with proper styling
                local content = args['list' .. i]
               
                -- Check if content starts with asterisk (list items)
                if content:match('^%*') then
                    -- Wrap in a div with hlist class styling
                    local listDiv = mw.html.create('div')
                        :css('margin', '0')
                   
                    -- Process each line
                    for line in content:gmatch('[^\n]+') do
                        if line:match('^%s*%*') then
                            -- It's a list item
                            local listItem = mw.html.create('div')
                                :css('margin', '4px 0')
                                :css('padding-left', '1.2em')
                                :css('position', 'relative')
                           
                            -- Add bullet
                            local bullet = mw.html.create('span')
                                :css('position', 'absolute')
                                :css('left', '0')
                                :css('top', '0')
                                :css('color', colors.teal_600)
                                :wikitext('• ')
                           
                            -- Add content
                            local itemContent = mw.html.create('span')
                           
                            -- Process bold text
                            local processedLine = line:gsub('%*%*%*([^*]+)%-%*%*%*', function(text)
                                return '<span style="font-weight: bold; font-style: italic;">' .. text .. '</span>'
                            end)
                            processedLine = processedLine:gsub('%*%*([^*]+)%*%*', function(text)
                                return '<strong>' .. text .. '</strong>'
                            end)
                            processedLine = processedLine:gsub('%*([^*]+)%*', function(text)
                                return '<em>' .. text .. '</em>'
                            end)
                           
                            -- Remove leading asterisk and spaces
                            processedLine = processedLine:gsub('^%s*%*%s*', '')
                           
                            itemContent:wikitext(processedLine)
                           
                            listItem:node(bullet)
                            listItem:node(itemContent)
                            listDiv:node(listItem)
                        else
                            -- Regular text line
                            local textLine = mw.html.create('div')
                                :css('margin', '4px 0')
                                :wikitext(line)
                            listDiv:node(textLine)
                        end
                    end
                   
                    listCell:node(listDiv)
                 else
                    -- Regular content (not a list)
                    local contentDiv = mw.html.create('div')
                   
                    -- Process any bold/italic markup in regular content
                    local processedContent = content
                    processedContent = processedContent:gsub('%*%*%*([^*]+)%-%*%*%*', function(text)
                        return '<span style="font-weight: bold; font-style: italic;">' .. text .. '</span>'
                    end)
                    processedContent = processedContent:gsub('%*%*([^*]+)%*%*', function(text)
                        return '<strong>' .. text .. '</strong>'
                    end)
                    processedContent = processedContent:gsub('%*([^*]+)%*', function(text)
                        return '<em>' .. text .. '</em>'
                    end)
                   
                    contentDiv:wikitext(processedContent)
                    listCell:node(contentDiv)
                end
               
                -- Style links within the content
                listCell:css('word-wrap', 'break-word')
               
                listRow:node(listCell)
                tbody:node(listRow)
            end
           
            -- Add spacer row between sections if not last
            local nextHasContent = false
            for j = i + 1, 10 do
                if args['group' .. j] or args['list' .. j] then
                    nextHasContent = true
                    break
                end
            end
           
            if nextHasContent then
                local spacerRow = mw.html.create('tr')
                local spacerCell = mw.html.create('td')
                    :attr('colspan', '2')
                    :css('height', '5px')
                    :css('background', 'transparent')
                    :css('border-top', '1px dashed ' .. colors.theme_border_color .. '80')
                spacerRow:node(spacerCell)
                tbody:node(spacerRow)
             end
             end
            listCell:wikitext(table.concat(formattedItems, ' • '))
        else
            listCell:wikitext(listData)
         end
         end
        i = i + 1
     end
     end
   
 
    -- Method 2: Check for simple content (no numbers)
     return tostring(container)
    if not hasContent and args.content then
        local contentRow = mw.html.create('tr')
        local contentCell = mw.html.create('td')
            :attr('colspan', '2')
            :css('padding', '12px')
            :css('background', colors.theme_page_background_color)
            :css('line-height', '1.6')
            :wikitext(args.content)
       
        contentRow:node(contentCell)
        tbody:node(contentRow)
    end
   
    -- Add body to table
    navbox:node(tbody)
   
    -- Add link styling via JavaScript-like approach (will be applied to all links in navbox)
    local styleTag = mw.html.create('style')
        :wikitext([[
            .navbox[style*="border: 2px solid #a1e9dc"] a {
                color: ]] .. colors.theme_link_color .. [[;
                text-decoration: none;
                border-bottom: 1px dotted ]] .. colors.gray_300 .. [[;
                transition: all 0.15s ease;
            }
            .navbox[style*="border: 2px solid #a1e9dc"] a:hover {
                color: ]] .. colors.theme_link_color_hover .. [[;
                border-bottom: 2px solid ]] .. colors.theme_accent_color .. [[;
                background: ]] .. colors.teal_050 .. [[;
                border-radius: 4px;
                padding: 0 2px;
            }
            .navbox[style*="border: 2px solid #a1e9dc"] strong {
                font-weight: 700;
                color: ]] .. colors.teal_700 .. [[;
            }
            .navbox[style*="border: 2px solid #a1e9dc"] em {
                font-style: italic;
                color: ]] .. colors.teal_600 .. [[;
            }
        ]])
   
     return tostring(styleTag) .. tostring(navbox)
end
end


return p
return p

Latest revision as of 07:19, 19 December 2025

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

local p = {}

-- Helper function to check if a file exists (requires expensive function overhead, 
-- so we usually just assume the naming convention: Item Name.png)
local function getIcon(item)
    return string.format('[[File:%s.png|22px|link=%s|alt=%s]]', item, item, item)
end

function p.main(frame)
    local args = frame:getParent().args
    local title = args.title or 'Character Info'
    
    -- MB Theme Colors (Map these to your Rarity/Tiers)
    local theme = {
        bg = '#1a1a1a',           -- Deep dark background
        header = '#2c7a7b',       -- Default Teal
        border = '#a1e9dc',       -- Glowing border
        text = '#f5fdfb'
    }
    
    -- Handle Rarity/Tier coloring
    if args.tier == '7' or args.tier == 'Noble' then
        theme.header = 'linear-gradient(135deg, #38b2ac 0%, #2c7a7b 100%)'
        theme.border = '#81e6d9'
    end

    -- Container
    local container = mw.html.create('table')
        :addClass('mb-navbox')
        :css({
            ['width'] = '100%',
            ['background'] = theme.bg,
            ['border'] = '2px solid ' .. theme.border,
            ['border-radius'] = '8px',
            ['color'] = theme.text,
            ['border-collapse'] = 'separate',
            ['border-spacing'] = '2px',
            ['margin'] = '10px 0'
        })

    -- Title Bar
    container:tag('tr'):tag('th')
        :attr('colspan', '2')
        :css({
            ['background'] = theme.header,
            ['padding'] = '10px',
            ['font-size'] = '1.1em',
            ['text-shadow'] = '1px 1px 2px #000'
        })
        :wikitext(title)

    -- Row Logic (Smarter Loop)
    local i = 1
    while args['group' .. i] or args['list' .. i] do
        local groupName = args['group' .. i] or ''
        local listData = args['list' .. i] or ''
        
        local row = container:tag('tr')
        
        -- Group Header (Left side)
        row:tag('td')
            :addClass('mb-group')
            :css({
                ['background'] = 'rgba(255,255,255,0.05)',
                ['width'] = '150px',
                ['font-weight'] = 'bold',
                ['padding'] = '8px',
                ['border-right'] = '1px solid ' .. theme.border .. '33'
            })
            :wikitext(groupName)
            
        -- List Content (Right side)
        local listCell = row:tag('td')
            :addClass('mb-content')
            :css('padding', '8px')

        -- SMART PARSER: Check if we should auto-icon
        if args.auto_icons == 'yes' then
            local items = mw.text.split(listData, ',%s*') -- Split by comma
            local formattedItems = {}
            for _, item in ipairs(items) do
                -- Remove bullets if present to clean string
                local cleanItem = item:gsub('^%s*%*%s*', '')
                table.insert(formattedItems, getIcon(cleanItem) .. ' [[' .. cleanItem .. ']]')
            end
            listCell:wikitext(table.concat(formattedItems, ' • '))
        else
            listCell:wikitext(listData)
        end

        i = i + 1
    end

    return tostring(container)
end

return p