Module:InfoboxMonster
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