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 common = require("Module:Common")
local ustring = mw.ustring
local html = mw.html
-- ---------- Data ----------
local MAX_ROWS = 10
local CATEGORY_EMPTY_ROW_REGEX = "%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^%]]*%]%]"
-- ---------- 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_EMPTY_ROW_REGEX, "") 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, "rows"
elseif args["header" .. i] then return "header", i, "rows"
elseif args["subheader" .. i] then return "subheader", i, "subheaders"
elseif args["image" .. i] then return "image", i, "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 empty_row_categories[#empty_row_categories + 1] = 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 = common.trim(v)
if v ~= "" then args[k] = v end
end
local field, idx, noun = checkOverflows(args)
if field then return common.error("%s%s exceeds the maximum of %s %s.", field, idx, MAX_ROWS, noun) 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
-- ---------- Interface ----------
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