Module:Infobox
From Against the Storm Official Wiki
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") local StyleUtils = require("Module:StyleUtils") --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_CAPACITY = "Storage Capacity" Infobox.TITLE_FARMING_AREA = "Farming Area" Infobox.TITLE_GATHERING_AREA = "Gathering Area" 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 ["Camps"] = "Construct Camps.png", ["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 Private methods --- --- Adds a separator if needed. --- ---@param row table html table row we're building ---@param needSeparator boolean whether we need a separator ---@return table the row ---@return boolean whether we still need a separator local function trySeparator(row, needSeparator) if needSeparator then StyleUtils.styleInfoboxSeparator(row) needSeparator = false end return row, needSeparator end --- --- Shortcut method to populate the provided row with a header and a value. --- ---@param htmlRow table the html table row we're populating ---@param header string header text ---@param value string value text ---@return table the same htmlTable local function populateStandardRow(htmlRow, header, value) htmlRow:tag("th"):wikitext(header):done() :tag("td"):wikitext(value):done() :done():newline() return htmlRow end --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 --- --- A shortcut method for looking up an icon and assigning its wiki markup. --- ---@param category string the category of the icon to make ---@return string the wiki markup for the icon function Infobox.makeCategoryIcon(category) return "[[File:" .. Infobox.ICON_FILENAMES_CATEGORIES[category] .. "|" .. Infobox.ICONSIZE_MED .. "|alt=" .. category .. "]]" end --- --- A shortcut method for making a standard title. --- ---@param parentNode table the html node to add to ---@param title string the title to write ---@return table the title node added function Infobox.makeTitle(parentNode, title) local p = parentNode:tag("p") StyleUtils.styleInfoboxTitle(p) p:wikitext(title):done():newline() return p end --- --- A shortcut method for adding a description as flavor text. --- ---@param parentNode table the html node to add to ---@param description string the description to write out ---@return table the title node added function Infobox.makeFlavorText(parentNode, description) local p = parentNode:tag("p") StyleUtils.styleInfoboxFlavorText(p) p:wikitext(description):done():newline() return p end --- --- A shortcut method for adding a large icon to the header. --- ---@param parentNode table the html node to add to ---@param iconFilename string the icon to use ---@return table the title node added function Infobox.makeTitleIcon(parentNode, iconFilename) local div = parentNode:tag("div") StyleUtils.styleInfoboxTitleIcon(div) div:wikitext("[[File:" .. iconFilename .. "]]"):done():newline() return div end --- --- A shortcut method to make a table row based on the provided check, also --- checks to see whether it needs to add a separator. --- ---@param parentNode table the html node to add to ---@param check boolean whether the row can be added ---@param needsSeparator boolean whether the row needs a separator before it ---@param header string the header of the row ---@param value string the value of the row ---@return boolean whether the next row still needs a separator before it function Infobox.makeInnerRow(parentNode, check, needsSeparator, header, value) local row if check ~= nil and check ~= "" then row = parentNode:tag("tr") _, needsSeparator = trySeparator(row, needsSeparator) populateStandardRow(row, header, value) end return needsSeparator end --- TODO DELETE THIS because we're not doing inline css anymore --- 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 ---@return table the same htmlTable 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(Infobox.resourceLink(goodID)):done() :done():newline() end return requiredGoodsRows end --- --- Starts off a new infobox. --- --- @return table the html node created function Infobox.startNewInfobox() local wikiInfobox = mw.html.create("div") StyleUtils.styleInfobox(wikiInfobox) return wikiInfobox end --- --- Creates a standard way of displaying the top content of the infobox and --- returns the HTML node. Styles consistently. --- ---@param wikiInfobox table the overall context this is added to ---@return table the html node created function Infobox.startNewHeader(wikiInfobox) local header = wikiInfobox:tag("div") StyleUtils.styleInfoboxHeader(header) return header end --- --- Finalizes the standard top content --- ---@param wikiInfobox table the overall context ---@param header table the header content to add to the outer context function Infobox.endInnerTable(wikiInfobox, header) header:done():newline() return wikiInfobox end --- --- Creates a standard way of displaying rows of headers and values and --- returns the HTML node. Styles consistently. --- ---@param wikiInfobox table the overall context this is added to ---@return table the html node created function Infobox.startNewInnerTable(wikiInfobox) local innerTable = wikiInfobox:tag("table") innerTable = StyleUtils.styleInfoboxInnerTable(innerTable) innerTable.newline() return innerTable end --- --- Finalizes the standard inner display of headers and values. --- ---@param wikiInfobox table the overall context ---@param innerTable table the inner content to add to the outer context function Infobox.endInnerTable(wikiInfobox, innerTable) innerTable:done():newline() return wikiInfobox end --endregion return Infobox