Module:T-Process: Difference between revisions

// via Wikitext Extension for VSCode
// via Wikitext Extension for VSCode
 
(86 intermediate revisions by the same user not shown)
Line 1: Line 1:
--Module:T-Process
--Module:T-Process
-- Renders the Process template for governance processes and initiatives, making use of ICANNWiki's "Template Blueprint Framework"
-- Makes use of ICANNWiki's "Template Blueprint Framework" to render the "Process" template


local p = {}
local p = {}


-- ========== Required modules ==========
-- ==================== Required modules ====================
local Blueprint = require('Module:LuaTemplateBlueprint')
local Blueprint = require('Module:LuaTemplateBlueprint')
local ErrorHandling = require('Module:ErrorHandling')
local ErrorHandling = require('Module:ErrorHandling')
local ConfigRepository = require('Module:ConfigRepository')
local LinkParser = require('Module:LinkParser')
local LinkParser = require('Module:LinkParser')
local ElementNavigation = require('Module:ElementNavigation')


-- Blueprint default: Module-level cache for lazy-loaded modules
-- ==================== Helper Functions ====================
local moduleCache = {}
-- Blueprint default: Create error context for the module
 
-- Blueprint default: Lazy module loader
local function lazyRequire(moduleName)
    return function()
        if not moduleCache[moduleName] then
            moduleCache[moduleName] = require(moduleName)
        end
        return moduleCache[moduleName]
    end
end
 
-- Lazy load modules that might not be needed immediately
local getTemplateHelpers = lazyRequire('Module:TemplateHelpers')
 
-- ========== Helper Functions ==========
-- Create error context for the module
local errorContext = ErrorHandling.createContext("T-Process")
local errorContext = ErrorHandling.createContext("T-Process")


Line 37: Line 19:
local template = Blueprint.registerTemplate('Process', {
local template = Blueprint.registerTemplate('Process', {
     features = {
     features = {
        -- Core rendering features
         title = true,
         title = true,
         logo = true,
         logo = true,
         fields = true,
         fields = true,
        navigation = true, -- Navigation feature for previous/next processes
         socialMedia = true,
         socialMedia = true,
       
        -- Semantic features
         semanticProperties = true,
         semanticProperties = true,
         categories = true,
         categories = true,
       
         errorReporting = true,
        -- Error handling
        navigation = true
         errorReporting = true
    },
   
    -- Add navigation to block sequence (after fields, before socialMedia)
    blockSequence = {
        'title',
        'logo',
        'fields',
        'navigation',  -- Navigation block
        'socialMedia',
        'semanticProperties',
        'categories',
        'errors'
     }
     }
})
})


-- Initialize the standard configuration
-- Blueprint default: Initialize standard configuration
Blueprint.initializeConfig(template)
Blueprint.initializeConfig(template)


