Jump to content
Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
Revision as of 20:28, 13 June 2026 by Gravy (talk | contribs) (1 revision imported from starcitizen:Module:InfoboxLua)

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

require('strict')

local PLACEHOLDER_IMAGE = 'Placeholderv2.png'
local PLACEHOLDER_IMAGE_SIZE = 400
local INFOBOX_WIDTH = 400

local headerComponent = require('Module:InfoboxLua/Components/Header')
local sectionComponent = require('Module:InfoboxLua/Components/Section')

--- @class InfoboxLuaData
--- @field class string|nil An additional HTML class for the infobox's container. Optional.
--- @field css table<string, string>|nil Additional CSS rules for the infobox. Optional.
--- @field title string The title of the infobox.
--- @field subtitle string|nil The subtitle of the infobox. Optional.
--- @field image ImageComponentData|string|nil The main image of the infobox. Optional.
--- @field images table<ImageComponentData>|nil The images of the infobox. Optional.
--- @field sections table<SectionComponentData>|nil The sections of the infobox. Optional.

local p = {}

--- Get the image data
---
--- @param image string|ImageComponentData
--- @return ImageComponentData
local function getImageData(image)
	local imageData = {}

	if type(image) == 'string' then
		imageData.src = image
	end

	if type(image) == 'table' then
		imageData = image
	end

	if type(imageData.size) ~= 'number' then
		imageData.size = INFOBOX_WIDTH
	end

	-- No image source, use placeholder
	if type(imageData.src) ~= 'string' then
		imageData.src = PLACEHOLDER_IMAGE
		imageData.size = PLACEHOLDER_IMAGE_SIZE
	end

	return imageData
end

--- @param data InfoboxLuaData
--- @return mw.html
local function getContentHtml(data)
	local contentHtml = mw.html.create('div'):addClass('t-infobox-content')

	contentHtml:node(headerComponent.getHtml({
		title = data.title,
		subtitle = data.subtitle or nil,
		image = getImageData(data.image),
		images = data.images or nil,
	}))

	for _, section in ipairs(data.sections) do
		local sectionHtml = sectionComponent.getHtml(section)
		if sectionHtml then
			contentHtml:node(sectionHtml)
		end
	end

	return contentHtml
end

--- @param data InfoboxLuaData
--- @return mw.html
local function getInfoboxHtml(data)
	local root = mw.html.create('div')
	root:addClass('t-infobox floatright')
		:addClass(data.class)
		:attr('role', 'complementary')
		:attr('aria-label', data.title)
		:css('max-width', INFOBOX_WIDTH .. 'px')
		:node(getContentHtml(data))

	if type(data.css) == 'table' then
		for cssProperty, cssValue in pairs(data.css) do
			root:css(cssProperty, cssValue)
		end
	end

	return root
end

--- @param data InfoboxLuaData
--- @return string
function p.render(data)
	local html = getInfoboxHtml(data)
	local styles = mw.getCurrentFrame():extensionTag({
		name = 'templatestyles',
		args = { src = 'Module:InfoboxLua/styles.css' },
	})

	return styles .. tostring(html)
end

function p.test()
	local data = mw.loadJsonData('Module:InfoboxLua/testData.json')
	local html = p.render(data)

	mw.logObject(data)
	mw.logObject(html)

	return html
end

return p
Last modified