Module:Infobox: Difference between revisions

From Against the Storm Official Wiki
(New utility module to make infoboxes consistent. All common elements, like styling, are here.)
 
(Moving common icon size to utility)
Line 54: Line 54:
Infobox.TITLE_WORKPLACES = "Workplaces"
Infobox.TITLE_WORKPLACES = "Workplaces"
Infobox.TITLE_RECIPES = "Recipes"
Infobox.TITLE_RECIPES = "Recipes"
Infobox.ICONSIZE_MED = mw.getCurrentFrame():expandTemplate{ title="ImgM" }


-- Infobox styling
-- Infobox styling

Revision as of 01:03, 28 November 2023

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

---
--- Module to create an infobox for displaying on a workshop's wiki page.
---
--- Shows the facts from the data about the specified workshop in an easy-to-
--- read table, with a large icon, information, categories, and the flavor
--- text.
---
--- This should be invoked from Template:Shopbox with the parameter of the
--- workshop whose infobox should be shown. See the template documentation for
--- more information about parameters and errors and to see examples.
---
--- @module Infobox
local Infobox = {}



local GoodsData = require("Module:GoodsData")



--region Private constants

local RESOURCE_LINK_TEMPLATE = "rl"
local RESOURCE_LINK_ICONSIZE = "med"

local INDEX_REQ_STACK_SIZE= "stackSize"
local INDEX_REQ_GOOD_ID = "goodID"

local BOLD = "'''"

local PATTERN_FORMAT_TWO_DECIMALS = "%1.2f"
local PATTERN_CAPTURE_FIRST_LETTER_IN_WORD = "(%a)([%w]*)"

--endregion



--region Public constants

-- Infobox header labels
Infobox.TITLE_ID = "ID"
Infobox.TITLE_CATEGORY = "Toolbar Category"
Infobox.TITLE_SIZE = "Building Size"
Infobox.TITLE_EATABLE = "Eatable"
Infobox.TITLE_BURNABLE = "Burnable"
Infobox.TITLE_BURN_TIME = "Fuel burn time"
Infobox.TITLE_MOVABLE = "Movable"
Infobox.TITLE_ESSENTIAL = "Initially Essential"
Infobox.TITLE_STORAGE = "Storage Capacity"
Infobox.TITLE_CONSTRUCTION_TIME = "Construction Time"
Infobox.TITLE_CONSTRUCTION_COST = "Construction Cost"
Infobox.TITLE_SELL_VALUE = "Value when sold"
Infobox.TITLE_BUY_VALUE = "Price when bought"
Infobox.TITLE_WORKPLACES = "Workplaces"
Infobox.TITLE_RECIPES = "Recipes"

Infobox.ICONSIZE_MED = mw.getCurrentFrame():expandTemplate{ title="ImgM" }

-- Infobox styling
Infobox.CSS_MAIN = {
	["float"] = "right",
	["clear"] = "right", 
	["width"] = "256px", 
	["border"] = "1px solid #a2a9b1", 
	["border-spacing"] = "3px",
	["border-collapse"] = "collapse",
	["margin"] = "0.5em 0 0.5em 1em"
}

Infobox.CSS_INNER_TABLE = {
	["border-collapse"] = "collapse"
}

Infobox.CSS_TR_BORDER_BOT = {
	["border-bottom"] = "1px solid #a2a9b1"
}

Infobox.CSS_TR_BORDER_TOP = {
	["border-top"] = "1px solid #a2a9b1"
}

-- Infobox icons
Infobox.ICON_FILENAMES_CATEGORIES = {
	-- Buildings
	["City Buildings"] = "Construct City Buildings.png",
	["Food Production"] = "Construct Food Production.png",
	["Industry"] = "Construct Industry.png",
	-- Goods
	["Building Materials"]	= "Icon_UI_CategoryBuilding.png",
	["Consumable Items"]	= "Icon_UI_CategoryConsumable.png",
	["Crafting Resources"]	= "Icon_UI_CategoryCrafting.png",
	["Food"]				= "Icon UI CategoryFood.png",
	["Fuel & Exploration"]	= "Icon_UI_CategoryFuel.png",
	["Trade Goods"]			= "Icon_UI_CategoryTrade.png"
}

--endregion



--region Public methods

---
--- Shortcut string to reformat numbers with two decimals.
---
---@param value number whole or with a fractional part
---@return string reformatted to force two decimal places
function Infobox.toTwoDecimalPlaces(value)

	return string.format(PATTERN_FORMAT_TWO_DECIMALS, value)
end



---
--- Capitalizes the first character of each word to "Make It Title Case." Also
--- converts any underscores to spaces.
---
--- @param title string to capitalize
--- @return string capitalized with title case
function Infobox.toTitleCase(title)

	title = title:gsub("_", " ")

	local newTitle = title:gsub(PATTERN_CAPTURE_FIRST_LETTER_IN_WORD, function(firstLetter, rest)
		return firstLetter:upper() .. rest:lower()
	end)

	return newTitle
end



---
--- A shortcut method for making resource links.
---
---@param goodID string the ID of the good to link to
---@return string wikimarkup representing an icon and link
function Infobox.resourceLink(goodID)

	local goodName = GoodsData.getGoodNameByID(goodID)

	return mw.getCurrentFrame():expandTemplate{ title=RESOURCE_LINK_TEMPLATE, args={
		resource=goodName, iconsize= RESOURCE_LINK_ICONSIZE } }
end



---
--- Shortcut method to build a standard row with a header and a value.
---
---@param htmlNode table the MediaWiki HTML entity to build on
---@param cssInline string inline style to apply
---@param header string header text
---@param value string value text
function Infobox.buildStandardRow(htmlNode, cssInline, header, value)

	htmlNode:tag("tr"):css(cssInline)
			  :tag("th"):wikitext(header):done()
			  :tag("td"):wikitext(value):done()
			  :done():newline()

	return htmlNode
end



---
--- Lays out an inner, no-styling table to display construction goods with
--- their stack sizes.
---
--- @param requiredGoods table of required goods, with stack sizes and IDs
--- @return string wikimarkup for a table of required goods to insert in other markup
function Infobox.writeRequiredGoodsRows(requiredGoods)

	if not requiredGoods or #requiredGoods == 0 then
		error("Cannot write content with provided table of required goods.")
	end

	local requiredGoodsRows =  mw.html.create("table")
	requiredGoodsRows:newline()

	for _, requiredGroup in ipairs(requiredGoods) do

		local stackSize = requiredGroup[INDEX_REQ_STACK_SIZE]
		local goodID = requiredGroup[INDEX_REQ_GOOD_ID]

		requiredGoodsRows:tag("tr")
				:tag("td"):wikitext(BOLD .. stackSize .. BOLD):done()
				:tag("td"):wikitext(resourceLink(goodID)):done()
			:done():newline()
	end

	return requiredGoodsRows
end

--endregion

return Infobox