Module:ConfigRepository: Difference between revisions

HARD FIX
Tag: Reverted
No edit summary
Tag: Reverted
Line 88: Line 88:


------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- TEMPLATE-SPECIFIC CONFIGURATIONS
-- Template Definitions (Lazy Loading)
------------------------------------------------------------------------------
------------------------------------------------------------------------------
p.templates = {


------------------------------------------------------------------------------
-- Cache for loaded templates
-- ANCHOR: EVENT TEMPLATE
local loadedTemplates = {}
------------------------------------------------------------------------------
 
    Event = {
        meta = {
            description = "Event template"
        },
       
        categories = { -- Default categories
            base = {"Events"}
        },


        patterns = {
-- Template definitions as functions for lazy loading
            -- Patterns for event navigation detection
local templateDefinitions = {
            seriesNumber = p.patterns.eventSeriesNumber, -- e.g., "ICANN 76"
    -- Event template definition
            seriesYear = p.patterns.eventSeriesYear -- e.g., "IGF 2023"
    Event = function()
        },
         return {
       
             meta = {
        fields = {
                 description = "Event template"
            {key="logo", label="Logo"},
            {key="process", label="Process"},
            {key="start", label="Start Date"},
            {key="end", label="End Date"},
            {key="region", label=p.fieldLabels.region},
            {keys={"country", "territory"}, label=p.fieldLabels.country},
            {key="city", label="City"},
            {key="venue", label="Venue"},
            {key="organizer", label="Organizer"},
            {keys={"website", "url"}, label=p.fieldLabels.website},
            {keys={"subject", "category"}, label="Subject"} -- REVIEW UNUSED
         },
       
        semantics = {
             properties = {
                 ["Has start date"] = "start",
                ["Has end date"] = "end",
                ["Part of process"] = "process",
                -- "Has country" and "Has ICANN region" handled by CountryData.addCountrySemanticProperties
                ["Has city"] = "city",
                ["Has venue"] = "venue",
                ["Has event organizer"] = "organizer"
                -- "Has event subject" -- UNUSED
             },
             },
              
              
             additionalProperties = {
             categories = { -- Default categories
                 ["Has country"] = {"country", "territory"}
                 base = {"Events"}
                 -- "Has event subject" UNUSED
            },
 
            patterns = {
                -- Patterns for event navigation detection
                seriesNumber = p.patterns.eventSeriesNumber, -- e.g., "ICANN 76"
                 seriesYear = p.patterns.eventSeriesYear -- e.g., "IGF 2023"
             },
             },
              
              
             transforms = {
             fields = {
                 ["Has start date"] = function(value)
                 {key="logo", label="Logo"},
                    return tostring(require('Module:NormalizationDate').formatDate(value))
                {key="process", label="Process"},
                 end,
                {key="start", label="Start Date"},
                 ["Has end date"] = function(value)
                {key="end", label="End Date"},
                    return tostring(require('Module:NormalizationDate').formatDate(value))
                {key="region", label=p.fieldLabels.region},
                 end
                 {keys={"country", "territory"}, label=p.fieldLabels.country},
                {key="city", label="City"},
                {key="venue", label="Venue"},
                 {key="organizer", label="Organizer"},
                {keys={"website", "url"}, label=p.fieldLabels.website},
                 {keys={"subject", "category"}, label="Subject"} -- REVIEW UNUSED
             },
             },
              
              
             skipProperties = { -- Handled separately
             semantics = {
                 ["Has country"] = true,
                 properties = {
                ["Has ICANN region"] = true,
                    ["Has start date"] = "start",
                ["Has event subject"] = true  -- REVIEW: UNUSED
                    ["Has end date"] = "end",
            }
                    ["Part of process"] = "process",
        }
                    -- "Has country" and "Has ICANN region" handled by CountryData.addCountrySemanticProperties
    },
                    ["Has city"] = "city",
   
                    ["Has venue"] = "venue",
------------------------------------------------------------------------------
                    ["Has event organizer"] = "organizer"
-- ANCHOR: PERSON TEMPLATE
                    -- "Has event subject" -- UNUSED
------------------------------------------------------------------------------
                },
 
    Person = {
        meta = {
            description = "Person template"
        },
       
        categories = { -- Default categories
            base = {"Person"}
        },
       
        mappings = {
            -- Community mappings for normalizing user input to canonical forms
            -- Each entry maps various synonyms to a canonical form and associated category
            community = {
                -- ICANN-related communities
                {canonical = "ICANN Community",
                synonyms = {"icann", "community"},
                category = "ICANN Community"},
                {canonical = "ICANN Staff",
                synonyms = {"staff", "icann org"},
                category = "ICANN Staff"},
                  
                  
                 -- Technical communities
                 additionalProperties = {
                {canonical = "Root Server Operator Community",
                    ["Has country"] = {"country", "territory"}
                synonyms = {"root server operator", "rso"},
                    -- "Has event subject" UNUSED
                category = "Root Server Operator Community"},
                 },
                {canonical = "RIR Community",
                synonyms = {"rir"},
                category = "RIR Community"},
                 {canonical = "Universal Acceptance Community",
                synonyms = {"universal acceptance", "ua", "ua member", "idn", "idn community"},
                category = "Universal Acceptance Community"},
                  
                  
                 -- Internet Governance organizations
                 transforms = {
                {canonical = "ISOC Community",
                    ["Has start date"] = function(value)
                synonyms = {"isoc", "internet society", "internet society community", "isoc member"},
                        return tostring(require('Module:NormalizationDate').formatDate(value))
                category = "ISOC Community"},
                    end,
                {canonical = "IETF Community",
                    ["Has end date"] = function(value)
                synonyms = {"ietf", "ietf member"},
                        return tostring(require('Module:NormalizationDate').formatDate(value))
                category = "IETF Community"},
                    end
                {canonical = "W3C Community",
                 },
                synonyms = {"w3c", "w3c member"},
                category = "W3C Community"},
                 {canonical = "IGF Community",
                synonyms = {"igf", "nri", "youth igf"},
                category = "IGF Community"},
                  
                  
                 -- Government-related
                 skipProperties = { -- Handled separately
                {canonical = "Governmental",
                    ["Has country"] = true,
                synonyms = {"government"},
                    ["Has ICANN region"] = true,
                category = "Governmental"},
                    ["Has event subject"] = true  -- REVIEW: UNUSED
                {canonical = "Intergovernmental",
                }
                synonyms = {"igo"},
                category = "Intergovernmental"}
             }
             }
         },
         }
       
    end,
        fields = {
   
            {key="community", label="Community"},
    -- Person template definition
            {key="affiliation", label="ICANN group"},
    Person = function()
            {key="organization", label="Organization"},
         return {
            {key="region", label=p.fieldLabels.region},
             meta = {
            {keys={"country", "territory"}, label=p.fieldLabels.country},
                 description = "Person template"
            {key="languages", label="Languages"},
            {key="website", label=p.fieldLabels.website},
            {key="soi", label="SOI"},
            {key="userbox", label="Achievements"}
        },
       
        patterns = {
            itemDelimiter = p.patterns.itemDelimiter, -- For splitting multi-value fields
            websitePattern = p.patterns.websitePattern -- For URL validation
         },
       
        semantics = {
             properties = {
                 ["Has governance community"] = "community",
                ["Has ICANN affiliation"] = "affiliation",
                ["Has organization"] = "organization",
                -- "Has ICANN region", "Has country", "Knows language", are all handled separately
             },
             },
              
              
             additionalProperties = {
             categories = { -- Default categories
                -- Handle multiple countries and regions in the special case handlers
                 base = {"Person"}
                ["Has country"] = {"country"},
                 ["Has ICANN region"] = {"region"}
             },
             },
              
              
             transforms = {
             mappings = {
                 ["Has governance community"] = function(value)
                 -- Community mappings for normalizing user input to canonical forms
                     local CanonicalForms = require('Module:CanonicalForms')
                -- Each entry maps various synonyms to a canonical form and associated category
                     return select(1, CanonicalForms.normalize(value, p.templates.Person.mappings.community)) or value
                community = {
                end,
                    -- ICANN-related communities
                ["Knows language"] = function(value)
                    {canonical = "ICANN Community",
                     -- Return raw value, the semantic property should store the raw data
                    synonyms = {"icann", "community"},
                     return value
                    category = "ICANN Community"},
                 end
                     {canonical = "ICANN Staff",
                    synonyms = {"staff", "icann org"},
                    category = "ICANN Staff"},
                   
                    -- Technical communities
                     {canonical = "Root Server Operator Community",
                    synonyms = {"root server operator", "rso"},
                    category = "Root Server Operator Community"},
                    {canonical = "RIR Community",
                    synonyms = {"rir"},
                    category = "RIR Community"},
                    {canonical = "Universal Acceptance Community",
                    synonyms = {"universal acceptance", "ua", "ua member", "idn", "idn community"},
                    category = "Universal Acceptance Community"},
                   
                    -- Internet Governance organizations
                    {canonical = "ISOC Community",
                    synonyms = {"isoc", "internet society", "internet society community", "isoc member"},
                    category = "ISOC Community"},
                    {canonical = "IETF Community",
                    synonyms = {"ietf", "ietf member"},
                    category = "IETF Community"},
                    {canonical = "W3C Community",
                    synonyms = {"w3c", "w3c member"},
                    category = "W3C Community"},
                    {canonical = "IGF Community",
                    synonyms = {"igf", "nri", "youth igf"},
                    category = "IGF Community"},
                   
                     -- Government-related
                    {canonical = "Governmental",
                    synonyms = {"government"},
                    category = "Governmental"},
                     {canonical = "Intergovernmental",
                    synonyms = {"igo"},
                    category = "Intergovernmental"}
                 }
             },
             },
              
              
             skipProperties = { -- Handled separately
             fields = {
                ["Has country"] = true,
                 {key="community", label="Community"},
                 ["Has ICANN region"] = true
                 {key="affiliation", label="ICANN group"},
            }
                {key="organization", label="Organization"},
        }
                {key="region", label=p.fieldLabels.region},
    },
                {keys={"country", "territory"}, label=p.fieldLabels.country},
   
                {key="languages", label="Languages"},
------------------------------------------------------------------------------
                {key="website", label=p.fieldLabels.website},
-- ANCHOR: TLD TEMPLATE
                {key="soi", label="SOI"},
------------------------------------------------------------------------------
                {key="userbox", label="Achievements"}
 
    TLD = {
        meta = {
            description = "TLD/ccTLD article template"
        },
       
        categories = {
            base = {}, -- TLDs use type-based categories
            conditional = {
                rvc = "TLDs with RVCs",
                idn = "IDN",
                idn_cctld = "IDN ccTLD"
            },
        },
       
        mappings = {
            type = {
                {canonical = "gTLD",
                synonyms = {"generic", "tld", "generic top level domain", "generic top-level domain", "generic tld"},
                category = "gTLD"},
                {canonical = "ccTLD",
                synonyms = {"country", "cc", "country code top level domain", "country code top-level domain", "country tld"},
                category = "ccTLD"}
            },
            subtype = {
                {canonical="geoTLD",
                synonyms={"geo tld","geo","geographic","geographical","geographic top level domain","geographic top-level domain","geographic tld"},
                css="tld-template-subtype-geotld",
                category="geoTLD"},
                {canonical="dotBrand",
                synonyms={"brand","brandtld","brand tld","brand top level domain","brand top-level domain"},
                css="tld-template-subtype-brandtld",
                category="dotBrand"},
                {canonical="Sponsored TLD",
                synonyms={"sponsored","sponsored top level domain","sponsored top-level domain"},
                css="tld-template-subtype-sponsored",
                category="Sponsored TLD"},
                {canonical="Legacy TLD",
                synonyms={"legacy","legacy top level domain","legacy top-level domain"},
                css="tld-template-subtype-legacytld",
                category="Legacy TLD"},
                {canonical="2012 gTLD Round",
                synonyms={"gtld round 2012","2012 ngtld round","2012 ngtld","ngtld 2012","ngtld","2012"},
                css="tld-template-subtype-ngtld-round-2012",
                category="2012 gTLD Round"}
            }
        },
       
        -- List of legacy TLDs that are not integrated into the nTLDStats database
        constants = {
            classicTLDs = {
                -- Generic TLDs
                com=true, net=true, org=true, info=true,
                -- Restricted TLDs
                edu=true, gov=true, mil=true, int=true,
                -- Sponsored TLDs
                aero=true, asia=true, cat=true, coop=true,  
                 jobs=true, mobi=true, museum=true, post=true,
                tel=true, travel=true, xxx=true
            }
        },
 
        patterns = {
            tldExtension = p.patterns.tldExtension, -- For extracting TLD from domain
            countryDelimiter = p.patterns.countryDelimiter -- For country parsing
        },
       
        fields = {
            {key="type",label="Type"},
            {key="subtype",label="Subtype"},
            {key="status",label="Status"},
            {keys={"country", "territory"},label=p.fieldLabels.country},
            {key="introduced",label="Introduced"},
            {keys={"date", "implemented"},label="Implemented"},
            {keys={"script", "language"},label="Script"},
            {key="translation",label="English version"},
            {key="ascii",label="Punycode"},
            {keys={"registry", "registryprovider"},label="Registry"},
            {key="website",label=p.fieldLabels.website},
            {keys={"RVC", "PIC"},label="PIC/RVC"}
        },
       
        semantics = {
            properties = {
                ["Has TLD type"] = "type",
                ["Has TLD subtype"] = "subtype",
                ["Has TLD status"] = "status",
                -- "Has country" is handled separately through addMultiCountrySemanticProperties
                ["Date introduced"] = "introduced",
                ["Date implemented"] = "date", -- Will also handle implemented
                ["Uses writing script"] = "script", -- Will also handle language
                ["Has registry operator"] = "registry", -- Will also handle registryprovider
                ["Has PIC or RVC"] = "RVC" -- Will also handle PIC
                -- "Is IDN" is handled separately as a boolean property
             },
             },
              
              
             additionalProperties = {
             patterns = {
                 ["Has country"] = {"country", "territory"},
                 itemDelimiter = p.patterns.itemDelimiter, -- For splitting multi-value fields
                ["Date implemented"] = {"date", "implemented"},
                 websitePattern = p.patterns.websitePattern -- For URL validation
                ["Uses writing script"] = {"script", "language"},
                 ["Has registry operator"] = {"registry", "registryprovider"},
                ["Has PIC or RVC"] = {"RVC", "PIC"}
             },
             },
              
              
             transforms = {
             semantics = {
                 ["Has TLD type"] = function(value)
                 properties = {
                     local CanonicalForms = require('Module:CanonicalForms')
                    ["Has governance community"] = "community",
                     return select(1, CanonicalForms.normalize(value, p.templates.TLD.mappings.type)) or value
                    ["Has ICANN affiliation"] = "affiliation",
                 end,
                     ["Has organization"] = "organization",
                 ["Has TLD subtype"] = function(value)
                     -- "Has ICANN region", "Has country", "Knows language", are all handled separately
                    local CanonicalForms = require('Module:CanonicalForms')
                 },
                    return select(1, CanonicalForms.normalize(value, p.templates.TLD.mappings.subtype)) or value
                  
                end,
                additionalProperties = {
                ["Date introduced"] = function(value)
                    -- Handle multiple countries and regions in the special case handlers
                    return tostring(require('Module:NormalizationDate').formatDate(value))
                    ["Has country"] = {"country"},
                end,
                    ["Has ICANN region"] = {"region"}
                ["Date implemented"] = function(value)
                },
                     return tostring(require('Module:NormalizationDate').formatDate(value))
               
                end,
                transforms = {
                ["Has PIC or RVC"] = function(value)
                    ["Has governance community"] = function(value)
                    -- If value exists and is not empty, return "true"
                        local CanonicalForms = require('Module:CanonicalForms')
                    if value and value ~= "" then
                        -- Use the loaded template from cache to avoid circular reference
                         return "true"
                        local personTemplate = loadedTemplates["Person"]
                        if not personTemplate then
                            -- Fallback to direct access if not loaded yet
                            return select(1, CanonicalForms.normalize(value, p.templates.Person.mappings.community)) or value
                        end
                        return select(1, CanonicalForms.normalize(value, personTemplate.mappings.community)) or value
                     end,
                    ["Knows language"] = function(value)
                        -- Return raw value, the semantic property should store the raw data
                         return value
                     end
                     end
                    return nil -- Return nil for empty values
                 },
                 end
               
            },
                skipProperties = { -- Handled separately
           
                    ["Has country"] = true,
            skipProperties = { -- Handled separately
                    ["Has ICANN region"] = true
                ["Has country"] = true
                }
             }
             }
         }
         }
     },
     end
   
}
 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- ANCHOR: LIBRARY INTERVIEW TEMPLATE
-- TEMPLATE-SPECIFIC CONFIGURATIONS
------------------------------------------------------------------------------
------------------------------------------------------------------------------


     LibraryInterview = {
-- Create templates table with metatable for lazy loading
         meta = {
p.templates = {}
             description = "Module for rendering the Library Interview template with semantics"
 
         },
-- Set up metatable for lazy loading
setmetatable(p.templates, {
     __index = function(t, key)
        -- Check if we have a cached version
         if loadedTemplates[key] then
             return loadedTemplates[key]
         end
          
          
         categories = { -- Default categories
         -- Check if we have a template definition for this key
            base = {
        if templateDefinitions[key] then
                 "Internet & Digital Governance Library",
            -- Load the template definition
                 "ICANNWiki Interviews"
            loadedTemplates[key] = templateDefinitions[key]()
            return loadedTemplates[key]
        end
       
        -- For backward compatibility, keep the legacy templates
        if key == "TLD" then
            -- TLD template definition (legacy)
            return {
                meta = {
                    description = "TLD/ccTLD article template"
                },
               
                categories = {
                    base = {}, -- TLDs use type-based categories
                    conditional = {
                        rvc = "TLDs with RVCs",
                        idn = "IDN",
                        idn_cctld = "IDN ccTLD"
                    },
                },
               
                mappings = {
                    type = {
                        {canonical = "gTLD",
                        synonyms = {"generic", "tld", "generic top level domain", "generic top-level domain", "generic tld"},
                        category = "gTLD"},
                        {canonical = "ccTLD",
                        synonyms = {"country", "cc", "country code top level domain", "country code top-level domain", "country tld"},
                        category = "ccTLD"}
                    },
                    subtype = {
                        {canonical="geoTLD",
                        synonyms={"geo tld","geo","geographic","geographical","geographic top level domain","geographic top-level domain","geographic tld"},
                        css="tld-template-subtype-geotld",
                        category="geoTLD"},
                        {canonical="dotBrand",
                        synonyms={"brand","brandtld","brand tld","brand top level domain","brand top-level domain"},
                        css="tld-template-subtype-brandtld",
                        category="dotBrand"},
                        {canonical="Sponsored TLD",
                        synonyms={"sponsored","sponsored top level domain","sponsored top-level domain"},
                        css="tld-template-subtype-sponsored",
                        category="Sponsored TLD"},
                        {canonical="Legacy TLD",
                        synonyms={"legacy","legacy top level domain","legacy top-level domain"},
                        css="tld-template-subtype-legacytld",
                        category="Legacy TLD"},
                        {canonical="2012 gTLD Round",
                        synonyms={"gtld round 2012","2012 ngtld round","2012 ngtld","ngtld 2012","ngtld","2012"},
                        css="tld-template-subtype-ngtld-round-2012",
                        category="2012 gTLD Round"}
                    }
                },
               
                -- List of legacy TLDs that are not integrated into the nTLDStats database
                constants = {
                    classicTLDs = {
                        -- Generic TLDs
                        com=true, net=true, org=true, info=true,
                        -- Restricted TLDs
                        edu=true, gov=true, mil=true, int=true,
                        -- Sponsored TLDs
                        aero=true, asia=true, cat=true, coop=true,
                        jobs=true, mobi=true, museum=true, post=true,
                        tel=true, travel=true, xxx=true
                    }
                },
 
                patterns = {
                    tldExtension = p.patterns.tldExtension, -- For extracting TLD from domain
                    countryDelimiter = p.patterns.countryDelimiter -- For country parsing
                },
                  
                fields = {
                    {key="type",label="Type"},
                    {key="subtype",label="Subtype"},
                    {key="status",label="Status"},
                    {keys={"country", "territory"},label=p.fieldLabels.country},
                    {key="introduced",label="Introduced"},
                    {keys={"date", "implemented"},label="Implemented"},
                    {keys={"script", "language"},label="Script"},
                    {key="translation",label="English version"},
                    {key="ascii",label="Punycode"},
                    {keys={"registry", "registryprovider"},label="Registry"},
                    {key="website",label=p.fieldLabels.website},
                    {keys={"RVC", "PIC"},label="PIC/RVC"}
                },
                  
                semantics = {
                    properties = {
                        ["Has TLD type"] = "type",
                        ["Has TLD subtype"] = "subtype",
                        ["Has TLD status"] = "status",
                        -- "Has country" is handled separately through addMultiCountrySemanticProperties
                        ["Date introduced"] = "introduced",
                        ["Date implemented"] = "date", -- Will also handle implemented
                        ["Uses writing script"] = "script", -- Will also handle language
                        ["Has registry operator"] = "registry", -- Will also handle registryprovider
                        ["Has PIC or RVC"] = "RVC" -- Will also handle PIC
                        -- "Is IDN" is handled separately as a boolean property
                    },
                   
                    additionalProperties = {
                        ["Has country"] = {"country", "territory"},
                        ["Date implemented"] = {"date", "implemented"},
                        ["Uses writing script"] = {"script", "language"},
                        ["Has registry operator"] = {"registry", "registryprovider"},
                        ["Has PIC or RVC"] = {"RVC", "PIC"}
                    },
                   
                    transforms = {
                        ["Has TLD type"] = function(value)
                            local CanonicalForms = require('Module:CanonicalForms')
                            -- Use the loaded template from cache to avoid circular reference
                            local tldTemplate = loadedTemplates["TLD"]
                            if not tldTemplate then
                                -- Fallback to direct access if not loaded yet
                                return select(1, CanonicalForms.normalize(value, p.templates.TLD.mappings.type)) or value
                            end
                            return select(1, CanonicalForms.normalize(value, tldTemplate.mappings.type)) or value
                        end,
                        ["Has TLD subtype"] = function(value)
                            local CanonicalForms = require('Module:CanonicalForms')
                            -- Use the loaded template from cache to avoid circular reference
                            local tldTemplate = loadedTemplates["TLD"]
                            if not tldTemplate then
                                -- Fallback to direct access if not loaded yet
                                return select(1, CanonicalForms.normalize(value, p.templates.TLD.mappings.subtype)) or value
                            end
                            return select(1, CanonicalForms.normalize(value, tldTemplate.mappings.subtype)) or value
                        end,
                        ["Date introduced"] = function(value)
                            return tostring(require('Module:NormalizationDate').formatDate(value))
                        end,
                        ["Date implemented"] = function(value)
                            return tostring(require('Module:NormalizationDate').formatDate(value))
                        end,
                        ["Has PIC or RVC"] = function(value)
                            -- If value exists and is not empty, return "true"
                            if value and value ~= "" then
                                return "true"
                            end
                            return nil -- Return nil for empty values
                        end
                    },
                   
                    skipProperties = { -- Handled separately
                        ["Has country"] = true
                    }
                }
             }
             }
         },
         elseif key == "LibraryInterview" then
            -- LibraryInterview template definition (legacy)
            return {
                meta = {
                    description = "Module for rendering the Library Interview template with semantics"
                },
               
                categories = { -- Default categories
                    base = {
                        "Internet & Digital Governance Library",
                        "ICANNWiki Interviews"
                    }
                },
               
                constants = {
                    title = "Internet & Digital Governance Library",
                    tableClass = "library-box"
                },
               
                fields = {
                    {key="Title", label="Title"},
                    {key="Format", label="Format"},
                    {key="Date", label=p.fieldLabels.date},
                    {key="Interviewer", label="Interviewer", autoWikiLink=true},
                    {key="Interviewee", label="Interviewee", autoWikiLink=true},
                    {key="ID", label="Permanent ID"}
                },
               
                semantics = {
                    -- Direct property mappings (1:1 relationship between property and field)
                    properties = {
                        ["Has interview format"] = "Format",
                        ["Has date"] = "Date",
                        ["Has interviewer"] = "Interviewer",
                        ["Has interviewee"] = "Interviewee",
                        ["Permanent ID"] = "ID"
                    },
                   
                    -- Properties that map to multiple possible fields
                    additionalProperties = {
                        ["Has person"] = {"Interviewer", "Interviewee"} -- Links interviews to person pages
                    },
                   
                    -- Transform functions to standardize property values
                    transforms = {
                        ["Has date"] = function(value)
                            return tostring(require('Module:NormalizationDate').formatDate(value))
                        end,
                        ["Permanent ID"] = function(value)
                            -- Simply return the value as is, ensuring it's a string
                            return tostring(value or "")
                        end
                    },
                   
                    skipProperties = {
                        -- No properties to skip
                    }
                }
            }
        end
          
          
         constants = {
         -- Return empty table if template not found
            title = "Internet & Digital Governance Library",
         return {}
            tableClass = "library-box"
     end
         },
})
       
        fields = {
            {key="Title", label="Title"},
            {key="Format", label="Format"},
            {key="Date", label=p.fieldLabels.date},
            {key="Interviewer", label="Interviewer", autoWikiLink=true},
            {key="Interviewee", label="Interviewee", autoWikiLink=true},
            {key="ID", label="Permanent ID"}
        },
       
        semantics = {
            -- Direct property mappings (1:1 relationship between property and field)
            properties = {
                ["Has interview format"] = "Format",
                ["Has date"] = "Date",
                ["Has interviewer"] = "Interviewer",
                ["Has interviewee"] = "Interviewee",
                ["Permanent ID"] = "ID"
            },
           
            -- Properties that map to multiple possible fields
            additionalProperties = {
                ["Has person"] = {"Interviewer", "Interviewee"} -- Links interviews to person pages
            },
           
            -- Transform functions to standardize property values
            transforms = {
                ["Has date"] = function(value)
                    return tostring(require('Module:NormalizationDate').formatDate(value))
                end,
                ["Permanent ID"] = function(value)
                    -- Simply return the value as is, ensuring it's a string
                    return tostring(value or "")
                end
            },
           
            skipProperties = {
                -- No properties to skip
            }
        }
     }
}


------------------------------------------------------------------------------
------------------------------------------------------------------------------
Line 474: Line 518:
-- Get configuration for a specific template type
-- Get configuration for a specific template type
function p.getConfig(templateType)
function p.getConfig(templateType)
    -- First check if we have a lazy-loaded template
    if loadedTemplates[templateType] then
        -- Return from cache if already loaded
        return loadedTemplates[templateType]
    end
   
    -- Check if we have a template definition for this type
    if templateDefinitions[templateType] then
        -- Load the template definition
        loadedTemplates[templateType] = templateDefinitions[templateType]()
        return loadedTemplates[templateType]
    end
   
    -- Fall back to the traditional approach for other templates
     return p.templates[templateType] or {}
     return p.templates[templateType] or {}
end
end