Jump to content

Module:ElementAchievementBadges

Documentation for this module may be created at Module:ElementAchievementBadges/doc

-- Module:ElementAchievementBadges
-- Renders achievement badges for Person templates and handles all badge-type achievements.

local p = {}

p.elementName = "achievementBadges"

-- Load required modules
local ErrorHandling = require('Module:ErrorHandling')
local Achievements = require('Module:AchievementSystem')

-- Default configuration
p.defaultConfig = {
    containerClass = "achievement-badges-container",
    badgeClass = "achievement-badge",
    emptyText = ""  -- Empty by default when no badges exist
}

-- Create block function
function p.createBlock()
    return function(template, args)
        -- Protected execution wrapper
        local function execute()
            local frame = mw.getCurrentFrame()
            
            -- Get the current page ID
            local pageId = mw.title.getCurrentTitle().id
            if not pageId then
                -- Include debug comment when no page ID available
                return "<!-- Achievement Badges: No page ID available -->"
            end
            
            -- CRITICAL: WE MUST PRE-LOAD THE JSON DATA WITH THE FRAME BEFORE GETTING ANY ACHIEVEMENTS
            pcall(function()
                Achievements.loadData(frame)
                Achievements.loadTypes(frame)
            end)
            
            -- Get all user achievements first
            local userAchievements = Achievements.getUserAchievements(pageId)
            
            -- Filter for only badge type achievements
            local badgeAchievements = {}
            local types = Achievements.loadTypes(frame)
            
            -- Build a lookup table for achievement types
            local typeDefinitions = {}
            for _, typeData in ipairs(types) do
                if typeData.id and typeData.type then
                    typeDefinitions[typeData.id] = typeData
                end
            end
            
            -- Filter user achievements to only include badge types
            for _, achievement in ipairs(userAchievements) do
                local achType = achievement.type
                if achType and typeDefinitions[achType] and typeDefinitions[achType].type == "badge" then
                    -- Add achievement display name from type definition
                    achievement.name = typeDefinitions[achType].name or achType
                    table.insert(badgeAchievements, achievement)
                end
            end
            
            -- Minimal debug info for troubleshooting
            local debugInfo = string.format(
                "<!-- Achievement Badges: pageId=%s, found=%s -->",
                pageId or "nil",
                #badgeAchievements
            )
            
            -- If no badges found, return empty or placeholder text
            if #badgeAchievements == 0 then
                -- No badges found - return empty string or configured empty text
                local emptyText = template.config.achievementBadges 
                    and template.config.achievementBadges.emptyText
                    or p.defaultConfig.emptyText
                
                return debugInfo .. emptyText
            end
            
            -- Configuration
            local containerClass = template.config.achievementBadges 
                and template.config.achievementBadges.containerClass
                or p.defaultConfig.containerClass
            
            local badgeClass = template.config.achievementBadges 
                and template.config.achievementBadges.badgeClass
                or p.defaultConfig.badgeClass
            
            -- Build the badges HTML
            local badgesHtml = {}
            
            -- Add a table row to contain the badges
            table.insert(badgesHtml, '|-\n| colspan="2" class="' .. containerClass .. '" | ')
            
            -- Add each badge
            for _, achievement in ipairs(badgeAchievements) do
                -- For each badge, create a span with appropriate classes
                local badgeType = achievement.type or ""
                if badgeType ~= "" then
                    -- Add CSS classes from achievement type (e.g., "badge-icann-fellow")
                    local badgeSpan = string.format(
                        '<span class="%s %s" title="%s"></span>',
                        badgeClass, badgeType, achievement.name or badgeType
                    )
                    table.insert(badgesHtml, badgeSpan)
                end
            end
            
            -- Return the complete HTML with debug info
            return table.concat(badgesHtml) .. debugInfo
        end
        
        -- Wrap with error handling
        if template._errorContext then
            return ErrorHandling.protect(
                template._errorContext,
                "ElementBlock_achievementBadges",
                execute,
                ""
            )
        else
            local ok, result = pcall(execute)
            return ok and result or "<!-- Achievement Badges: Protected execution failed -->"
        end
    end
end

return p