Module:Buildingbox: Difference between revisions

From Against the Storm Official Wiki
(Created to consolidate repetitive code for different buildings' infobox modules)
 
(Updating to new secondary categories)
 
(9 intermediate revisions by the same user not shown)
Line 1: Line 1:
---
--- Retrieves data for the specified building, resource, perk, etc. and sends the data over to the view, another template.
--- Module to create an infobox for displaying on a building's wiki page.
---
--- Shows the facts from the data about the specified building in an easy-to-
--- read table, with a large icon, information, categories, and the flavor
--- text.
---
--- This should be invoked from Template:Buildingbox with the parameter of the
--- building whose infobox should be shown. See the template documentation for
--- more information about parameters and errors and to see examples.
---
---
--- @module Buildingbox
--- @module Buildingbox
Line 15: Line 6:




local StyleUtils = require("Module:StyleUtils")
--region Dependencies
 
local BuildingDataProxy = require("Module:BuildingDataProxy")
 
local SpecializationsData = mw.loadData("Module:SpecializationsData")
local SpeciesData = mw.loadData("Module:SpeciesData")
local Construction = require("Module:Construction")
local ControllerUtilities = require("Module:ControllerUtilities")


local Infobox = require("Module:Infobox")
local VIEW_TEMPLATE = "Buildingbox/view"
local VIEW_TEMPLATE_SPECIALIZATION_LINK = "Specialization_link/view"
local VIEW_TEMPLATE_SPECIES_LINK = "Species_link/view"
local TEMPLATE_RECIPE = "Recipe"


local WorkshopsData = require("Module:WorkshopsData")
--endregion
local InstitutionsData = require("Module:InstitutionsData")
local CampsData = require("Module:CampsData")
local FarmsData = require("Module:FarmsData")
local CollectorsData = require("Module:CollectorsData")




Line 29: Line 26:
--region Private constants
--region Private constants


local ARGS = {
local ARG_NAME = "name"
["name"] = "name",
 
["purpose"] = "purpose",
local PARAM_TITLE = "title"
["species_preference"] = "species_preference",
local PARAM_SUBTITLE = "subtitle"
["specializations"] = "specializations",
local PARAM_DESCRIPTION = "description"
}
local PARAM_SPECIALIZATION = "specialization"
local PARAM_ICON_FILENAME = "iconfilename"
local PARAM_MOVABLE = "movable"
local PARAM_WORKPLACES = "workplaces"
local PARAM_STORAGE = "storage"
local PARAM_RECIPES = "recipes"
local PARAM_CONSTRUCTION_COST = "construction"
local PARAM_CITY_SCORE = "cityscore"
local PARAM_CONSTRUCTION_TIME = "constructiontime"
local PARAM_CONSTRUCTION_SIZE = "constructionsize"
local PARAM_ID = "id"


--endregion
--endregion
Line 42: Line 49:
--region Private methods
--region Private methods


---
---renderSpecializations takes the ID of a building and looks up its specializations, calls external view templates to convert those specializations into usable content strings for display, and returns those strings concatenated together for display by the calling scope.
--- Shortcut method to expand a template with parameters
---@param frame table the Mediawiki template calling context
---
---@param id string the unique ID of the building
---@param buildingName string the name of the building
---@return string a content string ready for display
---@return string html markup returned by the template
local function renderSpecializations(frame, id)
local function expandRecipeList(buildingName)


return mw.getCurrentFrame():expandTemplate{ title="Recipe", args={
    local listOfSpecializationsAtBuilding = SpecializationsData.buildingSpecializations[id]
building= buildingName, display="list" } }
end


    if not listOfSpecializationsAtBuilding then
        return nil
    end


    local concatenatedStrings = ""
    for _, specializationIndex in ipairs(listOfSpecializationsAtBuilding) do


---
        -- Specialization link first
--- Shortcut method since the size methods return two values.
        local specializationData = SpecializationsData.specializations[specializationIndex]
---
        local specializationString = frame:expandTemplate{
---@param buildingName string the name of the building to check
            title = VIEW_TEMPLATE_SPECIALIZATION_LINK,
---@return number, number the X and Y sizes
            args = {
local function distributeSizes(buildingName)
                ["iconfilename"] = specializationData[SpecializationsData.ICON_FILENAME],
                ["name"] = specializationData[SpecializationsData.NAME],
                ["type"] = specializationData[SpecializationsData.IS_COMFORTABLE] and "Comfort" or "Proficiency",
                ["iconsize"] = "small",
            }, }


local sizeX, sizeY = WorkshopsData.getWorkshopSize(buildingName)
        -- Species link second, but just the icon
if sizeX and sizeY then return sizeX, sizeY end
        local speciesID = specializationData[SpecializationsData.SPECIES]
        local speciesString = frame:expandTemplate{
            title = VIEW_TEMPLATE_SPECIES_LINK,
            args = {
                ["iconfilename"] = SpeciesData.species[speciesID][SpeciesData.ICON_FILENAME] .. ".png",
                ["name"] = SpeciesData.species[speciesID][SpeciesData.NAME],
                ["iconsize"] = "small",
                ["display"] = "notext",
            }, }


sizeX, sizeY = InstitutionsData.getInstitutionSize(buildingName)
        -- Separate multiple entries with line break
if sizeX and sizeY then return sizeX, sizeY end
        if #concatenatedStrings > 1 then
            concatenatedStrings = concatenatedStrings .. "<br />"
        end


sizeX, sizeY = CampsData.getCampSize(buildingName)
        concatenatedStrings = concatenatedStrings .. specializationString .. "&nbsp;" .. speciesString
if sizeX and sizeY then return sizeX, sizeY end
    end


sizeX, sizeY = FarmsData.getFarmSize(buildingName)
    if #concatenatedStrings < 1 then
if sizeX and sizeY then return sizeX, sizeY end
        return "None"
    end


sizeX, sizeY = CollectorsData.getCollectorSize(buildingName)
    return concatenatedStrings
return sizeX, sizeY
end
end






---expandRecipeList
---@param frame table
---@param id table
---@return table
local function expandRecipeList(frame, id)


    local recipeMarkup = frame:expandTemplate{
        title = TEMPLATE_RECIPE,
        args = {
            ["building"] = BuildingDataProxy.getName(id),
            ["display"] = "list",
        }
    }


---
    if recipeMarkup and not string.match(recipeMarkup, "^No recipes found") then
--- Builds using the provided wikiInfobox a few header items.
        return recipeMarkup
---
    else
---@param wikiInfobox table mw.html object into which we're building this
        return ""
---@param buildingName string the name of the building the infobox is about
    end
---@return table the Mediawiki html object into which we've been adding things
local function makeHeaderContent(wikiInfobox, buildingName)
 
-- Grab the data we'll use to populate this.
local description = WorkshopsData.getWorkshopDescription(buildingName)
or InstitutionsData.getInstitutionDescription(buildingName)
or CampsData.getCampDescription(buildingName)
or FarmsData.getFarmDescription(buildingName)
or CollectorsData.getCollectorDescription(buildingName)
local iconFilename = WorkshopsData.getWorkshopIcon(buildingName)
or InstitutionsData.getInstitutionIcon(buildingName)
or CampsData.getCampIcon(buildingName)
or FarmsData.getFarmIcon(buildingName)
or CollectorsData.getCollectorIcon(buildingName)
 
-- Start the header area
local header = Infobox.startNewHeader(wikiInfobox)
 
Infobox.makeTitle(header, buildingName)
Infobox.makeFlavorText(header, description)
Infobox.makeTitleIcon(header, iconFilename)
 
return wikiInfobox
end
end






---transformConstructionCosts
---Gets the construction costs for the specified building and calls the utility function, not as a template, but directly, to build a table from that data directly.
---
---
--- Builds using the provided wikiInfobox a subtable to lay out headers and
---@return string markup for a table of construction goods to display
--- fields.
local function transformConstructionCosts(id)
---
---@param wikiInfobox table mw.html object into which we're building this
---@param buildingName string the name of the good the infobox is about
---@param params table of template parameters
---@return table the Mediawiki html object into which we've been adding things
local function makeInnerContent(wikiInfobox, buildingName, params)


-- Grab the data we'll use to populate this.
    local constructionGoods = BuildingDataProxy.getConstructionCosts(id)
local category = WorkshopsData.getWorkshopCategory(buildingName)
or InstitutionsData.getInstitutionCategory(buildingName)
or CampsData.getCampCategory(buildingName)
or FarmsData.getFarmCategory(buildingName)
or CollectorsData.getCollectorCategory(buildingName)
local recipesTable = WorkshopsData.getAllWorkshopRecipes(buildingName)
or InstitutionsData.getAllInstitutionRecipes(buildingName)
or CampsData.getAllCampRecipes(buildingName)
or FarmsData.getAllFarmRecipes(buildingName)
or CollectorsData.getAllCollectorRecipes(buildingName)
local isMovable = WorkshopsData.isWorkshopMovable(buildingName)
or InstitutionsData.isInstitutionMovable(buildingName)
or CampsData.isCampMovable(buildingName)
or FarmsData.isFarmMovable(buildingName)
or CollectorsData.isCollectorMovable(buildingName)
local isEssential = WorkshopsData.isWorkshopInitiallyEssential(buildingName)
or InstitutionsData.isInstitutionInitiallyEssential(buildingName)
or CampsData.isCampInitiallyEssential(buildingName)
or FarmsData.isFarmInitiallyEssential(buildingName)
or CollectorsData.isCollectorInitiallyEssential(buildingName)
local sizeX, sizeY = distributeSizes(buildingName)
local range = CampsData.getCampArea(buildingName)
-- Workshops and
-- Institutions don't have a range/area
or FarmsData.getFarmArea(buildingName)
-- Collectors don't have a range
local storageCap = WorkshopsData.getWorkshopStorage(buildingName)
-- Institutions don't have storage
or CampsData.getCampStorage(buildingName)
or FarmsData.getFarmStorage(buildingName)
or CollectorsData.getCollectorStorage(buildingName)
local numWorkplaces = WorkshopsData.getWorkshopNumberOfWorkplaces(buildingName)
or InstitutionsData.getInstitutionNumberOfWorkplaces(buildingName)
or CampsData.getCampNumberOfWorkplaces(buildingName)
or FarmsData.getFarmNumberOfWorkplaces(buildingName)
or CollectorsData.getCollectorNumberOfWorkplaces(buildingName)
local constructionTime = WorkshopsData.getWorkshopConstructionTime(buildingName)
or InstitutionsData.getInstitutionConstructionTime(buildingName)
or CampsData.getCampConstructionTime(buildingName)
or FarmsData.getFarmConstructionTime(buildingName)
or CollectorsData.getCollectorConstructionTime(buildingName)
local constructionGoods = WorkshopsData.getAllWorkshopRequiredGoods(buildingName)
or InstitutionsData.getAllInstitutionRequiredGoods(buildingName)
or CampsData.getAllCampRequiredGoods(buildingName)
or FarmsData.getAllFarmRequiredGoods(buildingName)
or CollectorsData.getAllCollectorRequiredGoods(buildingName)
local buildingID = WorkshopsData.getWorkshopID(buildingName)
or InstitutionsData.getInstitutionID(buildingName)
or CampsData.getCampID(buildingName)
or FarmsData.getFarmID(buildingName)
or CollectorsData.getCollectorID(buildingName)


-- Start the inner table
    if not constructionGoods then
local innerTable = Infobox.startNewInnerTable(wikiInfobox)
        return nil
    end


-- we'll reuse this to mark where separators are needed in the table
    return "" .. Construction.makeTableFromData(constructionGoods)
local needsSeparator = false
end


-- Start with the things from the parameters, if any
for paramTitle, paramValue in pairs(params or {}) do
if paramTitle ~= nil and paramValue ~= nil then
Infobox.makeInnerRow(innerTable, paramValue, false,
Infobox.toTitleCase(paramTitle), paramValue)
-- Require a separator if there were any parameters.
needsSeparator = true
end
end


needsSeparator = Infobox.makeInnerRow(innerTable, category, needsSeparator,
---buildViewParameters
Infobox.TITLE_CATEGORY,
---Populates a table of parameters for the view based on building data.
Infobox.makeCategoryIcon(category, false) .. StyleUtils.NBSP .. category)
---
needsSeparator = Infobox.makeInnerRow(innerTable, recipesTable and #recipesTable > 0,
---Leverages the building proxy to federate the query out to the right data model without worrying about which one it's coming from:
needsSeparator, Infobox.TITLE_RECIPES,
--- getCategory
expandRecipeList(buildingName))
--- getCityScore
 
--- getConstructionCosts (as [goodName] = stack size)
needsSeparator = true
--- getConstructionTime
 
--- getDescription
needsSeparator = Infobox.makeInnerRow(innerTable, isMovable, needsSeparator,
--- getIcon
Infobox.TITLE_MOVABLE, isMovable and "Yes" or "No")
--- isMovable
needsSeparator = Infobox.makeInnerRow(innerTable, isEssential, needsSeparator,
--- getName
Infobox.TITLE_ESSENTIAL, isEssential and "Yes" or "No")
--- getNumberOfWorkplaces
needsSeparator = Infobox.makeInnerRow(innerTable, sizeX and sizeY,
--- getSize (as "X x Y")
needsSeparator, Infobox.TITLE_SIZE, sizeX .. " × " .. sizeY)
--- getStorage
needsSeparator = Infobox.makeInnerRow(innerTable, range, needsSeparator,
---
Infobox.TITLE_RANGE, range)
---@param frame table the Mediawiki template calling context
needsSeparator = Infobox.makeInnerRow(innerTable, storageCap, needsSeparator,
---@param name string the name of the building
Infobox.TITLE_STORAGE_CAPACITY, storageCap)
---@return table of arguments for the view template
 
local function buildViewParameters(frame, name)
needsSeparator = true
 
needsSeparator = Infobox.makeInnerRow(innerTable, numWorkplaces, needsSeparator,
Infobox.TITLE_WORKPLACES, numWorkplaces)
 
needsSeparator = true
 
needsSeparator = Infobox.makeInnerRow(innerTable, constructionTime,
needsSeparator, Infobox.TITLE_CONSTRUCTION_TIME,
constructionTime)
needsSeparator = Infobox.makeInnerRow(innerTable, constructionGoods, needsSeparator,
Infobox.TITLE_CONSTRUCTION_COST,
Infobox.writeRequiredGoodsRows(constructionGoods) )
 
needsSeparator = true
 
needsSeparator = Infobox.makeInnerRow(innerTable, buildingID, needsSeparator,
Infobox.TITLE_ID, StyleUtils.ITALIC .. buildingID .. StyleUtils.ITALIC)


-- Close the inner table, and return it with the passed context
    local id = BuildingDataProxy.getID(name)
Infobox.endInnerTable(wikiInfobox, innerTable)
    if not id then
        return nil
    end
   
    local viewParameters = {}
    viewParameters[PARAM_TITLE] = BuildingDataProxy.getName(id)
    viewParameters[PARAM_SUBTITLE] = BuildingDataProxy.getSecondCategory(id) .. "<br />" ..
            "(" .. BuildingDataProxy.getCategory(id) .. ")"
    viewParameters[PARAM_DESCRIPTION] = ControllerUtilities.findAndReplaceSpriteTagsWithFiles(BuildingDataProxy.getDescription(id), frame)
    viewParameters[PARAM_SPECIALIZATION] = renderSpecializations(frame, id)
    viewParameters[PARAM_ICON_FILENAME] = BuildingDataProxy.getIcon(id)
    viewParameters[PARAM_MOVABLE] = BuildingDataProxy.isMovable(id) and "true"
    viewParameters[PARAM_WORKPLACES] = BuildingDataProxy.getNumberOfWorkplaces(id)
    viewParameters[PARAM_RECIPES] = expandRecipeList(frame, id)
    viewParameters[PARAM_STORAGE] = BuildingDataProxy.getStorage(id)
    viewParameters[PARAM_CONSTRUCTION_COST] = transformConstructionCosts(id)
    viewParameters[PARAM_CITY_SCORE] = BuildingDataProxy.getCityScore(id)
    viewParameters[PARAM_CONSTRUCTION_TIME] = BuildingDataProxy.getConstructionTime(id)
    viewParameters[PARAM_CONSTRUCTION_SIZE] = BuildingDataProxy.getSize(id)
    viewParameters[PARAM_ID] = id


return wikiInfobox
    return viewParameters
end
end


Line 244: Line 194:
--region Public methods
--region Public methods


---main
--- For calling from Template:Buildingbox. After handling the frame, forwards control to the primary method, findBoxType, then calls the view template with the compiled box data. Does not interface with any data modules.
---
---
--- Creates an html and wiki markup to display the data in an infobox.
---@param frame table the calling template's context
---
---@return string wiki markup, constructed with the template view
--- @param frame table from template's calling context
function Buildingbox.main(frame)
--- @return string of html and wiki markup
 
function Buildingbox.renderBuildingbox(frame)
    local name = frame.args[ARG_NAME]
    if not name then
-- Every building must have a name.
        error("You must specify the name of the building. Please see the template documentation for how to use the parameters")
local buildingName = frame.args[ARGS.name]
    end
if not buildingName or buildingName == "" then
return "You must specify the name of the building. See [[Template:Buildingbox]] for examples."
end


-- Use this method here to check to see whether the provided name is valid.
    local viewParameters = buildViewParameters(frame, name)
if not ( WorkshopsData.getWorkshopID(buildingName)
    if not viewParameters then
or InstitutionsData.getInstitutionID(buildingName)
        error("No building found with name: " .. name .. ". Please see the template documentation for how to use the parameters")
or CampsData.getCampID(buildingName)
    end
or FarmsData.getFarmID(buildingName)
or CollectorsData.getCollectorID(buildingName) ) then
return "Buildingbox can't find the specified building: " .. buildingName .. "."
end


-- Additional template parameters, may or may not be present.
    -- Return the message if it's a string, otherwise proceed because it's a table.
local purpose = frame.args[ARGS.purpose]
    if type(viewParameters) == "string" then
local speciesPref = frame.args[ARGS.species_preference]
        return viewParameters
local specializations = frame.args[ARGS.specializations]
    end


local wikiInfobox = Infobox.startNewInfobox()
    return frame:expandTemplate{ title = VIEW_TEMPLATE, args = viewParameters }
makeHeaderContent(wikiInfobox, buildingName)
makeInnerContent(wikiInfobox, buildingName,
{ [ARGS.purpose] = purpose, [ARGS.species_preference] = speciesPref,
  [ARGS.specializations] = specializations })
return wikiInfobox
end
end



Latest revision as of 18:57, 10 November 2024

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

--- Retrieves data for the specified building, resource, perk, etc. and sends the data over to the view, another template.
---
--- @module Buildingbox
local Buildingbox = {}



--region Dependencies

local BuildingDataProxy = require("Module:BuildingDataProxy")

local SpecializationsData = mw.loadData("Module:SpecializationsData")
local SpeciesData = mw.loadData("Module:SpeciesData")
local Construction = require("Module:Construction")
local ControllerUtilities = require("Module:ControllerUtilities")

local VIEW_TEMPLATE = "Buildingbox/view"
local VIEW_TEMPLATE_SPECIALIZATION_LINK = "Specialization_link/view"
local VIEW_TEMPLATE_SPECIES_LINK = "Species_link/view"
local TEMPLATE_RECIPE = "Recipe"

--endregion



--region Private constants

local ARG_NAME = "name"

local PARAM_TITLE = "title"
local PARAM_SUBTITLE = "subtitle"
local PARAM_DESCRIPTION = "description"
local PARAM_SPECIALIZATION = "specialization"
local PARAM_ICON_FILENAME = "iconfilename"
local PARAM_MOVABLE = "movable"
local PARAM_WORKPLACES = "workplaces"
local PARAM_STORAGE = "storage"
local PARAM_RECIPES = "recipes"
local PARAM_CONSTRUCTION_COST = "construction"
local PARAM_CITY_SCORE = "cityscore"
local PARAM_CONSTRUCTION_TIME = "constructiontime"
local PARAM_CONSTRUCTION_SIZE = "constructionsize"
local PARAM_ID = "id"

--endregion



--region Private methods

---renderSpecializations takes the ID of a building and looks up its specializations, calls external view templates to convert those specializations into usable content strings for display, and returns those strings concatenated together for display by the calling scope.
---@param frame table the Mediawiki template calling context
---@param id string the unique ID of the building
---@return string a content string ready for display
local function renderSpecializations(frame, id)

    local listOfSpecializationsAtBuilding = SpecializationsData.buildingSpecializations[id]

    if not listOfSpecializationsAtBuilding then
        return nil
    end

    local concatenatedStrings = ""
    for _, specializationIndex in ipairs(listOfSpecializationsAtBuilding) do

        -- Specialization link first
        local specializationData = SpecializationsData.specializations[specializationIndex]
        local specializationString = frame:expandTemplate{
            title = VIEW_TEMPLATE_SPECIALIZATION_LINK,
            args = {
                ["iconfilename"] = specializationData[SpecializationsData.ICON_FILENAME],
                ["name"] = specializationData[SpecializationsData.NAME],
                ["type"] = specializationData[SpecializationsData.IS_COMFORTABLE] and "Comfort" or "Proficiency",
                ["iconsize"] = "small",
            }, }

        -- Species link second, but just the icon
        local speciesID = specializationData[SpecializationsData.SPECIES]
        local speciesString = frame:expandTemplate{
            title = VIEW_TEMPLATE_SPECIES_LINK,
            args = {
                ["iconfilename"] = SpeciesData.species[speciesID][SpeciesData.ICON_FILENAME] .. ".png",
                ["name"] = SpeciesData.species[speciesID][SpeciesData.NAME],
                ["iconsize"] = "small",
                ["display"] = "notext",
            }, }

        -- Separate multiple entries with line break
        if #concatenatedStrings > 1 then
            concatenatedStrings = concatenatedStrings .. "<br />"
        end

        concatenatedStrings = concatenatedStrings .. specializationString .. "&nbsp;" .. speciesString
    end

    if #concatenatedStrings < 1 then
        return "None"
    end

    return concatenatedStrings
end



---expandRecipeList
---@param frame table
---@param id table
---@return table
local function expandRecipeList(frame, id)

    local recipeMarkup = frame:expandTemplate{
        title = TEMPLATE_RECIPE,
        args = {
            ["building"] = BuildingDataProxy.getName(id),
            ["display"] = "list",
        }
    }

    if recipeMarkup and not string.match(recipeMarkup, "^No recipes found") then
        return recipeMarkup
    else
        return ""
    end
end



---transformConstructionCosts
---Gets the construction costs for the specified building and calls the utility function, not as a template, but directly, to build a table from that data directly.
---
---@return string markup for a table of construction goods to display
local function transformConstructionCosts(id)

    local constructionGoods = BuildingDataProxy.getConstructionCosts(id)

    if not constructionGoods then
        return nil
    end

    return "" .. Construction.makeTableFromData(constructionGoods)
end


---buildViewParameters
---Populates a table of parameters for the view based on building data.
---
---Leverages the building proxy to federate the query out to the right data model without worrying about which one it's coming from:
--- getCategory
--- getCityScore
--- getConstructionCosts (as [goodName] = stack size)
--- getConstructionTime
--- getDescription
--- getIcon
--- isMovable
--- getName
--- getNumberOfWorkplaces
--- getSize (as "X x Y")
--- getStorage
---
---@param frame table the Mediawiki template calling context
---@param name string the name of the building
---@return table of arguments for the view template
local function buildViewParameters(frame, name)

    local id = BuildingDataProxy.getID(name)
    if not id then
        return nil
    end
    
    local viewParameters = {}
    viewParameters[PARAM_TITLE] = BuildingDataProxy.getName(id)
    viewParameters[PARAM_SUBTITLE] = BuildingDataProxy.getSecondCategory(id) .. "<br />" ..
            "(" .. BuildingDataProxy.getCategory(id) .. ")"
    viewParameters[PARAM_DESCRIPTION] = ControllerUtilities.findAndReplaceSpriteTagsWithFiles(BuildingDataProxy.getDescription(id), frame)
    viewParameters[PARAM_SPECIALIZATION] = renderSpecializations(frame, id)
    viewParameters[PARAM_ICON_FILENAME] = BuildingDataProxy.getIcon(id)
    viewParameters[PARAM_MOVABLE] = BuildingDataProxy.isMovable(id) and "true"
    viewParameters[PARAM_WORKPLACES] = BuildingDataProxy.getNumberOfWorkplaces(id)
    viewParameters[PARAM_RECIPES] = expandRecipeList(frame, id)
    viewParameters[PARAM_STORAGE] = BuildingDataProxy.getStorage(id)
    viewParameters[PARAM_CONSTRUCTION_COST] = transformConstructionCosts(id)
    viewParameters[PARAM_CITY_SCORE] = BuildingDataProxy.getCityScore(id)
    viewParameters[PARAM_CONSTRUCTION_TIME] = BuildingDataProxy.getConstructionTime(id)
    viewParameters[PARAM_CONSTRUCTION_SIZE] = BuildingDataProxy.getSize(id)
    viewParameters[PARAM_ID] = id

    return viewParameters
end

--endregion



--region Public methods

---main
--- For calling from Template:Buildingbox. After handling the frame, forwards control to the primary method, findBoxType, then calls the view template with the compiled box data. Does not interface with any data modules.
---
---@param frame table the calling template's context
---@return string wiki markup, constructed with the template view
function Buildingbox.main(frame)

    local name = frame.args[ARG_NAME]
    if not name then
        error("You must specify the name of the building. Please see the template documentation for how to use the parameters")
    end

    local viewParameters = buildViewParameters(frame, name)
    if not viewParameters then
        error("No building found with name: " .. name .. ". Please see the template documentation for how to use the parameters")
    end

    -- Return the message if it's a string, otherwise proceed because it's a table.
    if type(viewParameters) == "string" then
        return viewParameters
    end

    return frame:expandTemplate{ title = VIEW_TEMPLATE, args = viewParameters }
end

--endregion

return Buildingbox