Module:Building infobox: Difference between revisions
From Beyond These Stars Official Wiki
adjusted subheadings to parent to the top-level div instead of to their sections; description no longer changes the data object |
adds generic category too |
||
| (3 intermediate revisions by the same user not shown) | |||
| Line 34: | Line 34: | ||
local RESOURCE_ICON_CLASS = "bts-resource-icon" | local RESOURCE_ICON_CLASS = "bts-resource-icon" | ||
local LARGE_ICON_SIZE = "168px" | |||
local MEDIUM_ICON_SIZE = "96px" | |||
local SMALL_ICON_SIZE = "32px" | local SMALL_ICON_SIZE = "32px" | ||
| Line 46: | Line 48: | ||
local function render_icon_markup(building) | local function render_icon_markup(building) | ||
local icon_filename | local icon_filename | ||
local size = LARGE_ICON_SIZE | |||
if building.portrait_icon then | if building.portrait_icon then | ||
icon_filename = building.portrait_icon .. ".png" | icon_filename = building.portrait_icon .. ".png" | ||
elseif building.icon then | |||
icon_filename = building.icon .. ".png" | |||
size = MEDIUM_ICON_SIZE | |||
else | else | ||
return "" | return "" | ||
end | end | ||
local image_markup = "[[File:" .. icon_filename .. "|" .. | local image_markup = "[[File:" .. icon_filename .. "|".. size .. "|" .. building.name .. "|link=]]" | ||
return image_markup | return image_markup | ||
end | end | ||
| Line 75: | Line 79: | ||
---@param building Building | ---@param building Building | ||
local function add_description(div, building) | local function add_description(div, building) | ||
local inner_div = div:tag("div"):addClass(DESCRIPTION_CLASS) | local inner_div = div:tag("div"):addClass(DESCRIPTION_CLASS) | ||
local description = building.description:gsub("<hb>", ""):gsub("</hb>", "") | local description = building.description:gsub("<hb>", ""):gsub("</hb>", "") | ||
| Line 98: | Line 101: | ||
---@param building Building | ---@param building Building | ||
local function add_tech_prerequisite(div, building) | local function add_tech_prerequisite(div, building) | ||
local inner_div = div:tag("div"):addClass(TECH_TREE_CLASS) | local inner_div = div:tag("div"):addClass(TECH_TREE_CLASS) | ||
local check_icon = "[[File:UI teal open checkmark.png|x16px|link=]]" | local check_icon = "[[File:UI teal open checkmark.png|x16px|link=]]" | ||
| Line 138: | Line 140: | ||
---@param building Building | ---@param building Building | ||
local function add_construction(div, building) | local function add_construction(div, building) | ||
local tbl = div:tag("div"):addClass(CONSTRUCTION_CLASS) | local tbl = div:tag("div"):addClass(CONSTRUCTION_CLASS) | ||
:tag("table"):addClass(CONSTRUCTION_TABLE_CLASS) | :tag("table"):addClass(CONSTRUCTION_TABLE_CLASS) | ||
| Line 156: | Line 157: | ||
---@param building Building | ---@param building Building | ||
local function add_tasks(div, building) | local function add_tasks(div, building) | ||
local tbl = div:tag("div"):addClass(TASKS_CLASS) | local tbl = div:tag("div"):addClass(TASKS_CLASS) | ||
:tag("table"):addClass(TASKS_TABLE_CLASS) | :tag("table"):addClass(TASKS_TABLE_CLASS) | ||
| Line 180: | Line 180: | ||
div:addClass(INFOBOX_CLASS) | div:addClass(INFOBOX_CLASS) | ||
add_header(div, building) | add_header(div, building) | ||
add_description(div, building) | if building.description and building.description ~= "" then | ||
add_subheader(div, "Tech tree prerequisite") | add_description(div, building) | ||
end | |||
add_subheader(div, "Construction costs") | if building.tech_tree_previous and building.tech_tree_previous ~= "" then | ||
add_subheader(div, "Tech tree prerequisite") | |||
add_tasks(div, building) | add_tech_prerequisite(div, building) | ||
end | |||
if building.construction_resources and #building.construction_resources > 0 then | |||
add_subheader(div, "Construction costs") | |||
add_construction(div, building) | |||
end | |||
if building.tasks and #building.tasks > 0 then | |||
add_subheader(div, "Work") | |||
add_tasks(div, building) | |||
end | |||
return tostring(div) | return tostring(div) | ||
end | end | ||
| Line 196: | Line 205: | ||
---@return string wikitext | ---@return string wikitext | ||
local function append_wiki_category(wikitext, building) | local function append_wiki_category(wikitext, building) | ||
if | wikitext = wikitext .. "\n[[Category:Buildings]]" | ||
if building.category and building.category ~= "" then | |||
wikitext = wikitext .. "\n[[Category:" .. building.category .. " Buildings]]" | |||
end | |||
return wikitext | |||
end | end | ||
Latest revision as of 00:09, 11 October 2026
Documentation for this module may be created at Module:Building infobox/doc
--[[
Test in Scribunto console with:
=p.render({ args = { page_name = "Ore Smelter" } })
]]--
local p = {}
local Building_Data_Module = require("Module:Building_data")
local Resource_Data_Module = require("Module:Resource_data")
--#region html building helper functions
---@diagnostic disable-next-line: duplicate-doc-alias
---@alias HtmlNode table
local INFOBOX_CLASS = "bts-infobox-building"
local HEADER_CLASS = INFOBOX_CLASS .. "-header"
local HEADER_ICON_CLASS = HEADER_CLASS .. "-icon"
local TITLE_CLASS = INFOBOX_CLASS .. "-title"
local SUBTITLE_CLASS = INFOBOX_CLASS .. "-subtitle"
local SUBHEADER_CLASS = INFOBOX_CLASS .. "-subheader"
local DESCRIPTION_CLASS = INFOBOX_CLASS .. "-description"
local TECH_TREE_CLASS = INFOBOX_CLASS .. "-techtree"
local CONSTRUCTION_CLASS = INFOBOX_CLASS .. "-construction"
local CONSTRUCTION_TABLE_CLASS = CONSTRUCTION_CLASS .. "-table"
local RESOURCE_ICON_CLASS = "bts-resource-icon"
local LARGE_ICON_SIZE = "168px"
local MEDIUM_ICON_SIZE = "96px"
local SMALL_ICON_SIZE = "32px"
local TASKS_CLASS = INFOBOX_CLASS .. "-tasks"
local TASKS_TABLE_CLASS = TASKS_CLASS .. "-table"
--- Renders wikitext for the building's icon.
---@param building Building
---@return string wikitext
local function render_icon_markup(building)
local icon_filename
local size = LARGE_ICON_SIZE
if building.portrait_icon then
icon_filename = building.portrait_icon .. ".png"
elseif building.icon then
icon_filename = building.icon .. ".png"
size = MEDIUM_ICON_SIZE
else
return ""
end
local image_markup = "[[File:" .. icon_filename .. "|".. size .. "|" .. building.name .. "|link=]]"
return image_markup
end
--- Adds the header of the infobox to the provided html node.
---@param div HtmlNode enclosing infobox div
---@param building Building
local function add_header(div, building)
local header = div:tag("div"):addClass(HEADER_CLASS)
header:tag("div"):addClass(TITLE_CLASS):wikitext(building.display_name)
header:tag("div"):addClass(HEADER_ICON_CLASS):wikitext(render_icon_markup(building))
if building.category and building.category ~= "" then
header:tag("div"):addClass(SUBTITLE_CLASS):wikitext(building.category .. " Building")
end
end
--- Adds the building's description to the provided html node.
---@param div HtmlNode enclosing infobox div
---@param building Building
local function add_description(div, building)
local inner_div = div:tag("div"):addClass(DESCRIPTION_CLASS)
local description = building.description:gsub("<hb>", ""):gsub("</hb>", "")
description = description:gsub("\n", "<br />")
inner_div:wikitext(description)
return inner_div
end
--- Adds a subheader to the provided html node.
---@param div HtmlNode enclosing infobox div
---@param text string
local function add_subheader(div, text)
div:tag("div"):addClass(SUBHEADER_CLASS):wikitext(text)
end
--- Adds the building's tech prerequisite to the provided html node.
---@param div HtmlNode enclosing infobox div
---@param building Building
local function add_tech_prerequisite(div, building)
local inner_div = div:tag("div"):addClass(TECH_TREE_CLASS)
local check_icon = "[[File:UI teal open checkmark.png|x16px|link=]]"
local link_markup = check_icon .. " [[" .. Building_Data_Module.get_name_by_id(building.tech_tree_previous) .. "]]"
inner_div:tag("div"):wikitext(link_markup)
end
--- Adds an icon for a resource to the provided html table row.
---@param tr HtmlNode tr
---@param resource Resource
local function add_resource_icon(tr, resource)
local icon_markup = ""
if resource and resource.icon then
local file_name = "File:" .. resource.icon .. ".png"
local icon_size = "x" .. SMALL_ICON_SIZE
local name = resource.display_name
local link_attr = "link=" .. resource.display_name
icon_markup = "[[" .. file_name .. "|" .. icon_size .. "|" .. name .. "|" .. link_attr .. "]]"
end
tr:tag("td"):tag("span"):addClass(RESOURCE_ICON_CLASS)
:wikitext(icon_markup)
end
--- Adds a link for a resource to the provided html table row.
---@param tr HtmlNode tr
---@param resource Resource
local function add_resource_link(tr, resource)
local link_markup = ""
if resource and resource.display_name then
link_markup = "[[" .. resource.display_name .. "]]"
end
tr:tag("td"):wikitext(link_markup)
end
--- Lays out the construction resources in the provided html node.
---@param div HtmlNode enclosing infobox div
---@param building Building
local function add_construction(div, building)
local tbl = div:tag("div"):addClass(CONSTRUCTION_CLASS)
:tag("table"):addClass(CONSTRUCTION_TABLE_CLASS)
for _, pair in ipairs(building.construction_resources) do
local tr = tbl:tag("tr")
tr:tag("td"):wikitext(pair.amount)
local resource = Resource_Data_Module.get_resource(pair.name)
add_resource_icon(tr, resource)
add_resource_link(tr, resource)
end
end
--- Lays out the building's tasks in the provided html node.
---@param div HtmlNode enclosing infobox div
---@param building Building
local function add_tasks(div, building)
local tbl = div:tag("div"):addClass(TASKS_CLASS)
:tag("table"):addClass(TASKS_TABLE_CLASS)
tbl:tag("tr")
:tag("th"):wikitext("Task"):done()
:tag("th"):wikitext("(Time)"):done()
:done()
for _, task in ipairs(building.tasks) do
local tr = tbl:tag("tr")
tr:tag("td"):wikitext(task.task_name)
tr:tag("td"):wikitext("(" .. task.time .. "s)")
end
end
--- Builds the infobox wikitext and html for the given building.
---@param building Building
---@return string wikitext
local function build_infobox(building)
---@type HtmlNode
local div = mw.html.create("div")
div:addClass(INFOBOX_CLASS)
add_header(div, building)
if building.description and building.description ~= "" then
add_description(div, building)
end
if building.tech_tree_previous and building.tech_tree_previous ~= "" then
add_subheader(div, "Tech tree prerequisite")
add_tech_prerequisite(div, building)
end
if building.construction_resources and #building.construction_resources > 0 then
add_subheader(div, "Construction costs")
add_construction(div, building)
end
if building.tasks and #building.tasks > 0 then
add_subheader(div, "Work")
add_tasks(div, building)
end
return tostring(div)
end
--- Appends the wiki category to the provided wikitext.
---@param wikitext string
---@param building Building
---@return string wikitext
local function append_wiki_category(wikitext, building)
wikitext = wikitext .. "\n[[Category:Buildings]]"
if building.category and building.category ~= "" then
wikitext = wikitext .. "\n[[Category:" .. building.category .. " Buildings]]"
end
return wikitext
end
--#endregion
--- `#invoke` entry point. Reads `page_name` from invoke args (not the parent
--- template); falls back to the current page title.
---@param frame table Scribunto frame from `#invoke`.
---@return string wikitext Infobox code or empty string if no building exists.
function p.render(frame)
local args = frame.args or {}
---@type string
local name = args[1] or args.page_name or mw.title.getCurrentTitle().fullText
local building = Building_Data_Module.get_building(name)
if not building then return "" end
local wikitext = build_infobox(building)
wikitext = append_wiki_category(wikitext, building)
return wikitext
end
return p


