Module:InfoboxMonster: Difference between revisions
Jump to navigation
Jump to search
(Created page with "-- Module:InfoboxMonster local p = {} -- Define CSS styles (matching weapon infobox for consistency) local STYLE_FLOATING = 'float: right !important; clear: right !important; max-width: 350px !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 !i...") |
mNo edit summary |
||
| Line 1: | Line 1: | ||
-- Module:InfoboxMonster | -- Module:InfoboxMonster (Fixed - No empty rows) | ||
local p = {} | local p = {} | ||
-- Define CSS styles | -- Define CSS styles | ||
local STYLE_FLOATING = 'float: right !important; clear: right !important; max-width: | 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_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_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;' | ||
| Line 9: | Line 9: | ||
local STYLE_DATALABEL = 'font-weight: 500 !important; color: #4A5568 !important; width: 40% !important; text-align: left !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;' | local STYLE_DATAVALUE = 'color: #4A5568 !important; text-align: right !important; width: 60% !important;' | ||
-- Function to generate a single data row | -- Function to generate a single data row | ||
local function make_data_row(label, value) | local function make_data_row(label, value) | ||
-- Only create row if value exists and is not empty | |||
if value and value ~= '' then | if value and value ~= '' then | ||
return string.format( | return string.format( | ||
| Line 23: | Line 22: | ||
value | value | ||
) | ) | ||
end | end | ||
return '' | return '' | ||
| Line 42: | Line 30: | ||
local categories = {} | local categories = {} | ||
if args.element and args.element ~= '' then | if args.element and args.element ~= '' then | ||
table.insert(categories, string.format('[[Category:%s monsters]]', args.element)) | table.insert(categories, string.format('[[Category:%s monsters]]', args.element)) | ||
end | end | ||
if args.type and args.type ~= '' then | if args.type and args.type ~= '' then | ||
table.insert(categories, string.format('[[Category:%s | table.insert(categories, string.format('[[Category:%s monsters]]', args.type)) | ||
end | end | ||
| Line 75: | Line 41: | ||
end | end | ||
-- Function to | -- Function to create list section ONLY if it has content | ||
local function | local function make_list_section(title, items) | ||
if not | -- 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)) | |||
local | -- 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 | ||
end | end | ||
table.insert(html, '</div>') | |||
return table.concat(html, '\n') | |||
end | end | ||
-- Main function | -- Main function - ONLY creates rows for parameters that exist | ||
function p.infobox(frame) | function p.infobox(frame) | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local name = args.title or args.name or frame:getParent().title.text | local name = args.title or args.name or frame:getParent().title.text | ||
| Line 111: | Line 93: | ||
-- Image Section | -- Image Section | ||
if args.image and args.image ~= '' then | if args.image and args.image ~= '' then | ||
local image_link = string.format('[[File:%s| | 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)) | table.insert(html, string.format('<div class="monster-image" style="padding: 10px !important; text-align: center !important;">%s</div>', image_link)) | ||
end | end | ||
| Line 119: | Line 101: | ||
table.insert(html, string.format('<div class="section-title" style="%s">Basic Information</div>', STYLE_SECTION_TITLE)) | table.insert(html, string.format('<div class="section-title" style="%s">Basic Information</div>', STYLE_SECTION_TITLE)) | ||
-- Data Rows | -- 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 | ||
if 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 | 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 | -- End container | ||
table.insert(html, '</div>') -- End monster-infobox | table.insert(html, '</div>') -- End monster-infobox | ||
-- Add categories | -- Add categories | ||
table.insert(html, '\n<!-- Categories -->\n' .. make_category_links(args)) | table.insert(html, '\n<!-- Categories -->\n' .. make_category_links(args)) | ||
Latest revision as of 11:22, 6 January 2026
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