Jump to content

Module:T-TLD: Difference between revisions

// via Wikitext Extension for VSCode
// via Wikitext Extension for VSCode
 
(23 intermediate revisions by the same user not shown)
Line 6: Line 6:
-- ==================== Required modules ====================
-- ==================== Required modules ====================
local Blueprint = require('Module:LuaTemplateBlueprint')
local Blueprint = require('Module:LuaTemplateBlueprint')
local TemplateHelpers = require('Module:TemplateHelpers')
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')


-- Blueprint default: Module-level cache for lazy-loaded modules
-- Blueprint possible default: Module-level cache for lazy-loaded modules
local moduleCache = {}
local moduleCache = {}


-- Blueprint default: Lazy module loader
-- Blueprint possible default: Lazy module loader
local function lazyRequire(moduleName)
local function lazyRequire(moduleName)
     return function()
     return function()
Line 25: Line 23:


-- Blueprint default: Modules to lazy load
-- Blueprint default: Modules to lazy load
    -- local getTemplateHelpers = lazyRequire('')
local getPunycode = lazyRequire('Module:Punycode')
local getPunycode = lazyRequire('Module:Punycode')
local getCountryData = lazyRequire('Module:CountryData')
local getSemanticCategoryHelpers = lazyRequire('Module:SemanticCategoryHelpers')
local getCanonicalForms = lazyRequire('Module:CanonicalForms')
local getCanonicalForms = lazyRequire('Module:CanonicalForms')


Line 34: Line 29:
-- Blueprint default: Create error context for the module
-- Blueprint default: Create error context for the module
local errorContext = ErrorHandling.createContext("T-TLD")
local errorContext = ErrorHandling.createContext("T-TLD")
-- Blueprint default: Helper for extracting semantic values from wiki links
local function extractSemanticValue(fieldValue, fieldName)
    return TemplateHelpers.extractSemanticValue(fieldValue, fieldName, errorContext)
end


-- ================================================================================
-- ================================================================================
Line 48: Line 38:
         title = true,
         title = true,
         logo = true,
         logo = true,
        tldflair = true,
         fields = true,
         fields = true,
         socialMedia = true,
         socialMedia = true,
        ntldstats = true,
         semanticProperties = true,
         semanticProperties = true,
         categories = true,
         categories = true,
         errorReporting = true,
         errorReporting = true
        tldflair = true,
        ntldstats = true
     }
     }
})
})
Line 96: Line 86:
end
end


-- Custom title row based on whether the TLD is "g" or a "cc"
-- Custom title row based on whether the TLD is a "g" or a "cc"
template.config.blocks = template.config.blocks or {}
template.config.blocks = template.config.blocks or {}
template.config.blocks.title = {
template.config.blocks.title = {
feature = 'title',
    feature = 'title',
render = function(template, args)
    render = function(template, args)
    return Blueprint.protectedExecute(
        return Blueprint.protectedExecute(
        template,
            template,
        'CustomBlock_title',
            'CustomBlock_title',
        function()
            function()
            local titleText = (args._type == 'ccTLD') and 'ccTLD' or 'gTLD'
                local titleText = (args._type == 'ccTLD') and 'ccTLD' or 'gTLD'
            return TemplateHelpers.renderTitleBlock(
                return require('Module:TemplateStructure').renderTitleBlock(
                args,
                    args,
                'template-title template-title-tld',
                    'template-title template-title-tld',
                titleText,
                    titleText
                 template.config.meta and template.config.meta.titleOptions or {}
                 )
             )
             end,
        end,
            '',
        '',
            args
        args
        )
    )
    end
end
}
}


-- PROCESSORS
template.config.processors = template.config.processors or {}
-- PIC/RVC link processor
-- PIC/RVC link processor
template.config.processors.RVC = function(value, args)
template.config.processors.RVC = function(value, args)
     local val = tostring(value)
     local val = tostring(value)
     if val:find("gtldresult.icann.org") then
     if val:match("^https://gtldresult%.icann%.org/") then
        -- Full URL provided, use it directly
         return string.format("[%s Here]", val)
         return string.format("[%s Here]", val)
     elseif val:match("^%d+$") then
     elseif val:match("^%d+$") then
        -- Only application number provided, construct the full URL
         return string.format("[https://gtldresult.icann.org/applicationstatus/applicationdetails/%s Here]", val)
         return string.format("[https://gtldresult.icann.org/applicationstatus/applicationdetails/%s Here]", val)
     end
     end
     return val
     return nil
end
end
template.config.processors.PIC = template.config.processors.RVC


template.config.processors.PIC = template.config.processors.RVC
-- Override singular 'language' field to skip normalization
template.config.processors.language = function(value, args)
    return value
end


-- IDN property provider
-- ================================================================================
Blueprint.registerPropertyProvider(template, function(template, args)
    local props = {}
    if args._idnFlag then props["Is IDN"] = "true" end
    return props
end)


