Module:InfoboxLite
Module:InfoboxLite
A lightweight variant of Module:Infobox for infoboxes that don't need the full feature set. Identical interface but with the following removed:
- TemplateStyles loading
child/subboxsupportautoheaders- Navbar
- Italic title
- Nested wikitable support
These were removed because there are currently no use cases for them on the wiki, and calling them 150~ times on content-heavy pages (such as Research) was causing Lua CPU timeouts.
Row limit
Numbered parameters (data, header, label, image, subheader) are capped, defined by local MAX_ROWS = X below, where X is the defined limit.
If a parameter beyond this limit is detected, up to the original Module:Infobox limit of 50 (e.g. |header11=), the infobox will not render, and an error message will be shown in its place.
Use Module:Infobox directly if you genuinely need more than 10 rows.
Usage
Use Template:InfoboxLite in place of Template:Infobox. All parameters are identical.
local p = {}
local MAX_ROWS = 10
local category_in_empty_row_pattern = '%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^%]]*%]%]'
local ustring = mw.ustring
local html = mw.html
local text = mw.text
local tinsert = table.insert
-- ---------- Helpers ----------
-- Strip categories since category links count as non-whitespace, which can cause empty infobox fields to show up
local function hasVisibleText(s)
if not s then return false end
if s:find('%[%[') then s = ustring.gsub(s, category_in_empty_row_pattern, '') end
return s:find('%S') ~= nil
end
-- Ensure no input fields are above the specified cap
local function checkOverflows(args)
for i = MAX_ROWS + 1, 50 do
if args['data' .. i] then
return '|data' .. i .. '= exceeds the maximum of ' .. MAX_ROWS .. ' rows.'
elseif args['header' .. i] then
return '|header' .. i .. '= exceeds the maximum of ' .. MAX_ROWS .. ' rows.'
elseif args['subheader' .. i] then
return '|subheader' .. i .. '= exceeds the maximum of ' .. MAX_ROWS .. ' subheaders.'
elseif args['image' .. i] then
return '|image' .. i .. '= exceeds the maximum of ' .. MAX_ROWS .. ' images.'
end
end
return nil
end
-- Process bullet lists to ensure they render correctly
local function fixChildBoxes(s, tt)
s = ustring.gsub(s, '([\r\n][%*#;:][^\r\n]*)$', '%1\n')
s = ustring.gsub(s, '^([%*#;:][^\r\n]*)$', '%1\n')
s = ustring.gsub(s, '^([%*#;:])', '\n%1')
return s
end
-- ---------- Rendering ----------
local function renderAboveRow(root, args)
local above = args.above
if not above then return end
root
:tag('tr')
:tag('th')
:attr('colspan', '2')
:addClass('infobox-above')
:addClass(args.aboveclass)
:cssText(args.abovestyle)
:wikitext(fixChildBoxes(above, 'th'))
end
local function renderSubheaders(root, args)
if args.subheader and not args.subheader1 then args.subheader1 = args.subheader end
local subheaderclass = args.subheaderclass
local subheaderstyle = args.subheaderstyle
for i = 1, MAX_ROWS do
local val = args['subheader' .. i]
if hasVisibleText(val) then
root
:tag('tr')
:tag('td')
:attr('colspan', '2')
:addClass('infobox-subheader')
:addClass(subheaderclass)
:cssText(subheaderstyle)
:cssText(args['subheaderstyle' .. i])
:wikitext(fixChildBoxes(val, 'td'))
end
end
end
local function renderImages(root, args)
if args.image and not args.image1 then args.image1 = args.image end
if args.caption and not args.caption1 then args.caption1 = args.caption end
local captionstyle = args.captionstyle
local imageclass = args.imageclass
local imagestyle = args.imagestyle
for i = 1, MAX_ROWS do
local img = args['image' .. i]
if hasVisibleText(img) then
local caption = args['caption' .. i]
local content
if caption then
local data = html.create()
data:wikitext(img)
data:tag('div')
:addClass('infobox-caption')
:cssText(captionstyle)
:wikitext(caption)
content = tostring(data)
end
root
:tag('tr')
:addClass(args['imagerowclass' .. i])
:tag('td')
:attr('colspan', '2')
:addClass('infobox-image')
:addClass(imageclass)
:cssText(imagestyle)
:wikitext(fixChildBoxes(content or img, 'td'))
end
end
end
local function renderRows(root, args, empty_row_categories)
local headerclass = args.headerclass
local headerstyle = args.headerstyle
local labelstyle = args.labelstyle
local datastyle = args.datastyle
for i = 1, MAX_ROWS do
local header = args['header' .. i]
local data = args['data' .. i]
local label = args['label' .. i]
local rowclass = args['rowclass' .. i]
local rowstyle = args['rowstyle' .. i]
local rowcellstyle = args['rowcellstyle' .. i]
if header and header ~= '_BLANK_' then
root
:tag('tr')
:addClass(rowclass)
:cssText(rowstyle)
:tag('th')
:attr('colspan', '2')
:addClass('infobox-header')
:addClass(headerclass)
:cssText(headerstyle)
:cssText(rowcellstyle)
:wikitext(fixChildBoxes(header, 'th'))
elseif hasVisibleText(data) then
local row = root:tag('tr')
row:addClass(rowclass)
row:cssText(rowstyle)
if label then
row
:tag('th')
:attr('scope', 'row')
:addClass('infobox-label')
:cssText(labelstyle)
:cssText(rowcellstyle)
:wikitext(label)
:done()
end
local dataCell = row:tag('td')
dataCell
:attr('colspan', not label and '2' or nil)
:addClass(not label and 'infobox-full-data' or 'infobox-data')
:addClass(args['class' .. i])
:cssText(datastyle)
:cssText(rowcellstyle)
:wikitext(fixChildBoxes(data, 'td'))
else tinsert(empty_row_categories, data or '') end
end
end
local function renderBelowRow(root, args)
local below = args.below
if not below then return end
root
:tag('tr')
:tag('td')
:attr('colspan', '2')
:addClass('infobox-below')
:addClass(args.belowclass)
:cssText(args.belowstyle)
:wikitext(fixChildBoxes(below, 'td'))
end
local function renderEmptyRowCategories(root, empty_row_categories)
for _, s in ipairs(empty_row_categories) do root:wikitext(s) end
end
-- ---------- Main ----------
local function _infobox(origArgs)
local args = {}
for k, v in pairs(origArgs) do
v = text.trim(v)
if v ~= '' then args[k] = v end
end
local overflow = checkOverflows(args)
if overflow then return '<strong class="error">⚠ InfoboxLite error: ' .. overflow .. '</strong>' end
local empty_row_categories = {}
local root = html.create('table')
root
:addClass('infobox')
:addClass(args.bodyclass)
:cssText(args.bodystyle)
if args.title then
root
:tag('caption')
:addClass('infobox-title')
:addClass(args.titleclass)
:cssText(args.titlestyle)
:wikitext(args.title)
end
renderAboveRow(root, args)
renderSubheaders(root, args)
renderImages(root, args)
renderRows(root, args, empty_row_categories)
renderBelowRow(root, args)
renderEmptyRowCategories(root, empty_row_categories)
return tostring(root)
end
function p.infobox(frame)
local origArgs
if frame == mw.getCurrentFrame() then origArgs = frame:getParent().args
else origArgs = frame end
return _infobox(origArgs)
end
function p.infoboxTemplate(frame)
return _infobox(frame.args)
end
return p