<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.hoodedhorse.com/Against_the_Storm/index.php?action=history&amp;feed=atom&amp;title=Module%3AOrdersView2</id>
	<title>Module:OrdersView2 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.hoodedhorse.com/Against_the_Storm/index.php?action=history&amp;feed=atom&amp;title=Module%3AOrdersView2"/>
	<link rel="alternate" type="text/html" href="https://wiki.hoodedhorse.com/Against_the_Storm/index.php?title=Module:OrdersView2&amp;action=history"/>
	<updated>2026-10-18T12:15:42Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.5</generator>
	<entry>
		<id>https://wiki.hoodedhorse.com/Against_the_Storm/index.php?title=Module:OrdersView2&amp;diff=11150&amp;oldid=prev</id>
		<title>76561198157077871: Temporary copy of OrdersView for development and testing of filtering by settlement difficulty</title>
		<link rel="alternate" type="text/html" href="https://wiki.hoodedhorse.com/Against_the_Storm/index.php?title=Module:OrdersView2&amp;diff=11150&amp;oldid=prev"/>
		<updated>2025-10-20T06:47:37Z</updated>

		<summary type="html">&lt;p&gt;Temporary copy of OrdersView for development and testing of filtering by settlement difficulty&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;---&lt;br /&gt;
--- Serves the Orders searching template by capturing input and using it to control the display of data.&lt;br /&gt;
---&lt;br /&gt;
---@module OrdersView2&lt;br /&gt;
local OrdersView2 = {}&lt;br /&gt;
&lt;br /&gt;
--region Dependencies&lt;br /&gt;
--- remove this dependency later&lt;br /&gt;
local OrdersData2 = require(&amp;quot;Module:OrdersData2&amp;quot;)&lt;br /&gt;
--endregion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--region Private constants&lt;br /&gt;
&lt;br /&gt;
local DEFAULT_CAPTION = &amp;quot;Orders&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local CLASS_ORDERS_TABLE = &amp;quot;wikitable mw-collapsible table-nobands&amp;quot;&lt;br /&gt;
local CLASS_ORDERS_COLLAPSED = &amp;quot;wikitable mw-collapsible mw-collapsed table-nobands&amp;quot;&lt;br /&gt;
local CLASS_UNSORTABLE = &amp;quot;unsortable&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local ORDER_LINK_ICON_SIZE = &amp;quot;large&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local HEADER_ID = &amp;quot;ID&amp;quot;&lt;br /&gt;
local HEADER_NAME = &amp;quot;Name&amp;quot;&lt;br /&gt;
local HEADER_REQUIREMENTS = &amp;quot;Requirements&amp;quot;&lt;br /&gt;
local HEADER_REWARDS = &amp;quot;Rewards&amp;quot;&lt;br /&gt;
local HEADER_TIER = &amp;quot;Tier&amp;quot;&lt;br /&gt;
local HEADER_TIMED = &amp;quot;Timed Order?&amp;quot;&lt;br /&gt;
local HEADER_TIME_LIMIT = &amp;quot;Time Limit (seconds)&amp;quot;&lt;br /&gt;
local HEADER_DIFFICULTY = &amp;quot;Difficulty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--endregion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--region Public sub-class&lt;br /&gt;
&lt;br /&gt;
--- This subclass should never be created directly, but only via the constructFromTemplateFrame method, to ensure data integrity and minimize chance for errors.&lt;br /&gt;
OrdersView2.ViewParameters = {}&lt;br /&gt;
&lt;br /&gt;
-- Indexes&lt;br /&gt;
local ARG_SHOW_ID = &amp;quot;show_id&amp;quot;&lt;br /&gt;
local ARG_SHOW_TIER = &amp;quot;show_tier&amp;quot;&lt;br /&gt;
local ARG_SHOW_TIMED = &amp;quot;show_timed&amp;quot;&lt;br /&gt;
local ARG_SHOW_TIME_LIMIT = &amp;quot;show_time_limit&amp;quot;&lt;br /&gt;
local ARG_SHOW_DIFFICULTY = &amp;quot;show_difficulty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- Flags&lt;br /&gt;
local ARG_SKIP_FLAG_VALUE = &amp;quot;skip&amp;quot;&lt;br /&gt;
local ARG_SHOW_FLAG_VALUE = &amp;quot;show&amp;quot;&lt;br /&gt;
&lt;br /&gt;
function OrdersView2.ViewParameters.isShowingID(self)&lt;br /&gt;
    return ARG_SHOW_FLAG_VALUE == self[ARG_SHOW_ID]&lt;br /&gt;
