Module:Infobox/Core
De Nefald
Autres actions
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