Module:InfoboxMonster

From MB Wiki
Jump to navigation Jump to search

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

-- Module:InfoboxMonster (Fixed - No empty rows)
local p = {}

-- Define CSS styles
local STYLE_FLOATING = 'float: right !important; clear: right !important; max-width: 300px !important; margin: 0 0 16px 16px !important; border: 1px solid #7a1a1a !important; border-radius: 10px !important; background-color: #FFFFFF !important; font-size: .9em !important;'
local STYLE_HEADER = 'background: #7a1a1a !important; color: white !important; padding: 8px 10px !important; text-align: center !important; font-weight: bold !important; font-size: 1.5em !important; border-top-left-radius: 10px !important; border-top-right-radius: 10px !important;'
local STYLE_SECTION_TITLE = 'padding: 5px 10px !important; color: #4A5568 !important; font-weight: bold !important; border-bottom: 1px solid #A2A9B1 !important; margin: 10px 0 5px 0 !important;'
local STYLE_DATAROW = 'display: flex !important; justify-content: space-between !important; padding: 5px 10px !important; border-bottom: 1px dotted #A2A9B1 !important;'
local STYLE_DATALABEL = 'font-weight: 500 !important; color: #4A5568 !important; width: 40% !important; text-align: left !important;'
local STYLE_DATAVALUE = 'color: #4A5568 !important; text-align: right !important; width: 60% !important;'

-- Function to generate a single data row
local function make_data_row(label, value)
    -- Only create row if value exists and is not empty
    if value and value ~= '' then
        return string.format(
            '<div style="%s"><span style="%s">%s:</span> <span style="%s">%s</span></div>',
            STYLE_DATAROW,
            STYLE_DATALABEL,
            label,
            STYLE_DATAVALUE,
            value
        )
    end
    return ''
end

-- Function to create category links
local function make_category_links(args)
    local categories = {}
    
    if args.element and args.element ~= '' then
        table.insert(categories, string.format('[[Category:%s monsters]]', args.element))
    end
    
    if args.type and args.type ~= '' then
        table.insert(categories, string.format('[[Category:%s monsters]]', args.type))
    end
    
    return table.concat(categories, '\n')
end

-- Function to create list section ONLY if it has content
local function make_list_section(title, items)
    -- Return empty string if no items or items is empty/whitespace
    if not items or items:match("^%s*$") then
        return ''
    end
    
    local html = {}
    table.insert(html, string.format('<div class="monster-section">'))
    table.insert(html, string.format('<div class="section-title" style="%s">%s</div>', STYLE_SECTION_TITLE, title))
    
    -- Handle "TBD" as special case
    if items == 'TBD' then
        table.insert(html, '<ul style="margin: 0 !important; padding-left: 20px !important;"><li>TBD</li></ul>')
    else
        -- Parse comma-separated list
        local list_items = {}
        for item in string.gmatch(items, '([^,]+)') do
            item = item:gsub('^%s*(.-)%s*$', '%1') -- trim
            if item ~= '' then
                table.insert(list_items, string.format('<li>%s</li>', item))
            end
        end
        
        if #list_items > 0 then
            table.insert(html, string.format('<ul style="margin: 0 !important; padding-left: 20px !important;">%s</ul>', table.concat(list_items, '')))
        else
            -- If we get here, items wasn't empty but had no valid list items
            return ''
        end
    end
    
    table.insert(html, '</div>')
    return table.concat(html, '\n')
end

-- Main function - ONLY creates rows for parameters that exist
function p.infobox(frame)
    local args = frame:getParent().args
    
    local name = args.title or args.name or frame:getParent().title.text
    
    local html = {}
    
    -- Start the main infobox container
    table.insert(html, string.format('<div class="monster-infobox" style="%s">', STYLE_FLOATING))
    
    -- Header/Title
    table.insert(html, string.format('<div class="monster-header" style="%s">%s</div>', STYLE_HEADER, name))
    
    -- Image Section
    if args.image and args.image ~= '' then
        local image_link = string.format('[[File:%s|250px|alt=%s]]', args.image, name)
        table.insert(html, string.format('<div class="monster-image" style="padding: 10px !important; text-align: center !important;">%s</div>', image_link))
    end
    
    -- Start Basic Information Section
    table.insert(html, '<div class="monster-section">')
    table.insert(html, string.format('<div class="section-title" style="%s">Basic Information</div>', STYLE_SECTION_TITLE))
    
    -- Data Rows - ONLY for parameters that exist in the call
    local rows = {}
    
    -- Define ALL possible parameters in order
    local all_params = {
        {key = 'element', label = 'Element'},
        {key = 'type', label = 'Type'},
        {key = 'size', label = 'Size'},
        {key = 'zone', label = 'Zone'},
        {key = 'habitat', label = 'Habitat'},
        {key = 'difficulty', label = 'Difficulty'},
        {key = 'behavior', label = 'Behavior'},
        {key = 'hp', label = 'HP'},
        {key = 'attack', label = 'Attack'},
        {key = 'defense', label = 'Defense'},
        {key = 'magic', label = 'Magic'},
        {key = 'speed', label = 'Speed'},
        {key = 'exp', label = 'EXP'},
        {key = 'gold', label = 'Gold'},
        -- NOTE: weaknesses, resistances, drops are handled separately as lists
    }
    
    -- Create rows only for parameters that exist in args
    for _, param in ipairs(all_params) do
        if args[param.key] then
            table.insert(rows, make_data_row(param.label, args[param.key]))
        end
    end
    
    -- Join all rows
    table.insert(html, table.concat(rows, '\n'))
    
    table.insert(html, '</div>') -- End basic info section
    
    -- List Sections (only if they have content)
    table.insert(html, make_list_section('Weaknesses', args.weaknesses))
    table.insert(html, make_list_section('Resistances', args.resistances))
    table.insert(html, make_list_section('Drops', args.drops))
    
    -- End container
    table.insert(html, '</div>') -- End monster-infobox
    
    -- Add categories
    table.insert(html, '\n<!-- Categories -->\n' .. make_category_links(args))
    
    return table.concat(html, '\n')
end

return p