Basculer le menu
Changer de menu des préférences
Basculer le menu personnel
Non connecté(e)
Votre adresse IP sera visible au public si vous faites des modifications.

La documentation pour ce module peut être créée à Module:Infobox/Core/doc

local p = {}
local getArgs = require('Module:Arguments').getArgs

-- Fonction pour créer l'HTML de l'infobox
function p.createInfobox(config, args)
    local root = mw.html.create('div')
        :addClass('infobox')
        :attr('role', 'region')
        :attr('aria-label', 'Infobox')

    -- En-tête avec titre
    local header = root:tag('div'):addClass('infobox-header')
    
    -- Conteneur pour l'icône et le titre
    local headerContent = header:tag('div'):addClass('infobox-header-content')
    
    -- Gestion de l'icône
    if config.icone then
        local iconSpan = headerContent:tag('span'):addClass('infobox-icon')
        
        if type(config.icone) == 'table' then
            -- Icône FontAwesome
            local iconType = config.icone.type or 'fas'
            local iconName = config.icone.nom or 'info-circle'
            iconSpan:addClass(iconType):addClass('fa-' .. iconName)
        elseif type(config.icone) == 'string' then
            -- Image personnalisée
            iconSpan:wikitext(string.format('[[Fichier:%s|20px|link=]]', config.icone))
        end
    end
    
    -- Titre
    local titre = type(config.titre) == 'function' and config.titre(args) or config.titre
    headerContent:tag('span')
        :addClass('infobox-title')
        :wikitext(titre)

    -- Image si définie
    if config.image then
        local imageData = type(config.image) == 'function' and config.image(args) or config.image
        if imageData and imageData.nom then
            local imageDiv = root:tag('div'):addClass('infobox-image')
            local taille = imageData.taille or '300px'
            local legende = imageData.legende
            
            -- Construction du wikitext pour l'image
            local imageWikitext = string.format('[[Fichier:%s|%s|center', imageData.nom, taille)
            if legende and legende ~= '' then
                imageWikitext = imageWikitext .. '|' .. legende
            end
            imageWikitext = imageWikitext .. ']]'
            
            imageDiv:wikitext(imageWikitext)
        end
    end

    -- Corps de l'infobox avec les sections
    local body = root:tag('div'):addClass('infobox-body')
    
    -- Variable pour suivre si les coordonnées ont été affichées
    local coordinatesDisplayed = false
    
    if config.sections then
        for _, section in ipairs(config.sections) do
            -- Créer la section seulement si elle a des champs à afficher
            local hasVisibleFields = false
            for _, champ in ipairs(section.champs) do
                if args[champ.cle] and args[champ.cle] ~= '' then
                    hasVisibleFields = true
                    break
                end
            end
            
            -- Vérifier aussi les coordonnées groupées
            if not coordinatesDisplayed and args.x and args.y and args.z then
                for _, champ in ipairs(section.champs) do
                    if champ.cle == 'x' or champ.cle == 'y' or champ.cle == 'z' then
                        hasVisibleFields = true
                        break
                    end
                end
            end
            
            if hasVisibleFields then
                local sectionDiv = body:tag('div'):addClass('infobox-section')
                
                -- Titre de section
                if section.titre then
                    sectionDiv:tag('div')
                        :addClass('infobox-section-title')
                        :wikitext(section.titre)
                end
                
                -- Vérifier si cette section contient les coordonnées (x, y, z)
                local hasCoordinates = false
                if not coordinatesDisplayed and args.x and args.y and args.z then
                    for _, champ in ipairs(section.champs) do
                        if champ.cle == 'x' or champ.cle == 'y' or champ.cle == 'z' then
                            hasCoordinates = true
                            break
                        end
                    end
                end
                
                -- Si la section contient les coordonnées, les afficher groupées
                if hasCoordinates and not coordinatesDisplayed then
                    -- Vérifier si on peut créer un lien (worldname obligatoire)
                    local canCreateLink = args.worldname and args.worldname ~= ''
                    
                    local labelDiv = mw.html.create('div')
                        :addClass('infobox-label')
                        :wikitext("'''Coordonnées'''")
                    
                    local valueDiv = mw.html.create('div')
                        :addClass('infobox-value')
                    
                    if canCreateLink then
                        -- Construction du lien avec worldname
                        local mapname = args.mapname and args.mapname ~= '' and args.mapname or 'flat'
                        local zoom = args.zoom and args.zoom ~= '' and args.zoom or '4'
                        
                        local mapUrl = string.format(
                            'https://map.nefald.fr/?worldname=%s&mapname=%s&zoom=%s&x=%s&y=%s&z=%s',
                            mw.uri.encode(args.worldname),
                            mw.uri.encode(mapname),
                            mw.uri.encode(zoom),
                            mw.uri.encode(args.x),
                            mw.uri.encode(args.y),
                            mw.uri.encode(args.z)
                        )
                        
                        local displayText = string.format('%s, %s, %s', args.x, args.y, args.z)
                        valueDiv:wikitext(string.format('[%s %s]', mapUrl, displayText))
                    else
                        -- Affichage simple sans lien si worldname manque
                        local displayText = string.format('%s, %s, %s', args.x, args.y, args.z)
                        valueDiv:wikitext(displayText)
                    end
                    
                    local rowDiv = mw.html.create('div'):addClass('infobox-row')
                    rowDiv:node(labelDiv):node(valueDiv)
                    sectionDiv:node(rowDiv)
                    coordinatesDisplayed = true
                end
                
                -- Champs de la section
                for _, champ in ipairs(section.champs) do
                    local value = args[champ.cle]
                    
                    -- Ignorer les coordonnées individuelles si elles ont été affichées groupées
                    if coordinatesDisplayed and (champ.cle == 'x' or champ.cle == 'y' or champ.cle == 'z') then
                        -- Ne rien faire, on a déjà affiché les coordonnées groupées
                    elseif value and value ~= '' then
                        local rowDiv = sectionDiv:tag('div'):addClass('infobox-row')
                        
                        -- Label
                        rowDiv:tag('div')
                            :addClass('infobox-label')
                            :wikitext("'''" .. champ.label .. "'''")
                        
                        -- Valeur
                        local valueDiv = rowDiv:tag('div'):addClass('infobox-value')
                        
                        -- Traiter la valeur (fonction ou chaîne)
                        if type(champ.format) == 'function' then
                            valueDiv:wikitext(champ.format(value, args))
                        else
                            valueDiv:wikitext(value)
                        end
                    end
                end
            end
        end
    end

    return tostring(root)
