Module:Goodbox: Difference between revisions
From Against the Storm Official Wiki
m added margin around infobox |
Refactoring to use the new getters instead of storing the whole record and worrying about indexes. |
||
| Line 1: | Line 1: | ||
--- | --- | ||
-- Module to create infobox for displaying on a good's wiki page. | --- Module to create an infobox for displaying on a good's wiki page. | ||
-- | --- | ||
-- @module | --- Shows the facts from the data about the specified good in an easy-to-read | ||
--- table, with a large icon, information, categories, and the flavor text. | |||
--- | |||
--- This should be invoked from Template:Goodbox with the parameter of the | |||
--- good whose infobox should be shown, for example, with {{PAGENAME}}. | |||
--- | |||
--- @module Goodbox | |||
local Goodbox = {} | local Goodbox = {} | ||
local GoodsData = require("Module:GoodsData") | local GoodsData = require("Module:GoodsData") | ||
-- | |||
--region Private constants | |||
local ARG_GOOD_NAME = "name" | local ARG_GOOD_NAME = "name" | ||
local ARG_GOOD_PURPOSE = "purpose" | local ARG_GOOD_PURPOSE = "purpose" | ||
local ARG_GOOD_SPECIES_PREF = "species_preference" | local ARG_GOOD_SPECIES_PREF = "species_preference" | ||
local TITLE_ID = "ID" | local TITLE_ID = "ID" | ||
local TITLE_CATEGORY = "Inventory Category" | local TITLE_CATEGORY = "Inventory Category" | ||
local TITLE_EATABLE = "Eatable" | |||
local TITLE_EATABLE = " | local TITLE_BURNABLE = "Burnable" | ||
local TITLE_BURNABLE = " | |||
local TITLE_BURN_TIME = "Fuel burn time" | local TITLE_BURN_TIME = "Fuel burn time" | ||
local TITLE_SELL_VALUE = "Value when sold" | local TITLE_SELL_VALUE = "Value when sold" | ||
| Line 42: | Line 36: | ||
local PATTERN_FORMAT_TWO_DECIMALS = "%1.2f" | local PATTERN_FORMAT_TWO_DECIMALS = "%1.2f" | ||
local NBSP = " " | local NBSP = " " | ||
local | local WIKIMARKUP_MED_ICON = "|32px|alt=" | ||
local | local ICON_FILENAMES_CATEGORIES = { | ||
["Building Materials"] = "Icon_UI_CategoryBuilding.png", | ["Building Materials"] = "Icon_UI_CategoryBuilding.png", | ||
["Consumable Items"] = "Icon_UI_CategoryConsumable.png", | ["Consumable Items"] = "Icon_UI_CategoryConsumable.png", | ||
["Crafting Resources"] = "Icon_UI_CategoryCrafting.png", | ["Crafting Resources"] = "Icon_UI_CategoryCrafting.png", | ||
["Food"] = "Icon UI CategoryFood.png", | ["Food"] = "Icon UI CategoryFood.png", | ||
["Fuel & Exploration"] = "Icon_UI_CategoryFuel.png", | ["Fuel & Exploration"] = "Icon_UI_CategoryFuel.png", | ||
["Trade Goods"] = "Icon_UI_CategoryTrade.png" | ["Trade Goods"] = "Icon_UI_CategoryTrade.png" | ||
} | } | ||
| Line 65: | Line 58: | ||
} | } | ||
local CSS_BOTTOM_BORDER_INLINE_STYLE = { | |||
["border-bottom"] = "1px solid #a2a9b1" | |||
} | |||
--endregion | |||
--region Private methods | |||
--- | --- | ||
-- | --- Builds using the provided wikiInfobox a subtable to lay out headers and | ||
-- | --- fields. | ||
-- @param | --- | ||
-- @ | ---@param wikiInfobox table mw.html object into which we're building this | ||
---@param goodName string the name of the good the infobox is about | |||
---@param purpose string the parameter provided to the template | |||
---@param speciesPref string the parameter provided to the template | |||
function makeInnerTable(wikiInfobox, goodName, purpose, speciesPref) | |||
-- Grab the data we'll use to populate this. | |||
local goodID = GoodsData.getGoodID(goodName) | |||
local goodCategory = GoodsData.getGoodCategory(goodName) | |||
local goodIsEatable = GoodsData.isGoodEatable(goodName) | |||
local goodIsBurnable = GoodsData.isGoodBurnable(goodName) | |||
local goodBurnTime = GoodsData.getGoodBurnTime(goodName) | |||
local goodSellValue, goodBuyValue = GoodsData.getGoodValue(goodName) | |||
local categoryIcon | |||
-- | -- Start the inner table | ||
local | |||
local goodIsEatable = | |||
local goodIsBurnable = | |||
local goodBurnTime = | |||
local goodSellValue | |||
-- | |||
local innerTable = wikiInfobox:tag("tr"):tag("td"):tag("table") | local innerTable = wikiInfobox:tag("tr"):tag("td"):tag("table") | ||
innerTable:newline() | innerTable:newline() | ||
-- Start with the things not provided by the data. | |||
if purpose and purpose ~= "" then | if purpose and purpose ~= "" then | ||
innerTable:tag("tr"):tag("th"):wikitext(toTitleCase(ARG_GOOD_PURPOSE)):done() | innerTable:tag("tr") | ||
:tag("th"):wikitext(toTitleCase(ARG_GOOD_PURPOSE)):done() | |||
:tag("td"):wikitext(purpose):done() | |||
:done():newline() | |||
end | end | ||
if speciesPref and speciesPref ~= "" then | if speciesPref and speciesPref ~= "" then | ||
innerTable:tag("tr"):tag("th"):wikitext(toTitleCase(ARG_GOOD_SPECIES_PREF)):done() | innerTable:tag("tr"):css(CSS_BOTTOM_BORDER_INLINE_STYLE) | ||
:tag("th"):wikitext(toTitleCase(ARG_GOOD_SPECIES_PREF)):done() | |||
:tag("td"):wikitext(speciesPref):done() | |||
:done():newline() | |||
end | end | ||
-- | -- Inventory category (this is the same as the subtitle for now) | ||
if goodCategory then | if goodCategory then | ||
categoryIcon = "[[File:" .. ICON_FILENAMES_CATEGORIES[goodCategory] .. WIKIMARKUP_MED_ICON .. goodCategory .. "]]" | |||
innerTable:tag("tr"):tag("th"):wikitext(TITLE_CATEGORY):done() | innerTable:tag("tr"):css(CSS_BOTTOM_BORDER_INLINE_STYLE) | ||
:tag("th"):wikitext(TITLE_CATEGORY):done() | |||
:tag("td"):wikitext(categoryIcon .. NBSP .. goodCategory):done() | |||
:done():newline() | |||
end | end | ||
-- | -- Uses | ||
if goodIsEatable then | |||
innerTable:tag("tr") | |||
:tag("th"):wikitext(TITLE_EATABLE):done() | |||
:tag("td"):wikitext(goodIsEatable and "Yes" or "No"):done() | |||
:done():newline() | |||
end | end | ||
if goodIsBurnable then | |||
innerTable:tag("tr") | |||
:tag("th"):wikitext(TITLE_BURNABLE):done() | |||
:tag("td"):wikitext(goodIsBurnable and "Yes" or "No"):done() | |||
:done():newline() | |||
end | |||
if goodIsBurnable and goodBurnTime then | |||
innerTable:tag("tr"):css(CSS_BOTTOM_BORDER_INLINE_STYLE) | |||
:tag("th"):wikitext(TITLE_BURN_TIME):done() | |||
:tag("td"):wikitext(goodBurnTime):done() | |||
:done():newline() | |||
end | |||
-- Trade values. | |||
if goodSellValue then | if goodSellValue then | ||
innerTable:tag("tr"):tag("th"):wikitext(TITLE_SELL_VALUE):done() | innerTable:tag("tr") | ||
:tag("th"):wikitext(TITLE_SELL_VALUE):done() | |||
:tag("td"):wikitext(toDecimal(goodSellValue)):done() | |||
:done():newline() | |||
end | end | ||
if goodBuyValue then | if goodBuyValue then | ||
innerTable:tag("tr"):tag("th"):wikitext(TITLE_BUY_VALUE):done() | innerTable:tag("tr"):css(CSS_BOTTOM_BORDER_INLINE_STYLE) | ||
:tag("th"):wikitext(TITLE_BUY_VALUE):done() | |||
:tag("td"):wikitext(toDecimal(goodBuyValue)):done() | |||
:done():newline() | |||
end | end | ||
-- End with the ID. | |||
if goodID then | if goodID then | ||
innerTable:tag("tr"):tag("th"):wikitext(TITLE_ID):done() | innerTable:tag("tr") | ||
:tag("th"):wikitext(TITLE_ID):done() | |||
:tag("td"):wikitext("\'" .. goodID .. "\'"):done() | |||
:done():newline() | |||
end | end | ||
-- Close the table. | |||
innerTable:done() | innerTable:done() | ||
-- Close the table cell and row the inner table is in. | |||
wikiInfobox:done():done():newline() | wikiInfobox:done():done():newline() | ||
end | end | ||
--endregion | |||
--region Public methods | |||
--- | |||
--- Creates an html html and wiki markup to display the data in an infobox. | |||
--- | --- | ||
- | --- @param frame table from template's calling context | ||
--- @return string of html and wiki markup | |||
function Goodbox.infobox(frame) | |||
-- @param | |||
-- @return | |||
function | |||
local | -- Every good must have a name. | ||
local goodName = frame.args[ARG_GOOD_NAME] | |||
if not goodName or goodName == "" then | |||
return "You must specify the name of the good. See [[Template:Goodbox]] for examples." | |||
end | |||
if | -- Additional template parameters, may or may not be present | ||
local purpose = frame.args[ARG_GOOD_PURPOSE] | |||
local speciesPref = frame.args[ARG_GOOD_SPECIES_PREF] | |||
-- Get the data. | |||
local goodDescription = GoodsData.getGoodDescription(goodName) | |||
local goodCategory = GoodsData.getGoodCategory(goodName) | |||
local goodIconFilename = GoodsData.getGoodIcon(goodName) | |||
-- Make the top of the infobox that every item has. | |||
wikiInfobox = mw.html.create("table"):css(CSS_INFOBOX_INLINE_STYLE_TABLE) | |||
-- with a title | |||
wikiInfobox:tag("tr") | |||
:tag("td"):wikitext(goodName):done() | |||
:done():newline() | |||
-- and a subtitle, showing the category | |||
if goodCategory then | |||
wikiInfobox:tag("tr") | |||
:tag("td"):wikitext(goodCategory):done() | |||
:done():newline() | |||
end | |||
-- and a large icon. | |||
if goodIconFilename then | |||
wikiInfobox:tag("tr") | |||
:tag("td"):wikitext("[[File:" .. goodIconFilename .. "]]"):done() | |||
:done():newline() | |||
wikiInfobox:tag("tr"):css(CSS_BOTTOM_BORDER_INLINE_STYLE) | |||
:tag("td"):wikitext(goodName .. ", as seen in-game"):done() | |||
:done():newline() | |||
end | end | ||
if | makeInnerTable(wikiInfobox, goodName, purpose, speciesPref) | ||
-- Finish with the flavor text. | |||
if goodDescription then | |||
wikiInfobox:tag("tr") | |||
:tag("td"):wikitext(goodDescription):done() | |||
:done():newline() | |||
end | end | ||
return | wikiInfobox.allDone() | ||
return wikiInfobox | |||
end | end | ||
Revision as of 05:38, 18 November 2023
Documentation for this module may be created at Module:Goodbox/doc
---
--- Module to create an infobox for displaying on a good's wiki page.
---
--- Shows the facts from the data about the specified good in an easy-to-read
--- table, with a large icon, information, categories, and the flavor text.
---
--- This should be invoked from Template:Goodbox with the parameter of the
--- good whose infobox should be shown, for example, with {{PAGENAME}}.
---
--- @module Goodbox
local Goodbox = {}
local GoodsData = require("Module:GoodsData")
--region Private constants
local ARG_GOOD_NAME = "name"
local ARG_GOOD_PURPOSE = "purpose"
local ARG_GOOD_SPECIES_PREF = "species_preference"
local TITLE_ID = "ID"
local TITLE_CATEGORY = "Inventory Category"
local TITLE_EATABLE = "Eatable"
local TITLE_BURNABLE = "Burnable"
local TITLE_BURN_TIME = "Fuel burn time"
local TITLE_SELL_VALUE = "Value when sold"
local TITLE_BUY_VALUE = "Price when bought"
local PATTERN_CAPTURE_BEGINNING_WITHIN_BRACKETS = "^%[(.-)%]"
local PATTERN_CAPTURE_BEGINNING_AFTER_UNDERSCORE = "^_(.-)%s"
local PATTERN_CAPTURE_FIRST_WORD = "^(%w-)%s"
local PATTERN_FORMAT_TWO_DECIMALS = "%1.2f"
local NBSP = " "
local WIKIMARKUP_MED_ICON = "|32px|alt="
local ICON_FILENAMES_CATEGORIES = {
["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"
}
local CSS_INFOBOX_INLINE_STYLE_TABLE = {
["float"] = "right",
["clear"] = "right",
["width"] = "256px",
["border"] = "1px solid #a2a9b1",
["border-spacing"] = "2px",
["margin"] = "0.5em 0 0.5em 1em"
}
local CSS_BOTTOM_BORDER_INLINE_STYLE = {
["border-bottom"] = "1px solid #a2a9b1"
}
--endregion
--region Private methods
---
--- Builds using the provided wikiInfobox a subtable to lay out headers and
--- fields.
---
---@param wikiInfobox table mw.html object into which we're building this
---@param goodName string the name of the good the infobox is about
---@param purpose string the parameter provided to the template
---@param speciesPref string the parameter provided to the template
function makeInnerTable(wikiInfobox, goodName, purpose, speciesPref)
-- Grab the data we'll use to populate this.
local goodID = GoodsData.getGoodID(goodName)
local goodCategory = GoodsData.getGoodCategory(goodName)
local goodIsEatable = GoodsData.isGoodEatable(goodName)
local goodIsBurnable = GoodsData.isGoodBurnable(goodName)
local goodBurnTime = GoodsData.getGoodBurnTime(goodName)
local goodSellValue, goodBuyValue = GoodsData.getGoodValue(goodName)
local categoryIcon
-- Start the inner table
local innerTable = wikiInfobox:tag("tr"):tag("td"):tag("table")
innerTable:newline()
-- Start with the things not provided by the data.
if purpose and purpose ~= "" then
innerTable:tag("tr")
:tag("th"):wikitext(toTitleCase(ARG_GOOD_PURPOSE)):done()
:tag("td"):wikitext(purpose):done()
:done():newline()
end
if speciesPref and speciesPref ~= "" then
innerTable:tag("tr"):css(CSS_BOTTOM_BORDER_INLINE_STYLE)
:tag("th"):wikitext(toTitleCase(ARG_GOOD_SPECIES_PREF)):done()
:tag("td"):wikitext(speciesPref):done()
:done():newline()
end
-- Inventory category (this is the same as the subtitle for now)
if goodCategory then
categoryIcon = "[[File:" .. ICON_FILENAMES_CATEGORIES[goodCategory] .. WIKIMARKUP_MED_ICON .. goodCategory .. "]]"
innerTable:tag("tr"):css(CSS_BOTTOM_BORDER_INLINE_STYLE)
:tag("th"):wikitext(TITLE_CATEGORY):done()
:tag("td"):wikitext(categoryIcon .. NBSP .. goodCategory):done()
:done():newline()
end
-- Uses
if goodIsEatable then
innerTable:tag("tr")
:tag("th"):wikitext(TITLE_EATABLE):done()
:tag("td"):wikitext(goodIsEatable and "Yes" or "No"):done()
:done():newline()
end
if goodIsBurnable then
innerTable:tag("tr")
:tag("th"):wikitext(TITLE_BURNABLE):done()
:tag("td"):wikitext(goodIsBurnable and "Yes" or "No"):done()
:done():newline()
end
if goodIsBurnable and goodBurnTime then
innerTable:tag("tr"):css(CSS_BOTTOM_BORDER_INLINE_STYLE)
:tag("th"):wikitext(TITLE_BURN_TIME):done()
:tag("td"):wikitext(goodBurnTime):done()
:done():newline()
end
-- Trade values.
if goodSellValue then
innerTable:tag("tr")
:tag("th"):wikitext(TITLE_SELL_VALUE):done()
:tag("td"):wikitext(toDecimal(goodSellValue)):done()
:done():newline()
end
if goodBuyValue then
innerTable:tag("tr"):css(CSS_BOTTOM_BORDER_INLINE_STYLE)
:tag("th"):wikitext(TITLE_BUY_VALUE):done()
:tag("td"):wikitext(toDecimal(goodBuyValue)):done()
:done():newline()
end
-- End with the ID.
if goodID then
innerTable:tag("tr")
:tag("th"):wikitext(TITLE_ID):done()
:tag("td"):wikitext("\'" .. goodID .. "\'"):done()
:done():newline()
end
-- Close the table.
innerTable:done()
-- Close the table cell and row the inner table is in.
wikiInfobox:done():done():newline()
end
--endregion
--region Public methods
---
--- Creates an html html and wiki markup to display the data in an infobox.
---
--- @param frame table from template's calling context
--- @return string of html and wiki markup
function Goodbox.infobox(frame)
-- Every good must have a name.
local goodName = frame.args[ARG_GOOD_NAME]
if not goodName or goodName == "" then
return "You must specify the name of the good. See [[Template:Goodbox]] for examples."
end
-- Additional template parameters, may or may not be present
local purpose = frame.args[ARG_GOOD_PURPOSE]
local speciesPref = frame.args[ARG_GOOD_SPECIES_PREF]
-- Get the data.
local goodDescription = GoodsData.getGoodDescription(goodName)
local goodCategory = GoodsData.getGoodCategory(goodName)
local goodIconFilename = GoodsData.getGoodIcon(goodName)
-- Make the top of the infobox that every item has.
wikiInfobox = mw.html.create("table"):css(CSS_INFOBOX_INLINE_STYLE_TABLE)
-- with a title
wikiInfobox:tag("tr")
:tag("td"):wikitext(goodName):done()
:done():newline()
-- and a subtitle, showing the category
if goodCategory then
wikiInfobox:tag("tr")
:tag("td"):wikitext(goodCategory):done()
:done():newline()
end
-- and a large icon.
if goodIconFilename then
wikiInfobox:tag("tr")
:tag("td"):wikitext("[[File:" .. goodIconFilename .. "]]"):done()
:done():newline()
wikiInfobox:tag("tr"):css(CSS_BOTTOM_BORDER_INLINE_STYLE)
:tag("td"):wikitext(goodName .. ", as seen in-game"):done()
:done():newline()
end
makeInnerTable(wikiInfobox, goodName, purpose, speciesPref)
-- Finish with the flavor text.
if goodDescription then
wikiInfobox:tag("tr")
:tag("td"):wikitext(goodDescription):done()
:done():newline()
end
wikiInfobox.allDone()
return wikiInfobox
end
function toDecimal(value)
return string.format(PATTERN_FORMAT_TWO_DECIMALS, value)
end
---
-- Capitalizes the first character of each word.
--
-- @param title the title to capitalize
-- @return the title once capitalized
function toTitleCase(title)
local newTitle = title:gsub("(%a)([%w_']*)", function(first, rest)
return first:upper() .. rest:lower()
end)
newTitle, _ = newTitle:gsub("_", " ")
return newTitle
end
return Goodbox


