Module:TemplateStructure
Documentation for this module may be created at Module:TemplateStructure/doc
-- Module:TemplateStructure
-- A module for rendering templates using a modular, block-based approach with error handling.
local p = {}
-- Local trim function: removes leading and trailing whitespace.
local function trim(s)
return (s:gsub("^%s+", ""):gsub("%s+$", ""))
end
-- Format block errors for data attribute output
local function formatBlockError(blockIndex, errorMsg)
-- No function body needed - we'll handle this differently
return nil
end
--[[
p.render(args, config)
Renders a table using a modular, block-based approach.
Parameters:
args - Template parameters (passed to each block function)
config - Configuration options:
tableClass: CSS class for the table (default: "template-table")
tableAttrs: Additional table attributes (default: 'cellpadding="2"')
blocks: Functions that generate table rows
Each accepts (args, config) and returns a string
continueOnError: Continue rendering if a block fails (default: true)
Returns:
Wikitext markup for the complete table
]]
function p.render(args, config)
config = config or {}
local tableClass = config.tableClass or "template-table"
local tableAttrs = config.tableAttrs or 'cellpadding="2"'
local blocks = config.blocks or {}
local continueOnError = config.continueOnError
if continueOnError == nil then continueOnError = true end -- Default to true
-- Begin the table markup.
local result = {}
table.insert(result, string.format('{| class="%s" %s', tableClass, tableAttrs))
-- Track errors for debugging
local errors = {}
-- Process each block function in the supplied order.
for i, block in ipairs(blocks) do
if type(block) == "function" then
-- Protect block execution to avoid template failure
local success, blockOutput = pcall(function()
return block(args, config)
end)
if success then
blockOutput = trim(blockOutput)
if blockOutput ~= "" then
table.insert(result, blockOutput)
end
else
-- Record error
table.insert(errors, {
blockIndex = i,
error = blockOutput -- In pcall, error message is returned as second value
})
-- Add error comment
table.insert(result, "<!-- WARNING COMMENT: Block #" .. i .. " failed with error: " .. tostring(blockOutput) .. " -->")
-- If we shouldn't continue on error, break the loop
if not continueOnError then
break
end
end
else
-- Add warning for non-function blocks
table.insert(result, "<!-- WARNING COMMENT: Block #" .. i .. " is not a function and will be skipped. -->")
end
end
-- Close the table
table.insert(result, "|}")
-- Add error debug comments if any errors occurred
if #errors > 0 then
local errorOutput = {"<!-- TEMPLATE_STRUCTURE_DEBUG: errors=" .. #errors}
for i, err in ipairs(errors) do
table.insert(errorOutput, " E" .. i .. "=Block" .. err.blockIndex .. ":" .. tostring(err.error))
end
table.insert(errorOutput, " -->")
table.insert(result, table.concat(errorOutput, ""))
end
local finalOutput = table.concat(result, "\n")
return trim(finalOutput)
end
return p