« Module:Infobox/Core » : différence entre les versions
De Nefald
Autres actions
Ajout catégorisation automatique (namespace 0) selon le type Balises : Modification par mobile Modification par le web mobile |
Port depuis codex.nefald.fr : masquage des sections vides, champs sans label pleine largeur, icône configurable par fonction (via update-page on MediaWiki MCP Server) |
||
| (9 versions intermédiaires par le même utilisateur non affichées) | |||
| Ligne 1 : | Ligne 1 : | ||
local p = {} | local p = {} | ||
local getArgs = require('Module:Arguments').getArgs | local getArgs = require('Module:Arguments').getArgs | ||
-- Fonction pour générer le lien de carte dynamique | |||
local function buildMapLink(args) | |||
-- Vérifier les champs obligatoires | |||
if not args.x or args.x == '' then return nil end | |||
if not args.y or args.y == '' then return nil end | |||
if not args.z or args.z == '' then return nil end | |||
if not args.worldname or args.worldname == '' then return nil end | |||
-- Valeurs par défaut pour les champs optionnels | |||
local mapname = args.mapname or 'flat' | |||
local zoom = args.zoom or '4' | |||
-- Construction de l'URL | |||
local url = string.format( | |||
'https://map.nefald.fr/?worldname=%s&mapname=%s&zoom=%s&x=%s&y=%s&z=%s', | |||
mw.uri.encode(args.worldname, 'PATH'), | |||
mw.uri.encode(mapname, 'PATH'), | |||
zoom, | |||
args.x, | |||
args.y, | |||
args.z | |||
) | |||
-- Retourner le lien formaté | |||
return string.format('[%s %s, %s, %s]', url, args.x, args.y, args.z) | |||
end | |||
-- Fonction de validation du champ "type" | -- Fonction de validation du champ "type" | ||
| Ligne 44 : | Ligne 71 : | ||
-- Fonction pour gérer la catégorisation automatique | -- Fonction pour gérer la catégorisation automatique | ||
local function | local function addCategories(args, config, frame) | ||
-- Vérifier qu'on est dans le namespace principal (0) | -- Vérifier qu'on est dans le namespace principal (0) ou namespace plugin (3000) | ||
local title = mw.title.getCurrentTitle() | local title = mw.title.getCurrentTitle() | ||
if title.namespace ~= 0 then | if title.namespace ~= 0 and title.namespace ~= 3000 then | ||
return '' | return '' | ||
end | end | ||
local categoryString = '' | |||
-- Nouvelles catégories configurables (fonction categories) | |||
if | if type(config.categories) == 'function' then | ||
local cats = config.categories(args, config, frame) | |||
if cats then | |||
for _, cat in ipairs(cats) do | |||
categoryString = categoryString .. '[[Catégorie:' .. cat .. ']]' | |||
end | |||
end | |||
end | end | ||
return | return categoryString | ||
end | end | ||
| Ligne 126 : | Ligne 146 : | ||
local body = mw.html.create('div') | local body = mw.html.create('div') | ||
:addClass('infobox-body') | :addClass('infobox-body') | ||
-- Vérifier si on a des coordonnées complètes | |||
local mapLink = buildMapLink(args) | |||
local coordinatesDisplayed = false | |||
for _, section in ipairs(config.sections or {}) do | for _, section in ipairs(config.sections or {}) do | ||
-- Les lignes de la section sont accumulées ici et intégrées au body seulement | |||
-- si au moins une a du contenu — sinon le section-title reste orphelin (ex. une | |||
-- section "Sous-pages" ou "Compatibilité" entièrement vide sur cette page). | |||
local sectionRows = {} | |||
-- | |||
local | |||
for _, champ in ipairs(section.champs or {}) do | for _, champ in ipairs(section.champs or {}) do | ||
-- | -- Gestion spéciale pour les coordonnées | ||
if | if mapLink and not coordinatesDisplayed and (champ.cle == 'x' or champ.cle == 'y' or champ.cle == 'z' or champ.cle == 'worldname' or champ.cle == 'coordonnees') then | ||
local rowDiv = mw.html.create('div') | local rowDiv = mw.html.create('div') | ||
:addClass('infobox-row') | :addClass('infobox-row') | ||
| Ligne 151 : | Ligne 169 : | ||
local valueDiv = mw.html.create('div') | local valueDiv = mw.html.create('div') | ||
:addClass('infobox-value') | :addClass('infobox-value') | ||
:wikitext(mapLink) | |||
rowDiv:node(labelDiv):node(valueDiv) | rowDiv:node(labelDiv):node(valueDiv) | ||
table.insert(sectionRows, rowDiv) | |||
coordinatesDisplayed = true | coordinatesDisplayed = true | ||
-- Traitement normal des autres champs | -- Traitement normal des autres champs (ignorer x, y, z, worldname s'ils sont déjà affichés comme coordonnées) | ||
elseif not ( | elseif not (mapLink and (champ.cle == 'x' or champ.cle == 'y' or champ.cle == 'z' or champ.cle == 'worldname' or champ.cle == 'mapname' or champ.cle == 'zoom')) then | ||
local rawValue = args[champ.cle] | |||
-- Si le champ a une valeur OU une fonction process qui peut générer une valeur | |||
if (rawValue and rawValue ~= '') or champ.process then | |||
local finalValue = rawValue | |||
-- Appliquer la fonction process si elle existe | |||
if champ.process and type(champ.process) == 'function' then | |||
finalValue = champ.process(rawValue, args, frame) | |||
end | |||
-- N'afficher que si on a une valeur finale | |||
if finalValue and finalValue ~= '' then | |||
local rowDiv = mw.html.create('div') | |||
:addClass('infobox-row') | |||
local valueDiv = mw.html.create('div') | |||
:addClass('infobox-value') | |||
-- Champ sans label (ex. liste pleine largeur type Sous-pages) : | |||
-- pas de colonne label, la valeur devient seule enfant flex du | |||
-- row et occupe donc naturellement 100% de la largeur. | |||
if champ.label and champ.label ~= '' then | |||
local labelDiv = mw.html.create('div') | |||
:addClass('infobox-label') | |||
:wikitext(champ.label) | |||
rowDiv:node(labelDiv) | |||
end | |||
-- Formatage spécial pour le champ "type" | |||
if champ.cle == 'type' and typeValidation.displayValue then | |||
valueDiv:wikitext(typeValidation.displayValue) | |||
else | |||
valueDiv:wikitext(finalValue) | |||
end | |||
rowDiv:node(valueDiv) | |||
table.insert(sectionRows, rowDiv) | |||
end | |||
end | end | ||
end | |||
end | |||
if #sectionRows > 0 then | |||
if section.titre then | |||
local sectionDiv = mw.html.create('div') | |||
:addClass('infobox-section-title') | |||
:wikitext(section.titre) | |||
body:node(sectionDiv) | |||
end | |||
for _, rowDiv in ipairs(sectionRows) do | |||
body:node(rowDiv) | body:node(rowDiv) | ||
end | end | ||
| Ligne 197 : | Ligne 239 : | ||
if config.icone then | if config.icone then | ||
local | local iconeConfig = config.icone | ||
local iconeNom = | if type(iconeConfig) == 'function' then | ||
iconeConfig = iconeConfig(args) or {} | |||
end | |||
local iconeType = iconeConfig.type or 'fas' | |||
local iconeNom = iconeConfig.nom | |||
-- Utiliser mw.getCurrentFrame() si frame n'est pas disponible | -- Utiliser mw.getCurrentFrame() si frame n'est pas disponible | ||
| Ligne 219 : | Ligne 265 : | ||
-- Ajouter les catégories automatiques | -- Ajouter les catégories automatiques | ||
local categories = | local categories = addCategories(args, config, frame) | ||
return finalResult .. categories | return finalResult .. categories | ||