-- Register navigation block
-- CONTROL THE VISUAL ORDER THAT EACH ASPECT IS RENDERED IN
template._blocks = template._blocks or {}
template.config.blockSequence = {
template._blocks.navigation = {
     'title',
     feature = 'navigation',
     'logo',
     render = function(template, args)
    'fields',
        -- Get configuration from template
    'navigation',
        local config = template.config.navigation or {}
    'socialMedia',
       
    'semanticProperties',
        -- Get field names
    'categories',
        local prevField = config.prevField or "has_previous"
     'errors'
        local nextField = config.nextField or "has_next"
       
        -- Check for user-provided navigation values
        local hasPrev = args[prevField]
        local hasNext = args[nextField]
       
        -- If no navigation is provided at all, return empty string
        if (not hasPrev or hasPrev == "") and (not hasNext or hasNext == "") then
            return ""
        end
       
        -- Determine previous and next pages
        local prevPage = hasPrev and hasPrev ~= "" and hasPrev ~= "yes" and hasPrev ~= "true" and hasPrev or nil
        local nextPage = hasNext and hasNext ~= "" and hasNext ~= "yes" and hasNext ~= "true" and hasNext or nil
       
        -- If no actual navigation links were found, return empty string
        if not prevPage and not nextPage then
            return ""
        end
       
        -- Get styling options
        local prevClass = "process-navigation-prev"
        local nextClass = "process-navigation-next"
        local prevLabel = config.prevLabel or "← Previous Process"
        local nextLabel = config.nextLabel or "Next Process →"
        local rowHeight = "40"
       
        -- Create navigation row
        local output = {
            '|-',
            '| class="' .. prevClass .. '" height="' .. rowHeight .. '" valign="middle" |'
        }
       
        -- Add previous link
        if prevPage then
            table.insert(output, string.format(
                '<div class="process-nav-prev">[[%s|%s]]</div>',
                prevPage, prevLabel
            ))
        else
            table.insert(output, "&nbsp;")
        end
       
        -- Add next link cell
        table.insert(output, '| class="' .. nextClass .. '" height="' .. rowHeight .. '" valign="middle" |')
       
        if nextPage then
            table.insert(output, string.format(
                '<div class="process-nav-next">[[%s|%s]]</div>',
                nextPage, nextLabel
            ))
        else
            table.insert(output, "&nbsp;")
        end
       
        return table.concat(output, "\n")
     end
}
}


-- Add navigation configuration
-- ================================================================================
template.config.navigation = {
 
    autoDetect = false,  -- Disable automatic detection - navigation is always editor-specified
-- TEMPLATE-SPECIFIC CALLS AND CODE
    prevField = "has_previous",
    nextField = "has_next",
    prevLabel = "← Previous Process",
    nextLabel = "Next Process →"
}


-- Add title block configuration to use the correct CSS class
-- ELEMENT:NAVIGATION
template.config.meta = template.config.meta or {}
if template.features.navigation then
template.config.meta.titleOptions = {
    local ElementNavigation = ErrorHandling.safeRequire(errorContext, 'Module:ElementNavigation', false)
    cssClass = "template-title template-title-process"
    if ElementNavigation and ElementNavigation.elementName then
}
        Blueprint.registerElement(ElementNavigation.elementName, ElementNavigation)
Blueprint.addElementToTemplate(template, 'navigation')
        template.config.navigation = {
            prevLabel = "← %s",
            nextLabel = "%s →",
            classPrefix = "process"
        }
    end
end


-- ================================================================================
-- ================================================================================


-- ========== Preprocessors ==========
-- ==================== Preprocessors ====================
-- Standard preprocessors - use built-in ones first
-- Basic preprocessors
Blueprint.addPreprocessor(template, 'setPageIdField')
Blueprint.addPreprocessor(template, 'setPageIdField') -- Blueprint default
Blueprint.addPreprocessor(template, 'deriveRegionFromCountry')
Blueprint.addPreprocessor(template, 'deriveRegionFromCountry')


-- Preprocessor for semantic property extraction
-- ==================== Main Render Function ====================
Blueprint.addPreprocessor(template, function(template, args)
-- Blueprint default: Render
    local TemplateHelpers = getTemplateHelpers()
   
    -- Extract plain text from wiki links for has_previous and has_next
    args._semanticPrecededBy = TemplateHelpers.extractSemanticValue(args.has_previous, "Preceded By", errorContext)
    args._semanticSucceededBy = TemplateHelpers.extractSemanticValue(args.has_next, "Succeeded By", errorContext)
   
    return args
end)
 
-- Configure semantic properties to use extracted values
template.config.semantics = template.config.semantics or {}
template.config.semantics.properties = template.config.semantics.properties or {}
template.config.semantics.properties["Preceded by process"] = "_semanticPrecededBy"
template.config.semantics.properties["Succeeded by process"] = "_semanticSucceededBy"
 
-- ========== Main Render Function ==========
-- Main render function which delegates to the template's render method
function p.render(frame)
function p.render(frame)
     return ErrorHandling.protect(
     return ErrorHandling.protect(