-- IDN detection preprocessor
-- ==================== Preprocessors ====================
-- IDN detection preprocessor - sets idn="true" for boolean transform to handle
local function detectIDNStatus(template, args)
local function detectIDNStatus(template, args)
    args._idnFlag = false
     if args.idn and args.idn ~= '' then
     if args.idn and args.idn ~= '' then
         local idnVal = string.lower(args.idn)
         local idnVal = string.lower(args.idn)
         if idnVal == 'yes' or idnVal == 'true' or idnVal == '1' then
         if idnVal == 'yes' or idnVal == 'true' or idnVal == '1' then
             args._idnFlag = true
            -- Set idn directly to "true" - will be handled by "boolean" transform
             args.idn = "true"
           
            -- Generate ASCII representation for IDN TLDs
             local titleObj = mw.title.getCurrentTitle()
             local titleObj = mw.title.getCurrentTitle()
             local pageName = titleObj and titleObj.text or ''
             local pageName = titleObj and titleObj.text or ''
Line 162: Line 157:
end
end


-- Field Processors
-- Map tld_type to internal _type for title block display logic
template.config.processors = template.config.processors or {}
local function mapTldTypeToInternalType(template, args)
template.config.processors.tld_type = function(value, args)
    return select(1, getCanonicalForms().normalize(value, template.config.mappings.tld_type)) or value
end
template.config.processors.tld_subtype = function(value, args)
    return select(1, getCanonicalForms().normalize(value, template.config.mappings.tld_subtype)) or value
end
template.config.processors.introduced = function(value, args)
    return TemplateHelpers.formatDateRange(value, nil, {outputMode='text'})
end
template.config.processors.implemented = function(value, args)
    return TemplateHelpers.formatDateRange(value, nil, {outputMode='text'})
end
template.config.processors.website = function(value, args)
    return TemplateHelpers.normalizeWebsites(value)
end
template.config.processors.country = function(value, args)
    return TemplateHelpers.normalizeCountries(value)
end
 
-- Category Provider
Blueprint.registerCategoryProvider(template, function(template, args)
    local cats = {}
    local cond = template.config.categories and template.config.categories.conditional or {}
    if cond.rvc and ((args.RVC and args.RVC ~= "") or (args.PIC and args.PIC ~= "")) then
        table.insert(cats, cond.rvc)
    end
    if args._idnFlag and cond.idn then
        table.insert(cats, cond.idn)
    end
    if args._idnFlag and args._type == "ccTLD" and cond.idn_cctld then
        table.insert(cats, cond.idn_cctld)
    end
    -- Type mapping categories
    for _, cat in ipairs(getSemanticCategoryHelpers().addMappingCategories(args._type, template.config.mappings.tld_type) or {}) do
        table.insert(cats, cat)
    end
    -- Subtype mapping categories
    for _, cat in ipairs(getSemanticCategoryHelpers().addMappingCategories(args._type, template.config.mappings.tld_subtype) or {}) do
        table.insert(cats, cat)
    end
    return cats
end)
 
-- ================================================================================
 