end&lt;br /&gt;
function OrdersView2.ViewParameters.isShowingName()&lt;br /&gt;
    return true&lt;br /&gt;
end&lt;br /&gt;
function OrdersView2.ViewParameters.isShowingTier(self)&lt;br /&gt;
    return ARG_SHOW_FLAG_VALUE == self[ARG_SHOW_TIER]&lt;br /&gt;
end&lt;br /&gt;
function OrdersView2.ViewParameters.isShowingTimed(self)&lt;br /&gt;
    return ARG_SHOW_FLAG_VALUE == self[ARG_SHOW_TIMED]&lt;br /&gt;
end&lt;br /&gt;
function OrdersView2.ViewParameters.isShowingTimeLimit(self)&lt;br /&gt;
    return ARG_SHOW_FLAG_VALUE == self[ARG_SHOW_TIME_LIMIT]&lt;br /&gt;
end&lt;br /&gt;
function OrdersView2.ViewParameters.isShowingRequirements()&lt;br /&gt;
    return true&lt;br /&gt;
end&lt;br /&gt;
function OrdersView2.ViewParameters.isShowingRewards()&lt;br /&gt;
    return true&lt;br /&gt;
end&lt;br /&gt;
function OrdersView2.ViewParameters.isShowingDifficulty(self)&lt;br /&gt;
    return ARG_SHOW_FLAG_VALUE == self[ARG_SHOW_DIFFICULTY]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function OrdersView2.ViewParameters.countShownExtraColumns(self)&lt;br /&gt;
