Module:T-Campaign
Appearance
Documentation for this module may be created at Module:T-Campaign/doc
--[[
* T-Campaign.lua
* Generic campaign template that dynamically loads campaign data from JSON files. This template provides a flexible, data-driven approach to campaign templates without cluttering ConfigRepository. It dynamically generates field definitions based on the JSON structure and renders any campaign content.
*
* Usage: {{#invoke:T-Campaign|render|campaign_name=ASP2025}}
]]
local p = {}
-- Required modules
local Blueprint = require('Module:LuaTemplateBlueprint')
local ErrorHandling = require('Module:ErrorHandling')
local DatasetLoader = require('Module:DatasetLoader')
-- Register the Campaign template with Blueprint
local template = Blueprint.registerTemplate('Campaign', {
features = {
title = true,
fields = true,
categories = true,
errorReporting = true
}
})
-- Dynamic configuration - will be populated based on JSON structure
template.config = {
fields = {}, -- Will be dynamically generated
categories = {
base = {} -- Will be populated dynamically based on campaign
},
constants = {
title = "Campaign Information" -- Default title, can be overridden by JSON
}
}
-- Generic field processor that handles different data types
local function processFieldValue(value)
if type(value) == "table" then
if #value > 0 then
-- Array of values - render as bullet list
return "* " .. table.concat(value, "\n* ")
else
-- Object with key-value pairs - render as sections
local output = {}
for category, content in pairs(value) do
local categoryTitle = "'''" .. category:gsub("^%l", string.upper):gsub("_", " ") .. "'''"
table.insert(output, categoryTitle)
if type(content) == "table" and #content > 0 then
table.insert(output, "* " .. table.concat(content, "\n* "))
else
table.insert(output, tostring(content))
end
end
return table.concat(output, "\n")
end
else
return tostring(value)
end
end
-- Custom preprocessor to load campaign data and generate fields dynamically
Blueprint.addPreprocessor(template, function(template, args)
local campaignName = args.campaign_name
if not campaignName or campaignName == "" then
ErrorHandling.addError(
template._errorContext or ErrorHandling.createContext('T-Campaign'),
'preprocessor',
'No campaign_name provided',
nil,
false
)
return args
end
-- Load campaign data from JSON
local campaignData = DatasetLoader.load('Data:Campaigns/' .. campaignName .. '.json')
if not campaignData then
ErrorHandling.addError(
template._errorContext or ErrorHandling.createContext('T-Campaign'),
'preprocessor',
'Failed to load campaign data for: ' .. campaignName,
nil,
false
)
return args
end
-- Dynamically generate field definitions based on JSON structure
local fields = {}
for key, value in pairs(campaignData) do
-- Skip campaign_name as it's a control parameter
if key ~= "campaign_name" then
-- Create human-readable labels from JSON keys
local label = key:gsub("_", " "):gsub("^%l", string.upper)
table.insert(fields, {key = key, label = label})
end
end
-- Sort fields to ensure consistent ordering
table.sort(fields, function(a, b) return a.key < b.key end)
template.config.fields = fields
-- Override title if provided in JSON
if campaignData.title then
template.config.constants.title = campaignData.title
end
-- Merge campaign data into args for rendering
for k, v in pairs(campaignData) do
args[k] = v
end
-- Add campaign-specific category
template.config.categories.base = {campaignName}
return args
end)
-- Initialize field processors for the template
-- Set up a universal processor that can handle any field type
if not template._processors then
template._processors = {}
end
-- Set up a universal field processor that will be used for all fields
-- This processor will be called by the Blueprint system for each field
template._processors.default = processFieldValue
-- Also set up specific processors for common field patterns
template._processors.title = function(value) return tostring(value) end
template._processors.regions_covered = processFieldValue
template._processors.services_provided = processFieldValue
template._processors.areas_of_expertise = processFieldValue
template._processors.icann_experience = function(value)
if value and value ~= "" then
return tostring(value)
end
return nil -- Don't display empty fields
end
-- Export the render function
function p.render(frame)
return template.render(frame)
end
return p