Jump to content

Module:TemplateStructure: Difference between revisions

// via Wikitext Extension for VSCode
// via Wikitext Extension for VSCode
Line 44: Line 44:
     table.insert(result, string.format('{| class="%s" %s', tableClass, tableAttrs))
     table.insert(result, string.format('{| class="%s" %s', tableClass, tableAttrs))
      
      
     -- Track errors for debugging
     -- Minimalist error tracking
     local errors = {}
     local errorCount = 0
    local errorData = {}
      
      
     -- Process each block function in the supplied order.
     -- Process each block function in the supplied order
     for i, block in ipairs(blocks) do
     for i, block in ipairs(blocks) do
         if type(block) == "function" then
         if type(block) == "function" then
Line 61: Line 62:
                 end
                 end
             else
             else
                 -- Record error
                 -- Record error with minimal data
                 table.insert(errors, {
                 errorCount = errorCount + 1
                    blockIndex = i,
                 errorData["block-" .. i] = tostring(blockOutput)
                    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 we shouldn't continue on error, break the loop
Line 76: Line 72:
             end
             end
         else
         else
             -- Add warning for non-function blocks
             -- Non-function blocks are silently skipped in minimalist mode
             table.insert(result, "<!-- WARNING COMMENT: Block #" .. i .. " is not a function and will be skipped. -->")
             -- No warning comment needed
         end
         end
     end
     end
Line 84: Line 80:
     table.insert(result, "|}")
     table.insert(result, "|}")
      
      
     -- Add error debug comments if any errors occurred
     -- Add minimal error information using data attributes
     if #errors > 0 then
     if errorCount > 0 then
         local errorOutput = {"<!-- TEMPLATE_STRUCTURE_DEBUG: errors=" .. #errors}
        -- Build data attributes
         for i, err in ipairs(errors) do
         local attrStr = ' data-structure-error="1"'
             table.insert(errorOutput, " E" .. i .. "=Block" .. err.blockIndex .. ":" .. tostring(err.error))
        attrStr = attrStr .. ' data-error-count="' .. errorCount .. '"'
       
        -- Add each error
         for key, value in pairs(errorData) do
             attrStr = attrStr .. ' data-error-' .. key .. '="' .. value .. '"'
         end
         end
         table.insert(errorOutput, " -->")
          
         table.insert(result, table.concat(errorOutput, ""))
        -- Add hidden div with error data
         table.insert(result, string.format('<div style="display:none"%s></div>', attrStr))
     end
     end
      
      

Revision as of 05:35, 11 April 2025

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))
    
    -- Minimalist error tracking
    local errorCount = 0
    local errorData = {}
    
    -- 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 with minimal data
                errorCount = errorCount + 1
                errorData["block-" .. i] = tostring(blockOutput)
                
                -- If we shouldn't continue on error, break the loop
                if not continueOnError then
                    break
                end
            end
        else
            -- Non-function blocks are silently skipped in minimalist mode
            -- No warning comment needed
        end
    end
    
    -- Close the table
    table.insert(result, "|}")
    
    -- Add minimal error information using data attributes
    if errorCount > 0 then
        -- Build data attributes
        local attrStr = ' data-structure-error="1"'
        attrStr = attrStr .. ' data-error-count="' .. errorCount .. '"'
        
        -- Add each error
        for key, value in pairs(errorData) do
            attrStr = attrStr .. ' data-error-' .. key .. '="' .. value .. '"'
        end
        
        -- Add hidden div with error data
        table.insert(result, string.format('<div style="display:none"%s></div>', attrStr))
    end
    
    local finalOutput = table.concat(result, "\n")
    return trim(finalOutput)
end

return p