end

-- Fonction pour valider le type
function p.validateType(args, config)
    if not config.typeField then
        return true, nil
    end
    
    local typeValue = args.type
    if not typeValue or typeValue == '' then
        if config.typeField.required then
            return false, "Le champ 'type' est obligatoire"
        end
        return true, nil
    end
    
    -- Vérifier si le type est dans les valeurs autorisées
    if config.typeField.allowedValues then
        local typeConfig = config.typeField.allowedValues[typeValue:lower()]
        if not typeConfig then
            return false, config.typeField.errorMessage or "Type non reconnu"
        end
        return true, typeConfig
    end
    
    return true, nil
end

-- Fonction pour générer les catégories
function p.generateCategories(args, config, typeConfig)
    if not config.categories then
        return ''
    end
    
    return config.categories(args, typeConfig)
end

-- Fonction principale appelée par {{#invoke:}}
function p.main(frame)
    local args = getArgs(frame, {parentFirst = true})
    
    -- Récupérer le type d'infobox depuis les arguments du frame
    local infoboxType = frame.args[1] or frame.args.type
    if not infoboxType or infoboxType == '' then
        return '<div class="error">Type d\'infobox requis</div>'
    end
    
    -- Charger la configuration appropriée
    local configModule = 'Module:Infobox/Configs/' .. infoboxType
    local success, config = pcall(require, configModule)
    
    if not success then
        return '<div class="error">Configuration introuvable pour : ' .. infoboxType .. '</div>'
    end
    
    -- Valider le type si nécessaire
    local isValid, typeConfig = p.validateType(args, config)
    if not isValid then
        return '<div class="error">' .. typeConfig .. '</div>'
    end
    
    -- Générer l'infobox
    local infobox = p.createInfobox(config, args)
    
    -- Ajouter les catégories
    local categories = p.generateCategories(args, config, typeConfig)
    
    return infobox .. categories
end

return p