Module:CountryData: Difference between revisions

// via Wikitext Extension for VSCode
Tag: Reverted
// via Wikitext Extension for VSCode
 
(4 intermediate revisions by the same user not shown)
Line 1: Line 1:
-- Module:CountryData
--[[
-- Unified module for country data management.
* Name: CountryData
--
* Author: Mark W. Datysgeld
-- Features:
* Description: Unified module for country data management with JSON loading, normalization, region mapping, and Semantic MediaWiki integration
--  * Loads country data from JSON stored in Data:CountryDataset.json
* Notes: Loads from Data:CountryDataset.json; normalizes country names to canonical forms; maps countries to ICANN regions; provides extensible property access; formats country lists with region-specific emoji styling; processes countries for category assignment
--  * Normalizes country names to canonical forms
]]
--  * Maps countries to ICANN regions
--  * Provides extensible property access
--  * Integrates with Semantic MediaWiki
--  * Formats country lists with region-specific emoji styling
--  * Processes countries for category assignment


-- Dependencies
-- Dependencies
Line 15: Line 10:
local NormalizationText = require('Module:NormalizationText')
local NormalizationText = require('Module:NormalizationText')
local loader = require('Module:DatasetLoader')
local loader = require('Module:DatasetLoader')
local ErrorHandling = require('Module:ErrorHandling')


-- Module-level cache tables for improved performance
-- Module-level cache tables for improved performance
Line 278: Line 272:
end
end


function CountryData.getRegionByCountry(name, context)
function CountryData.getRegionByCountry(name)
     if not name or name == "" then
     if not name or name == "" then
         return "(Unrecognized)"
         return "(Unrecognized)"
Line 293: Line 287:
     if country and country.icann_region then
     if country and country.icann_region then
         result = country.icann_region
         result = country.icann_region
        if context then
            ErrorHandling.addStatus(
                context,
                "CountryData.getRegionByCountry",
                "Country and region matched successfully.",
                string.format("Input: '%s' -> Matched Country: '%s' -> Matched Region: '%s'", name, country.name, result)
            )
        end
     else
     else
         result = "(Unrecognized)"
         result = "(Unrecognized)"
Line 458: Line 444:
     functionCache[cacheKey] = properties
     functionCache[cacheKey] = properties
     return properties
     return properties
end
function CountryData.getSemanticPropertyName(propertyKey)
    local ConfigRepository = require('Module:ConfigRepository')
    for templateName, templateConfig in pairs(ConfigRepository.templates) do
        if templateConfig.semantics and templateConfig.semantics.additionalProperties then
            if templateConfig.semantics.additionalProperties[propertyKey] then
                return propertyKey
            end
        end
    end
    return nil
end
end


Line 478: Line 452:
     end
     end
      
      
    -- This function requires 'Module:ConfigRepository' to get the semantic property names.
     local ConfigRepository = require('Module:ConfigRepository')
    -- Using a protected call to prevent errors if the module is not available.
     local success, ConfigRepository = pcall(require, 'Module:ConfigRepository')
    if not success or not ConfigRepository then
        return properties -- Cannot proceed without the configuration.
    end
 
     local countryPropertyName = ConfigRepository.getSemanticPropertyName("Has country")
     local countryPropertyName = ConfigRepository.getSemanticPropertyName("Has country")
     local regionPropertyName = ConfigRepository.getSemanticPropertyName("Has ICANN region")
     local regionPropertyName = ConfigRepository.getSemanticPropertyName("Has ICANN region")
Line 550: Line 518:
function CountryData.formatCountryList(value)
function CountryData.formatCountryList(value)
     if not value or value == "" then return "" end
     if not value or value == "" then return "" end
      
 
     local countries = {}
     local ListGeneration = require('Module:ListGeneration')
     for country in string.gmatch(value, "[^;]+") do
     local itemsToProcess = {}
        local trimmed = country:match("^%s*(.-)%s*$")
 
        if trimmed and trimmed ~= "" then
    -- First, check if the entire string is a single, valid country.
            table.insert(countries, trimmed)
     -- This correctly handles names like "Trinidad and Tobago".
    local singleCountryName = CountryData.normalizeCountryName(value)
    if singleCountryName ~= "(Unrecognized)" then
        -- If it's a valid country, treat it as a single item.
        table.insert(itemsToProcess, value)
    else
        -- If not a single country, assume it's a list and split ONLY by semicolon.
        -- This is safer than letting ListGeneration guess the delimiter.
        for item in string.gmatch(value, "[^;]+") do
            local trimmed = item:match("^%s*(.-)%s*$")
            if trimmed and trimmed ~= "" then
                table.insert(itemsToProcess, trimmed)
            end
         end
         end
     end
     end
      
 
     local listItems = {}
     -- Define the item hook for country-specific formatting
    for _, countryName in ipairs(countries) do
     local function countryItemHook(countryName)
         local normalized = CountryData.normalizeCountryName(countryName)
         local normalized = CountryData.normalizeCountryName(countryName)
         if normalized ~= "(Unrecognized)" then
         if normalized ~= "(Unrecognized)" then
             local countryRegion = CountryData.getRegionByCountry(normalized)
             local countryRegion = CountryData.getRegionByCountry(normalized)
             local regionClass = getRegionClass(countryRegion)
             -- Return a table with content and class for the li element
             table.insert(listItems, string.format("<li class=\"%s\">%s</li>", regionClass, normalized))
            return {
                content = normalized,
                class = getRegionClass(countryRegion)
             }
         end
         end
        return nil -- Exclude unrecognized countries from the list
     end
     end
      
 
     if #listItems > 0 then
     -- Set the options for the list generation
         return string.format("<ul class=\"template-list template-list-country\">%s</ul>", table.concat(listItems, ""))
     local options = {
     end
        mode = 'bullet',
      
         listClass = 'template-list-country',
     return ""
        itemHook = countryItemHook
     }
 
     -- Pass the pre-processed table of items to the list generator.
     return ListGeneration.createList(itemsToProcess, options)
end
end