&lt;br /&gt;
    local count = 0&lt;br /&gt;
    if self:isShowingID() then&lt;br /&gt;
        count = count + 1&lt;br /&gt;
    end&lt;br /&gt;
    if self:isShowingTier() then&lt;br /&gt;
        count = count + 1&lt;br /&gt;
    end&lt;br /&gt;
    if self:isShowingTimed() then&lt;br /&gt;
        count = count + 1&lt;br /&gt;
    end&lt;br /&gt;
    if self:isShowingTimeLimit() then&lt;br /&gt;
        count = count + 1&lt;br /&gt;
    end&lt;br /&gt;
    if self:isShowingDifficulty() then&lt;br /&gt;
        count = count + 1&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- No matter what, one column.&lt;br /&gt;
    if 0 == count then&lt;br /&gt;
        return 1&lt;br /&gt;
    else&lt;br /&gt;
        return count&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local checkerSwitch = {&lt;br /&gt;
    [HEADER_ID] = OrdersView2.ViewParameters.isShowingID,&lt;br /&gt;
    [HEADER_NAME] = OrdersView2.ViewParameters.isShowingName,&lt;br /&gt;
    [HEADER_TIER] = OrdersView2.ViewParameters.isShowingTier,&lt;br /&gt;
    [HEADER_TIMED] = OrdersView2.ViewParameters.isShowingTimed,&lt;br /&gt;
    [HEADER_REQUIREMENTS] = OrdersView2.ViewParameters.isShowingRequirements,&lt;br /&gt;
    [HEADER_REWARDS] = OrdersView2.ViewParameters.isShowingRewards,&lt;br /&gt;
    [HEADER_TIME_LIMIT] = OrdersView2.ViewParameters.isShowingTimeLimit,&lt;br /&gt;
    [HEADER_DIFFICULTY] = OrdersView2.ViewParameters.isShowingDifficulty,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
---getCheckerMethod&lt;br /&gt;
---@param headerLabel string the label displayed on the table&lt;br /&gt;
---@return function the function to call to see whether that column should be shown&lt;br /&gt;
function OrdersView2.ViewParameters.getCheckerMethod(headerLabel)&lt;br /&gt;
    return checkerSwitch[headerLabel]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---constructViewParametersFromTemplateFrame&lt;br /&gt;
---@param frame table the mediawiki template&amp;#039;s calling frame&lt;br /&gt;
---@return table an instance of the ViewParameters class&lt;br /&gt;
function OrdersView2.constructViewParametersFromTemplateFrame(frame)&lt;br /&gt;
    local newInstance = {}&lt;br /&gt;
    newInstance[ARG_SHOW_ID] = frame.args[ARG_SHOW_ID] or &amp;quot;not by default&amp;quot;&lt;br /&gt;
    newInstance[ARG_SHOW_TIER] = frame.args[ARG_SHOW_TIER] or ARG_SHOW_FLAG_VALUE&lt;br /&gt;
    newInstance[ARG_SHOW_TIMED] = frame.args[ARG_SHOW_TIMED] or ARG_SHOW_FLAG_VALUE&lt;br /&gt;
    newInstance[ARG_SHOW_TIME_LIMIT] = frame.args[ARG_SHOW_TIME_LIMIT] or ARG_SHOW_FLAG_VALUE&lt;br /&gt;
    newInstance[ARG_SHOW_DIFFICULTY] = frame.args[ARG_SHOW_DIFFICULTY] or ARG_SHOW_FLAG_VALUE&lt;br /&gt;
    -- Attach methods to the instance&lt;br /&gt;
    setmetatable(newInstance, { __index = OrdersView2.ViewParameters })&lt;br /&gt;
&lt;br /&gt;
    return newInstance&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--endregion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--region Private member variables&lt;br /&gt;
&lt;br /&gt;
local htmlTable&lt;br /&gt;
&lt;br /&gt;
--endregion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--region Private methods&lt;br /&gt;
&lt;br /&gt;
---createCaptionNode&lt;br /&gt;
---@param captionText string the desired caption&lt;br /&gt;
---@return table the html node of the caption tags&lt;br /&gt;
local function createCaptionNode(captionText)&lt;br /&gt;
&lt;br /&gt;
    captionNode = mw.html.create(&amp;quot;caption&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    if null == captionText or &amp;quot;&amp;quot; == captionText then&lt;br /&gt;
        captionNode:wikitext(DEFAULT_CAPTION)&lt;br /&gt;
    else&lt;br /&gt;
        captionNode:wikitext(captionText)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return captionNode&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---openTable&lt;br /&gt;
---@param caption string the desired caption&lt;br /&gt;
---@return table the complete html node, htmlTable, the class variable&lt;br /&gt;
local function openTable(caption, collapsed)&lt;br /&gt;
&lt;br /&gt;
    htmlTable = mw.html.create(&amp;quot;table&amp;quot;)&lt;br /&gt;
    if collapsed then&lt;br /&gt;
    	htmlTable:addClass(CLASS_ORDERS_COLLAPSED):newline()&lt;br /&gt;
    else&lt;br /&gt;
    	htmlTable:addClass(CLASS_ORDERS_TABLE):newline()&lt;br /&gt;
    end&lt;br /&gt;
    htmlTable:node(createCaptionNode(caption)):newline()&lt;br /&gt;
&lt;br /&gt;
    return htmlTable&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---createHeaderCell&lt;br /&gt;
---@param label string the label to put in the header cell&lt;br /&gt;
---@return table a new html table header cell&lt;br /&gt;
local function createHeaderCell(label)&lt;br /&gt;
&lt;br /&gt;
    local cell = mw.html.create(&amp;quot;th&amp;quot;)&lt;br /&gt;
    cell:wikitext(label)&lt;br /&gt;
&lt;br /&gt;
    -- Assign the methods so they can be chained&lt;br /&gt;
    cell.spanMultipleRows = function(self, rowsToSpan)&lt;br /&gt;
        self:attr({ rowspan=rowsToSpan })&lt;br /&gt;
        return self&lt;br /&gt;
    end&lt;br /&gt;
    cell.makeUnsortable = function(self)&lt;br /&gt;
        self:addClass(CLASS_UNSORTABLE)&lt;br /&gt;
        return self&lt;br /&gt;
    end&lt;br /&gt;
    cell.spanMultipleColumns = function(self, columnsToSpan)&lt;br /&gt;
        self:attr({ colspan=columnsToSpan })&lt;br /&gt;
        return self&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    return cell&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---loopThroughHeaderCells&lt;br /&gt;
---@param row table the html table row node to use&lt;br /&gt;
---@param preconfiguredRowToUse table the row already setup to choose from&lt;br /&gt;
---@param viewParameters table the ViewParameters specified by the author&lt;br /&gt;
---@return table the same row, now with more stuff in it&lt;br /&gt;
local function addAllCellsThatShouldBeShowing(row, preconfiguredRowToUse, viewParameters)&lt;br /&gt;
&lt;br /&gt;
    for _, rowItem in ipairs(preconfiguredRowToUse) do&lt;br /&gt;
        local isShowingIn = OrdersView2.ViewParameters.getCheckerMethod(rowItem.label)&lt;br /&gt;
        if isShowingIn(viewParameters) then&lt;br /&gt;
            row:node(rowItem.cell):newline()&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---addHeaderRow adds header rows to the member variable htmlTable and returns what was added.&lt;br /&gt;
---&lt;br /&gt;
---@param viewParameters table a ViewParameters initialized with its constructor&lt;br /&gt;
---@return table, table the header row added, sometimes a second sub-header row&lt;br /&gt;
local function addHeaderRow(viewParameters)&lt;br /&gt;
&lt;br /&gt;
    -- Configure the options; we&amp;#039;ll figure out which to create in a moment. Separating the setup from the logic makes this significantly easier to read and understand. These cannot be key-value pairs, like [label] = cell, because we have to use numerical indexes to preserve their order.&lt;br /&gt;
    local headersInOrder = {&lt;br /&gt;
        { label = HEADER_ID, cell = createHeaderCell(HEADER_ID) },&lt;br /&gt;
        { label = HEADER_TIER, cell = createHeaderCell(HEADER_TIER) },&lt;br /&gt;
        { label = HEADER_TIMED, cell = createHeaderCell(HEADER_TIMED) },&lt;br /&gt;
        { label = HEADER_TIME_LIMIT, cell = createHeaderCell(HEADER_TIME_LIMIT) },&lt;br /&gt;
        { label = HEADER_NAME, cell = createHeaderCell(HEADER_NAME) },&lt;br /&gt;
        { label = HEADER_DIFFICULTY, cell = createHeaderCell(HEADER_DIFFICULTY):makeUnsortable() },&lt;br /&gt;
        { label = HEADER_REQUIREMENTS, cell = createHeaderCell(HEADER_REQUIREMENTS):makeUnsortable() },&lt;br /&gt;
        { label = HEADER_REWARDS, cell = createHeaderCell(HEADER_REWARDS) }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    -- If there are subheaders, populate two rows then add them to the main htmlTable&lt;br /&gt;
    &lt;br /&gt;
    -- No subheaders, just populate one row then add it to the main htmlTable.&lt;br /&gt;
    local headerRow = mw.html.create(&amp;quot;tr&amp;quot;)&lt;br /&gt;
    headerRow:newline()&lt;br /&gt;
    addAllCellsThatShouldBeShowing(headerRow, headersInOrder, viewParameters)&lt;br /&gt;
&lt;br /&gt;
    htmlTable:node(headerRow):newline()&lt;br /&gt;
&lt;br /&gt;
    return headerRow&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---createDataCell&lt;br /&gt;
---@param label string the label to put in the cell&lt;br /&gt;
---@return table a new html table data cell&lt;br /&gt;
local function createDataCell(label)&lt;br /&gt;
&lt;br /&gt;
    local cell = mw.html.create(&amp;quot;td&amp;quot;)&lt;br /&gt;
    cell:wikitext(label)&lt;br /&gt;
    -- Assign the methods so they can be chained&lt;br /&gt;
    cell.spanMultipleRows = function(self, rowsToSpan)&lt;br /&gt;
        self:attr({ rowspan=rowsToSpan })&lt;br /&gt;
        return self&lt;br /&gt;
    end&lt;br /&gt;
    cell.makeUnsortable = function(self)&lt;br /&gt;
        self:addClass(CLASS_UNSORTABLE)&lt;br /&gt;
        return self&lt;br /&gt;
    end&lt;br /&gt;
    cell.spanMultipleColumns = function(self, columnsToSpan)&lt;br /&gt;
        self:attr({ colspan=columnsToSpan })&lt;br /&gt;
        return self&lt;br /&gt;
    end&lt;br /&gt;
    return cell&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---addDataRow&lt;br /&gt;
---@param data table a table of data configured with keys to match the labels in cellsInOrder in this method&lt;br /&gt;
---@param viewParameters table a ViewParameters initialized with its constructor&lt;br /&gt;
---@return table the data row added, sometimes a second sub-header row&lt;br /&gt;
 local function addDataRow(data, viewParameters, rowSpan)&lt;br /&gt;
&lt;br /&gt;
    -- Configure the table; we&amp;#039;ll figure out which to actually show in a moment. Separating the setup from the logic makes this significantly easier to read and understand. These cannot be key-value pairs, like [label] = cell, because we have to use numerical indexes to preserve their order.&lt;br /&gt;
    local cellsInOrder = {}&lt;br /&gt;
&lt;br /&gt;
    if rowSpan &amp;gt; 0 then&lt;br /&gt;
    	cellsInOrder = {&lt;br /&gt;
        { label = HEADER_ID, cell = createDataCell(data[HEADER_ID] or &amp;quot;—&amp;quot;):spanMultipleRows(rowSpan) },&lt;br /&gt;
        { label = HEADER_TIER, cell = createDataCell(data[HEADER_TIER] or &amp;quot;—&amp;quot;):spanMultipleRows(rowSpan) },&lt;br /&gt;
        { label = HEADER_TIMED, cell = createDataCell(data[HEADER_TIMED] or &amp;quot;—&amp;quot;):spanMultipleRows(rowSpan) },&lt;br /&gt;
        { label = HEADER_TIME_LIMIT, cell = createDataCell(data[HEADER_TIME_LIMIT] or &amp;quot;—&amp;quot;):spanMultipleRows(rowSpan) },&lt;br /&gt;
        { label = HEADER_NAME, cell = createDataCell(data[HEADER_NAME] or &amp;quot;—&amp;quot;):spanMultipleRows(rowSpan) },&lt;br /&gt;
        { label = HEADER_DIFFICULTY, cell = createDataCell(data[HEADER_DIFFICULTY] or &amp;quot;—&amp;quot;) },&lt;br /&gt;
        { label = HEADER_REQUIREMENTS, cell = createDataCell(data[HEADER_REQUIREMENTS] or &amp;quot;—&amp;quot;) },&lt;br /&gt;
        { label = HEADER_REWARDS, cell = createDataCell(data[HEADER_REWARDS] or &amp;quot;—&amp;quot;):spanMultipleRows(rowSpan) }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    	cellsInOrder = {&lt;br /&gt;
        { label = HEADER_ID, cell = createDataCell(data[HEADER_ID] or &amp;quot;—&amp;quot;) },&lt;br /&gt;
        { label = HEADER_TIER, cell = createDataCell(data[HEADER_TIER] or &amp;quot;—&amp;quot;) },&lt;br /&gt;
        { label = HEADER_TIMED, cell = createDataCell(data[HEADER_TIMED] or &amp;quot;—&amp;quot;) },&lt;br /&gt;
        { label = HEADER_TIME_LIMIT, cell = createDataCell(data[HEADER_TIME_LIMIT] or &amp;quot;—&amp;quot;) },&lt;br /&gt;
        { label = HEADER_NAME, cell = createDataCell(data[HEADER_NAME] or &amp;quot;—&amp;quot;) },&lt;br /&gt;
        { label = HEADER_DIFFICULTY, cell = createDataCell(data[HEADER_DIFFICULTY] or &amp;quot;—&amp;quot;) },&lt;br /&gt;
        { label = HEADER_REQUIREMENTS, cell = createDataCell(data[HEADER_REQUIREMENTS] or &amp;quot;—&amp;quot;) },&lt;br /&gt;
        { label = HEADER_REWARDS, cell = createDataCell(data[HEADER_REWARDS] or &amp;quot;—&amp;quot;) }&lt;br /&gt;
    }&lt;br /&gt;
    end&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
    local dataRow = mw.html.create(&amp;quot;tr&amp;quot;)&lt;br /&gt;
    dataRow:newline()&lt;br /&gt;
    addAllCellsThatShouldBeShowing(dataRow, cellsInOrder, viewParameters)&lt;br /&gt;
&lt;br /&gt;
    htmlTable:node(dataRow):newline()&lt;br /&gt;
&lt;br /&gt;
    return dataRow&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---addExtraRow&lt;br /&gt;
---@param data table a table of data configured with keys to match the labels in cellsInOrder in this method&lt;br /&gt;
---@return table the data row added, which only includes the difficulty as a separate row&lt;br /&gt;
 local function addExtraRow(data, viewParameters)&lt;br /&gt;
&lt;br /&gt;
    -- Configure the table; we&amp;#039;ll figure out which to actually show in a moment. Separating the setup from the logic makes this significantly easier to read and understand. These cannot be key-value pairs, like [label] = cell, because we have to use numerical indexes to preserve their order.&lt;br /&gt;
    local cellsInOrder = {&lt;br /&gt;
        { label = HEADER_DIFFICULTY, cell = createDataCell(data[HEADER_DIFFICULTY] or &amp;quot;—&amp;quot;) },&lt;br /&gt;
        { label = HEADER_REQUIREMENTS, cell = createDataCell(data[HEADER_REQUIREMENTS] or &amp;quot;—&amp;quot;) },&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    -- If skipping the sources altogether overrides individual column visibility.&lt;br /&gt;
   &lt;br /&gt;
    local dataRow = mw.html.create(&amp;quot;tr&amp;quot;)&lt;br /&gt;
    dataRow:newline()&lt;br /&gt;
    addAllCellsThatShouldBeShowing(dataRow, cellsInOrder, viewParameters)&lt;br /&gt;
&lt;br /&gt;
    htmlTable:node(dataRow):newline()&lt;br /&gt;
&lt;br /&gt;
    return dataRow&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---validateStringData&lt;br /&gt;
---@param stringData string a string to display&lt;br /&gt;
---@return string the same string, or nil if it&amp;#039;s empty&lt;br /&gt;
local function validateStringData(stringData)&lt;br /&gt;
&lt;br /&gt;
	stringData = tostring(stringData)&lt;br /&gt;
    if &amp;quot;&amp;quot; == stringData or &amp;quot; &amp;quot; == stringData then&lt;br /&gt;
        return nil&lt;br /&gt;
    else&lt;br /&gt;
        return stringData&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---validateBooleanData&lt;br /&gt;
---@param booleanData boolean a boolean to display&lt;br /&gt;
---@return boolean the same boolean, or false if it&amp;#039;s anything besides a true value&lt;br /&gt;
local function validateBooleanData(booleanData)&lt;br /&gt;
&lt;br /&gt;
    if true == booleanData or &amp;quot;true&amp;quot; == booleanData then&lt;br /&gt;
        return true&lt;br /&gt;
    else&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---validateNumberData&lt;br /&gt;
---@param numberData number a number to display&lt;br /&gt;
---@return number the same number, or nil if it was invalid or 0&lt;br /&gt;
local function validateNumberData(numberData)&lt;br /&gt;
&lt;br /&gt;
    if type(numberData) ~= &amp;quot;number&amp;quot; then&lt;br /&gt;
        return tonumber(numberData)&lt;br /&gt;
    else&lt;br /&gt;
        if 0 &amp;gt; numberData then&lt;br /&gt;
            return nil&lt;br /&gt;
        else&lt;br /&gt;
            return numberData&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function createOrderLink(id)&lt;br /&gt;
&lt;br /&gt;
    return mw.getCurrentFrame():expandTemplate{&lt;br /&gt;
        title = &amp;quot;ol&amp;quot;,&lt;br /&gt;
        args = { [&amp;quot;id&amp;quot;] = id, [&amp;quot;iconsize&amp;quot;] = ORDER_LINK_ICON_SIZE }&lt;br /&gt;
    }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--endregion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--region Public methods&lt;br /&gt;
&lt;br /&gt;
---startTable&lt;br /&gt;
---@param caption string the desired caption&lt;br /&gt;
---@param viewParameters table a ViewParameters initialized with its constructor&lt;br /&gt;
---@return table an html node, the htmlTable member variable&lt;br /&gt;
function OrdersView2.startTable(caption, viewParameters, collapsed)&lt;br /&gt;
&lt;br /&gt;
    openTable(caption, collapsed)&lt;br /&gt;
    addHeaderRow(viewParameters)&lt;br /&gt;
&lt;br /&gt;
    return htmlTable&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---addRow&lt;br /&gt;
---@param id string the ID of the order&lt;br /&gt;
---@param _ string the name of the order is not actually used, but asked for because the Controller doesn&amp;#039;t need to know&lt;br /&gt;
---@param rarity string the rarity of the order expressed as a string&lt;br /&gt;
---@param description string the description of the order&lt;br /&gt;
---@param isSourceAltar boolean whether the order is acquired at the altar&lt;br /&gt;
---@param isSourceCornerstone boolean whether the order is acquired as a cornerstone&lt;br /&gt;
---@param isSourceOrder boolean whether the order is acquired from orders&lt;br /&gt;
---@param isSourceRelic boolean whether the order is acquired from relics&lt;br /&gt;
---@param isSourceTrader boolean whether the order is acquired from traders&lt;br /&gt;
---@param price number the purchase price at a trader&lt;br /&gt;
---@param viewParameters table a ViewParameters initialized with its constructor&lt;br /&gt;
---@return table an html node, the htmlTable member variable&lt;br /&gt;
function OrdersView2.addRow(id, _, tier, timed, timeLimit, difficulty, requirements, rewards, viewParameters, isExtraRow, rowSpan)&lt;br /&gt;
&lt;br /&gt;
    local data = {&lt;br /&gt;
        [HEADER_ID] = validateStringData(id),&lt;br /&gt;
        ---TODO: change back to createOrderLink once ready&lt;br /&gt;
        [HEADER_NAME] = validateStringData(OrdersData2.getNameByID(id)), --createOrderLink(validateStringData(id)),&lt;br /&gt;
        [HEADER_TIER] = validateStringData(tier),&lt;br /&gt;
        [HEADER_TIMED] = validateStringData(timed),&lt;br /&gt;
        [HEADER_TIME_LIMIT] = validateNumberData(timeLimit),&lt;br /&gt;
        [HEADER_DIFFICULTY] = validateStringData(difficulty),&lt;br /&gt;
        [HEADER_REQUIREMENTS] = validateStringData(requirements),&lt;br /&gt;
        [HEADER_REWARDS] = validateStringData(rewards),&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if isExtraRow then&lt;br /&gt;
		addExtraRow(data, viewParameters)&lt;br /&gt;
	else&lt;br /&gt;
    	addDataRow(data, viewParameters, rowSpan)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return htmlTable&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---finalize&lt;br /&gt;
---@return table the complete html table node, fully rendered&lt;br /&gt;
function OrdersView2.finalize()&lt;br /&gt;
&lt;br /&gt;
    return htmlTable&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--endregion&lt;br /&gt;
&lt;br /&gt;
return OrdersView2&lt;/div&gt;</summary>
		<author><name>76561198157077871</name></author>
	</entry>
</feed>