-- ==================== Preprocessors ====================
-- Basic preprocessors
Blueprint.addPreprocessor(template, function(template, args)
     if args.tld_type and args.tld_type ~= '' then
     if args.tld_type and args.tld_type ~= '' then
         args._type = select(1, getCanonicalForms().normalize(args.tld_type, template.config.mappings.tld_type)) or args.tld_type
         args._type = select(1, getCanonicalForms().normalize(args.tld_type, template.config.mappings.tld_type)) or args.tld_type
     end
     end
     return args
     return args
end-- Map tld_type to internal _type
end
Blueprint.addPreprocessor(template, detectIDNStatus) -- IDN detection
 
Blueprint.addPreprocessor(template, 'setPageIdField') -- Blueprint default
-- Call preprocessors
-- Blueprint.addPreprocessor(template, 'deriveRegionFromCountry')
Blueprint.addPreprocessor(template, 'setPageIdField') -- Blueprint default
Blueprint.addPreprocessor(template, 'deriveRegionFromCountry') -- Blueprint possible default
Blueprint.addPreprocessor(template, mapTldTypeToInternalType) -- TLD type detection
Blueprint.addPreprocessor(template, detectIDNStatus) -- IDN detection


-- ==================== Main Render Function ====================
-- ==================== Main Render Function ====================

Latest revision as of 22:31, 18 May 2025

Documentation for this module may be created at Module:T-TLD/doc

--Module:T-TLD
-- Makes use of ICANNWiki's "Template Blueprint Framework" to render the "TLD" template

local p = {}

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

-- Blueprint possible default: Module-level cache for lazy-loaded modules
local moduleCache = {}

-- Blueprint possible 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

-- Blueprint default: Modules to lazy load
local getPunycode = lazyRequire('Module:Punycode')
local getCanonicalForms = lazyRequire('Module:CanonicalForms')

-- ==================== Helper Functions ====================
-- Blueprint default: Create error context for the module
local errorContext = ErrorHandling.createContext("T-TLD")

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

-- IMPORTANT! TEMPLATE BLUEPRINT FRAMEWORK INSTRUCTIONS
-- CONTROL OF TEMPLATE FEATURES: THIS LIST SPECIFIES IN AN EXPLICIT MANNER WHAT FEATURES ARE TO BE CALLED/RENDERED BY THE TEMPLATE.
local template = Blueprint.registerTemplate('TLD', {
    features = {
        title = true,
        logo = true,
        tldflair = true,
        fields = true,
        socialMedia = true,
        ntldstats = true,
        semanticProperties = true,
        categories = true,
        errorReporting = true
    }
})

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

-- CONTROL THE VISUAL ORDER THAT EACH ASPECT IS RENDERED IN
template.config.blockSequence = {
    'title',
    'logo',
    'tldflair',
    'fields',
    'socialMedia',
    'ntldstats',
    'semanticProperties',
    'categories',
    'errors'
}

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

-- TEMPLATE-SPECIFIC CALLS AND CODE

-- ELEMENT:TLD FLAIR
if template.features.tldflair then
    local ElementTLDFlair = ErrorHandling.safeRequire(errorContext, 'Module:ElementTLDFlair', false)
    if ElementTLDFlair and ElementTLDFlair.elementName then
        Blueprint.registerElement(ElementTLDFlair.elementName, ElementTLDFlair)
        Blueprint.addElementToTemplate(template, 'tldflair')
    end
end

-- ELEMENT:NTLDSTATS
if template.features.ntldstats then
    local ElementNTLDStats = ErrorHandling.safeRequire(errorContext, 'Module:ElementNTLDStats', false)
    if ElementNTLDStats and ElementNTLDStats.elementName then
        Blueprint.registerElement(ElementNTLDStats.elementName, ElementNTLDStats)
        Blueprint.addElementToTemplate(template, 'ntldstats')
    end
end

-- Custom title row based on whether the TLD is a "g" or a "cc"
template.config.blocks = template.config.blocks or {}
template.config.blocks.title = {
    feature = 'title',
    render = function(template, args)
        return Blueprint.protectedExecute(
            template,
            'CustomBlock_title',
            function()
                local titleText = (args._type == 'ccTLD') and 'ccTLD' or 'gTLD'
                return require('Module:TemplateStructure').renderTitleBlock(
                    args,
                    'template-title template-title-tld',
                    titleText
                )
            end,
            '',
            args
        )
    end
}

-- PROCESSORS
template.config.processors = template.config.processors or {}
-- PIC/RVC link processor
template.config.processors.RVC = function(value, args)
    local val = tostring(value)
    if val:match("^https://gtldresult%.icann%.org/") then
        -- Full URL provided, use it directly
        return string.format("[%s Here]", val)
    elseif val:match("^%d+$") then
        -- Only application number provided, construct the full URL
        return string.format("[https://gtldresult.icann.org/applicationstatus/applicationdetails/%s Here]", val)
    end
    return nil
end
template.config.processors.PIC = template.config.processors.RVC

-- Override singular 'language' field to skip normalization
template.config.processors.language = function(value, args)
    return value
end

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

-- ==================== Preprocessors ====================
-- IDN detection preprocessor - sets idn="true" for boolean transform to handle
local function detectIDNStatus(template, args)
    if args.idn and args.idn ~= '' then
        local idnVal = string.lower(args.idn)
        if idnVal == 'yes' or idnVal == 'true' or idnVal == '1' then
            -- Set idn directly to "true" - will be handled by "boolean" transform
            args.idn = "true"
            
            -- Generate ASCII representation for IDN TLDs
            local titleObj = mw.title.getCurrentTitle()
            local pageName = titleObj and titleObj.text or ''
            local puny = Blueprint.protectedExecute(
                template,
                'IDN_toASCII',
                function()
                    return getPunycode().encode(pageName:gsub('^%.',''))
                end,
                pageName
            )
            args.ascii = 'xn--' .. puny
        end
    end
    return args
end

-- Map tld_type to internal _type for title block display logic
local function mapTldTypeToInternalType(template, args)
    if args.tld_type and args.tld_type ~= '' then
        args._type = select(1, getCanonicalForms().normalize(args.tld_type, template.config.mappings.tld_type)) or args.tld_type
    end
    return args
end

-- Call preprocessors
Blueprint.addPreprocessor(template, 'setPageIdField') -- Blueprint default
Blueprint.addPreprocessor(template, 'deriveRegionFromCountry') -- Blueprint possible default
Blueprint.addPreprocessor(template, mapTldTypeToInternalType) -- TLD type detection
Blueprint.addPreprocessor(template, detectIDNStatus) -- IDN detection

-- ==================== Main Render Function ====================
-- Blueprint default: Render
function p.render(frame)
    return ErrorHandling.protect(
        errorContext,
        "render",
        function()
            return template.render(frame)
        end,
        ErrorHandling.getMessage("TEMPLATE_RENDER_ERROR"),
        frame
    )
end

return p