« Module:Bandeau » : différence entre les versions
Apparence
Modèle:Infobox_Musique_(œuvre)>Od1n retrait de la classe "ambox", qui est hardcodée dans MediaWiki pour s'adapter aux modèles de enwiki, mais qui sur les autres wikis amène plus de problèmes qu'autre chose, en particulier sur la version mobile ; à propos actuellement l'affichage de nos bandeaux sur mobile est une horreur (notamment les icônes), mais c'est un autre problème |
m 252 versions importées |
||
| (25 versions intermédiaires par 4 utilisateurs non affichées) | |||
| Ligne 1 : | Ligne 1 : | ||
-- luacheck: globals mw, no max line length | |||
--Ce module implémente les modèles de bandeau. | --Ce module implémente les modèles de bandeau. | ||
| Ligne 21 : | Ligne 23 : | ||
forme = 'bandeau-simple', | forme = 'bandeau-simple', | ||
niveau = 'bandeau-niveau-neutre', | niveau = 'bandeau-niveau-neutre', | ||
formatLien = '[[Fichier:%s|%spx|alt=%s|class=noviewer]]', | formatLien = '[[Fichier:%s|%spx|alt=%s|class=noviewer %s]]', | ||
tailleIcone = '45x45', | tailleIcone = '45x45', | ||
erreurArgument = 'Paramètre <code>|%s=</code> manquant', | erreurArgument = 'Paramètre <code>|%s=</code> manquant', | ||
erreurEbaucheParam = 'le thème « %s » du modèle [[Modèle:Ébauche|{{ébauche}}]] n’est pas [[Aide:Ébauche/Aide paramètres|défini]].', | erreurEbaucheParam = 'le thème « %s » du modèle [[Modèle:Ébauche|' .. mw.text.nowiki('{{ébauche}}') .. ']] n’est pas [[Aide:Ébauche/Aide paramètres|défini]].', | ||
erreurEbaucheType = 'le thème « %s » doit apparaître en tête de liste du modèle [[Modèle:Ébauche|{{ébauche}}]].', | erreurEbaucheType = 'le thème « %s » doit apparaître en tête de liste du modèle [[Modèle:Ébauche|' .. mw.text.nowiki('{{ébauche}}') .. ']].', | ||
ebaucheImage = '<span style="white-space:nowrap;word-spacing:5px">%s</span>', | ebaucheImage = '<span style="white-space:nowrap;word-spacing:5px">%s</span>', | ||
ebaucheTitre = '%s est une [[Aide:Ébauche|ébauche]].', | ebaucheTitre = '%s est une [[Aide:Ébauche|ébauche]].', | ||
| Ligne 33 : | Ligne 35 : | ||
-- CSS inline pour éviter FOUC sur le site mobile | -- CSS inline pour éviter FOUC sur le site mobile | ||
-- [2025-03-08] notes ultérieures : | |||
-- * le CSS mobile est dorénavant chargé en synchrone (et dans tous les cas à l'avenir, hors de question de repasser en asynchrone), donc il n'y a en théorie plus de problématique de FOUC | |||
-- * ce code (du CSS inline) a pour effet de bord inattendu de rendre ineffectif le masquage des icônes sur mobile, cf. [[Spécial:Lien permanent/223683963#L-384]] et [[Discussion MediaWiki:Common.css/Archive 1#Disparition inexpliquées]] | |||
-- * pas simple... mais si ça se trouve, à la condition que l'on souhaite bien masquer les icônes sur mobile, il suffirait de virer cette rustine maintenant qu'elle n'est théoriquement plus nécessaire | |||
-- * néanmoins, certaines autres icônes que celles des bandeaux d'homonymie seraient peut-être aussi souhaitables, je pense notamment à celles des bandeaux d'ébauches | |||
local rustineFoucMobile = { | local rustineFoucMobile = { | ||
['display'] = 'table-cell', | ['display'] = 'table-cell', | ||
| Ligne 66 : | Ligne 73 : | ||
:addClass(classData.formes[args.forme] or cfg.forme) | :addClass(classData.formes[args.forme] or cfg.forme) | ||
:addClass(classData.niveau[args.niveau] or cfg.niveau) | :addClass(classData.niveau[args.niveau] or cfg.niveau) | ||
:addClass(args.class) | |||
:cssText(args.style) | if args.class and args.class ~= '' then | ||
res:addClass(args.class) | |||
end | |||
if args.style and args.style ~= '' then | |||
res:cssText(args.style) | |||
end | |||
if yesno(args.centrer) then | if yesno(args.centrer) then | ||
| Ligne 93 : | Ligne 106 : | ||
end | end | ||
local taille = args['taille icône'] or cfg.tailleIcone | local taille = args['taille icône'] or cfg.tailleIcone | ||
iconeWiki = cfg.formatLien:format(icone, taille, alt) | local classeIcone = args['classe icône'] or args.classeIcone or '' | ||
iconeWiki = cfg.formatLien:format(icone, taille, alt, classeIcone) | |||
end | end | ||
cells | cells | ||
| Ligne 157 : | Ligne 171 : | ||
:newline() | :newline() | ||
:newline() | :newline() | ||
:wikitext(texte) | :tag('div') | ||
:addClass('nomobile') | |||
:newline() | |||
:newline() | |||
:wikitext(texte) | |||
end | end | ||
| Ligne 167 : | Ligne 185 : | ||
['icône'] = trim(args['icône']) or trim(args['icône-complexe']) or args.niveau, | ['icône'] = trim(args['icône']) or trim(args['icône-complexe']) or args.niveau, | ||
alt = args.alt or args['légende'], | alt = args.alt or args['légende'], | ||
classeIcone = args['classe icône'] or args.classeIcone or '', | |||
['domaine public'] = args['domaine public'], | ['domaine public'] = args['domaine public'], | ||
texte = tostring(htmlTexte), | texte = tostring(htmlTexte), | ||
| Ligne 198 : | Ligne 217 : | ||
alt = alt .. '|link=' | alt = alt .. '|link=' | ||
end | end | ||
iconeWiki = cfg.formatLien:format(icone, 'text-top|20x17', alt) | local classeIcone = args['classe icône'] or '' | ||
iconeWiki = cfg.formatLien:format(icone, 'text-top|20x17', alt, classeIcone) | |||
end | end | ||
res :tag('div') | res :tag('div') | ||
| Ligne 224 : | Ligne 244 : | ||
end | end | ||
-- fonction qui | -- fonction qui récupère la ou les tables d'ébauche correspondant au thème | ||
local function getEbaucheTable( paramEbauche, theme, feminin ) | local function getEbaucheTable( paramEbauche, theme, feminin ) | ||
-- suprime les marques de direction ltr | -- suprime les marques de direction ltr | ||
theme = theme:gsub( '\226\128\142', '' ):gsub( '_', ' ' ) | theme = theme:gsub( '\226\128\142', '' ):gsub( '_', ' ' ) | ||
-- | -- récupère les paramètres lié au theme, à partir du module:Bandeau/Ébauche | ||
local params = {} | local params = {} | ||
local ebauche = paramEbauche[ theme ] or paramEbauche[ inverserCasse( theme ) ] | local ebauche = paramEbauche[ theme ] or paramEbauche[ inverserCasse( theme ) ] | ||
| Ligne 234 : | Ligne 254 : | ||
-- teste si l'un des mots du thème correspond à un adjectif existant | -- teste si l'un des mots du thème correspond à un adjectif existant | ||
for adj in theme:gmatch( ' ([^ ]+)' ) do | for adj in theme:gmatch( ' ([^ ]+)' ) do | ||
paramsAdj = getEbaucheTable( paramEbauche, adj, feminin ) | local paramsAdj = getEbaucheTable( paramEbauche, adj, feminin ) | ||
if paramsAdj and paramsAdj.adjectif == true then | if paramsAdj and paramsAdj.adjectif == true then | ||
local nom = theme:gsub( ' ' .. adj:gsub( '(%p)', '%%%1'), '' ) | local nom = theme:gsub( ' ' .. adj:gsub( '(%p)', '%%%1'), '' ) | ||
| Ligne 304 : | Ligne 324 : | ||
-- fonction qui retourne la valeur de param pour l'ébauche i, ou une valeur par défaut | -- fonction qui retourne la valeur de param pour l'ébauche i, ou une valeur par défaut | ||
local ebaucheParam = function( i, param ) | local ebaucheParam = function( i, param ) | ||
if ebauches[ i ] and ebauches[ i ][ param ] ~= nil then | |||
return ebauches[ i ][ param ] | |||
else | |||
return paramEbauche[''][ param ] | |||
end | |||
end | end | ||
| Ligne 334 : | Ligne 358 : | ||
local alt = '' | local alt = '' | ||
if ebauche.icone then | if ebauche.icone then | ||
local image = cfg.formatLien:format( ebauche.icone, tailleIcone, alt ) | local classeIcone = ebauche.classeIcone or '' | ||
local image = cfg.formatLien:format( ebauche.icone, tailleIcone, alt, classeIcone ) | |||
table.insert( images, image ) | table.insert( images, image ) | ||
end | end | ||
| Ligne 352 : | Ligne 377 : | ||
end | end | ||
-- | -- récupère les différents noms de thème | ||
if ebauche.adjectif and #titres > 0 then | if ebauche.adjectif and #titres > 0 then | ||
local sujet = ebauche.sujet or ebauche.nom | local sujet = ebauche.sujet or ebauche.nom | ||
| Ligne 411 : | Ligne 436 : | ||
theme.icone, | theme.icone, | ||
tailleIcone, | tailleIcone, | ||
theme.altIcone or ( 'image illustrant ' .. theme.sujet ) | theme.altIcone or ( 'image illustrant ' .. theme.sujet ), | ||
theme.classeIcone or '' | |||
) | ) | ||
end | end | ||
| Ligne 433 : | Ligne 459 : | ||
-- mise en forme du texte | -- mise en forme du texte | ||
local texte | local texte | ||
if #ebauches == 0 then | local message = ebaucheParam( 1, 'message' ) | ||
local selon = ebaucheParam( 1, 'selon' ) | |||
if #ebauches == 0 or selon == '' then | |||
if not message:match( '[.,;:!?]$' ) then | |||
message = message .. '.' | |||
end | |||
texte = message | |||
else | else | ||
-- ajout d'un point si le paramètre selon commence par un retour ligne ou une majuscule | -- ajout d'un point si le paramètre selon commence par un retour ligne ou une majuscule | ||
if message: | if not message:match( '[.,;:!?]$' ) and ( selon:match( '^<[bB][rR] */?>' ) or mw.ustring.match( selon, '^%u' ) ) then | ||
message = message .. '.' | |||
end | |||
if not selon:match( '[.,;:!?]$' ) then | |||
selon = selon .. '.' | |||
end | end | ||
texte = message .. ' ' .. selon | |||
end | end | ||
-- ajout d'un texte s'il y a une liste de tâches | -- ajout d'un texte s'il y a une liste de tâches | ||
| Ligne 465 : | Ligne 496 : | ||
-- concaténation des différentes catégories (pas de catégorisation si nocat, ou page de discussion, ou espace utilisateur) | -- concaténation des différentes catégories (pas de catégorisation si nocat, ou page de discussion, ou espace utilisateur) | ||
local categ = '' | local categ = '' | ||
if not ( yesno( args.nocat, true, false ) or page.isTalkPage or page.namespace == 2 ) then | if not ( yesno( args.nocat, true, false ) or page.isTalkPage or page.namespace == 2 ) then | ||
for i = 1, #categs do | if #categs > 0 then | ||
for i = 1, #categs do | |||
categs[ i ] = cfg.ebaucheCateg:format( categs[ i ] ) | |||
end | |||
categ = table.concat( categs ):gsub( ' <[^>]*>', '' ) | |||
else | |||
categ = cfg.ebaucheCateg:format('') | categ = cfg.ebaucheCateg:format('') | ||
end | end | ||
end | |||
local messageErreur = '' | |||
if #gestionErreur > 0 then | |||
messageErreur = table.concat( gestionErreur ) | |||
if page.namespace == 2 then | |||
messageErreur = messageErreur .. '[[Catégorie:Ébauche inconnue dans une page utilisateur]]' | |||
else | |||
messageErreur = messageErreur .. '[[Catégorie:Ébauche inconnue]]' | messageErreur = messageErreur .. '[[Catégorie:Ébauche inconnue]]' | ||
end | end | ||
end | end | ||
return p._bandeauAvertissement( parametres ) .. categ .. messageErreur | |||
return p._bandeauAvertissement( parametres ) .. | |||
end | end | ||
| Ligne 512 : | Ligne 548 : | ||
local t = getEbaucheTable( paramEbauche, theme ) | local t = getEbaucheTable( paramEbauche, theme ) | ||
local tF, tAdjF = getEbaucheTable( paramEbauche, theme, true ) | local tF, tAdjF = getEbaucheTable( paramEbauche, theme, true ) | ||
if t.feminin and | if t and tF and t.feminin and tF.categ == t.categ then | ||
if tAdjF then | if tAdjF then | ||
themeF = tF.nom .. ' ' .. tAdjF.feminin | themeF = tF.nom .. ' ' .. tAdjF.feminin | ||
else | |||
themeF = tF.nom | themeF = tF.nom | ||
end | end | ||
| Ligne 530 : | Ligne 566 : | ||
local currentFrame = mw.getCurrentFrame() | local currentFrame = mw.getCurrentFrame() | ||
local languageObj = mw.getContentLanguage() | local languageObj = mw.getContentLanguage() | ||
function pagesInCategory( category ) | local function pagesInCategory( category ) | ||
return languageObj:formatNum( tonumber( currentFrame:callParserFunction( 'PAGESINCATEGORY', { category, 'R' } ) ) ) | return languageObj:formatNum( tonumber( currentFrame:callParserFunction( 'PAGESINCATEGORY', { category, 'R' } ) ) ) | ||
end | end | ||
| Ligne 579 : | Ligne 615 : | ||
:insert('</td><td>') | :insert('</td><td>') | ||
if ebauche.icone then | if ebauche.icone then | ||
wikiTab:insert( cfg.formatLien:format( ebauche.icone, '45x35', ebauche.altIcone or '' ) ) | wikiTab:insert( cfg.formatLien:format( ebauche.icone, '45x35', ebauche.altIcone or '', ebauche.classeIcone or '' ) ) | ||
end | end | ||
wikiTab | wikiTab | ||
| Ligne 622 : | Ligne 658 : | ||
if ebauche.icone then | if ebauche.icone then | ||
wikiTab | wikiTab | ||
:insert( cfg.formatLien:format( ebauche.icone, '45x35', ebauche.altIcone or '' ) ) | :insert( cfg.formatLien:format( ebauche.icone, '45x35', ebauche.altIcone or '', ebauche.classeIcone or '' ) ) | ||
end | end | ||
wikiTab | wikiTab | ||
| Ligne 656 : | Ligne 692 : | ||
:insert('</td><td>') | :insert('</td><td>') | ||
if ebauche.icone then | if ebauche.icone then | ||
wikiTab:insert( cfg.formatLien:format( ebauche.icone, '45x35', ebauche.altIcone or '' ) ) | wikiTab:insert( cfg.formatLien:format( ebauche.icone, '45x35', ebauche.altIcone or '', ebauche.classeIcone or '' ) ) | ||
end | end | ||
wikiTab | wikiTab | ||
Dernière version du 21 février 2026 à 23:31
La documentation pour ce module peut être créée à Module:Bandeau/doc
-- luacheck: globals mw, no max line length
--Ce module implémente les modèles de bandeau.
--Standardisation des bandeaux ([[Catégorie:Modèle de bandeau]]).
--Créer une fonction exportable pour le modèle {{Bandeau}} (ns:all).
--Créer une fonction exportable pour les bandeaux d'article (ns:0).
--Créer une fonction exportable pour les bandeaux de section (ns:0).
--Créer une fonction exportable pour les bandeaux d'ébauche (ns:0).
--Créer une fonction exportable pour les bandeaux de discussion (ns:1).
--Créer une fonction exportable pour les bandeaux système (ns:8).
--Gérer les images multiples.
local p = {}
local trim = require('Module:Outils').trim
local yesno = require('Module:yesno')
local classData = mw.loadData('Module:Bandeau/Class')
local moduleEbauche = 'Module:Bandeau/Ébauche'
-- local paramEbauche = mw.loadData(moduleEbauche) -- ne sera chargé que pour un bandeau d'ébauche.
local cfg = {
forme = 'bandeau-simple',
niveau = 'bandeau-niveau-neutre',
formatLien = '[[Fichier:%s|%spx|alt=%s|class=noviewer %s]]',
tailleIcone = '45x45',
erreurArgument = 'Paramètre <code>|%s=</code> manquant',
erreurEbaucheParam = 'le thème « %s » du modèle [[Modèle:Ébauche|' .. mw.text.nowiki('{{ébauche}}') .. ']] n’est pas [[Aide:Ébauche/Aide paramètres|défini]].',
erreurEbaucheType = 'le thème « %s » doit apparaître en tête de liste du modèle [[Modèle:Ébauche|' .. mw.text.nowiki('{{ébauche}}') .. ']].',
ebaucheImage = '<span style="white-space:nowrap;word-spacing:5px">%s</span>',
ebaucheTitre = '%s est une [[Aide:Ébauche|ébauche]].',
ebaucheTitreSujet = '%s est une [[Aide:Ébauche|ébauche]] concernant %s.',
ebaucheCateg = '[[Catégorie:Wikipédia:ébauche %s]]',
}
-- CSS inline pour éviter FOUC sur le site mobile
-- [2025-03-08] notes ultérieures :
-- * le CSS mobile est dorénavant chargé en synchrone (et dans tous les cas à l'avenir, hors de question de repasser en asynchrone), donc il n'y a en théorie plus de problématique de FOUC
-- * ce code (du CSS inline) a pour effet de bord inattendu de rendre ineffectif le masquage des icônes sur mobile, cf. [[Spécial:Lien permanent/223683963#L-384]] et [[Discussion MediaWiki:Common.css/Archive 1#Disparition inexpliquées]]
-- * pas simple... mais si ça se trouve, à la condition que l'on souhaite bien masquer les icônes sur mobile, il suffirait de virer cette rustine maintenant qu'elle n'est théoriquement plus nécessaire
-- * néanmoins, certaines autres icônes que celles des bandeaux d'homonymie seraient peut-être aussi souhaitables, je pense notamment à celles des bandeaux d'ébauches
local rustineFoucMobile = {
['display'] = 'table-cell',
['padding-right'] = '0.5em',
}
local function erreur(texte, formatstring, tag)
local res = mw.html.create(tag or 'span')
res :addClass('error')
:wikitext('Erreur : ')
if formatstring then
res:wikitext(formatstring:format(texte))
else
res:wikitext(texte)
end
return tostring(res)
end
function p._bandeau(args)
local res = mw.html.create('div')
local cells = mw.html.create()
local icone = trim(args.image) or trim(args['icône'])
local backgroundIcone = icone and classData.icones[icone:gsub('_', ' ')] or false
local texte = (trim(args.texte) or erreur('texte', cfg.erreurArgument))
if args.id and args.id ~= '' then
res:attr('id', args.id)
end
res :addClass('bandeau-container metadata')
:addClass(classData.formes[args.forme] or cfg.forme)
:addClass(classData.niveau[args.niveau] or cfg.niveau)
if args.class and args.class ~= '' then
res:addClass(args.class)
end
if args.style and args.style ~= '' then
res:cssText(args.style)
end
if yesno(args.centrer) then
cells = mw.html.create('div')
:addClass('bandeau-centrer')
elseif trim(args.droite) then
cells = mw.html.create('div')
:css{ display = 'table', width = '100%' }
end
if args['icône bma'] and args['icône bma'] ~= 'non' then
if args['icône bma'] == 'oui' then
cells:wikitext( mw.getCurrentFrame():expandTemplate{ title = 'Bma' } )
else
cells:wikitext( mw.getCurrentFrame():expandTemplate{ title = 'Bma', args = {args['icône bma']} } )
end
end
if icone and not backgroundIcone then
local iconeWiki = icone
if not icone:match('%[') then
local alt = args.alt or args['légende'] or ''
if yesno( args['domaine public'] ) then
alt = alt .. '|link='
end
local taille = args['taille icône'] or cfg.tailleIcone
local classeIcone = args['classe icône'] or args.classeIcone or ''
iconeWiki = cfg.formatLien:format(icone, taille, alt, classeIcone)
end
cells
:tag('div')
:addClass('bandeau-cell bandeau-icone')
:css(rustineFoucMobile)
:wikitext(iconeWiki)
end
cells
:tag('div')
:addClass('bandeau-cell')
:css(rustineFoucMobile)
:addClass(backgroundIcone and ('bandeau-icone-css ' .. backgroundIcone) or nil)
:newline() -- sert à la génération automatique de <p> encadrant le contenu
:wikitext(texte)
:newline() -- sert à la génération automatique de <p> encadrant le contenu
if trim(args.droite) then
cells
:tag('div')
:addClass('bandeau-cell')
:css(rustineFoucMobile)
:css( 'padding-left', '1em' )
:newline()
:wikitext(args.droite)
end
res :node(cells)
if trim(args['supplément']) then
res :tag('div')
:wikitext(args['supplément'])
end
return tostring(res)
end
function p._bandeauAvertissement(args)
local htmlTexte = mw.html.create()
local titre = trim(args.titre) or erreur('titre', cfg.erreurArgument)
local suffixeDate = trim(args.date)
if suffixeDate then
-- pour rendre insécable, seulement si le paramètre semble bien être une date valide
suffixeDate = (require 'Module:Date').modeleDate{suffixeDate, nolinks=true, afficherErreurs=false, categoriserErreurs=false}
titre = titre:gsub('%.$', '')
suffixeDate = ' <small>(' .. suffixeDate .. ').</small>'
elseif not titre:match('[.,;:!?]$') then
titre = titre .. '.'
end
htmlTexte
:tag('strong')
:addClass('bandeau-titre')
:wikitext(titre)
:done()
:wikitext(suffixeDate)
local texte = trim(args.texte)
if texte then
htmlTexte
:newline()
:newline()
:tag('div')
:addClass('nomobile')
:newline()
:newline()
:wikitext(texte)
end
local parametres = {
forme = 'article',
niveau = args.niveau,
id = args.id,
class = args.class,
['icône'] = trim(args['icône']) or trim(args['icône-complexe']) or args.niveau,
alt = args.alt or args['légende'],
classeIcone = args['classe icône'] or args.classeIcone or '',
['domaine public'] = args['domaine public'],
texte = tostring(htmlTexte),
['icône bma'] = args['icône bma'],
['supplément'] = args['supplément'],
}
return p._bandeau(parametres)
end
--[[
TODO - fusionner ces deux méthodes :
* p._bandeau() avec forme=section
* p._bandeauSection()
]]--
function p._bandeauSection(args)
local res = mw.html.create('div')
local icone = trim(args.image) or trim(args['icône'])
local backgroundIcone = icone and classData.icones[icone:gsub('_', ' ')] or false
local texte = (trim(args.texte) or erreur('texte', cfg.erreurArgument))
res :addClass('bandeau-container bandeau-section metadata')
:addClass(classData.niveau[args.niveau] or cfg.niveau)
if icone and not backgroundIcone then
local iconeWiki = icone
if not icone:match('%[') then
local alt = args.alt or args['légende'] or ''
if yesno( args['domaine public'] ) then
alt = alt .. '|link='
end
local classeIcone = args['classe icône'] or ''
iconeWiki = cfg.formatLien:format(icone, 'text-top|20x17', alt, classeIcone)
end
res :tag('div')
:addClass('bandeau-cell bandeau-icone')
:wikitext(iconeWiki)
end
res :tag('div')
:addClass('bandeau-cell')
:addClass(backgroundIcone and ('bandeau-icone-css ' .. backgroundIcone) or nil)
:wikitext(texte)
return tostring(res)
end
-- fonction qui inverse la casse du premier caractère d'une chaine
local function inverserCasse( str )
if type( str ) == 'string' then
local premierCar = mw.ustring.sub( str, 1, 1 )
if mw.ustring.lower( premierCar ) == premierCar then
return mw.ustring.upper( premierCar ) .. mw.ustring.sub( str, 2 )
else
return mw.ustring.lower( premierCar ) .. mw.ustring.sub( str, 2 )
end
end
end
-- fonction qui récupère la ou les tables d'ébauche correspondant au thème
local function getEbaucheTable( paramEbauche, theme, feminin )
-- suprime les marques de direction ltr
theme = theme:gsub( '\226\128\142', '' ):gsub( '_', ' ' )
-- récupère les paramètres lié au theme, à partir du module:Bandeau/Ébauche
local params = {}
local ebauche = paramEbauche[ theme ] or paramEbauche[ inverserCasse( theme ) ]
if not ebauche and theme:find( ' ' ) then
-- teste si l'un des mots du thème correspond à un adjectif existant
for adj in theme:gmatch( ' ([^ ]+)' ) do
local paramsAdj = getEbaucheTable( paramEbauche, adj, feminin )
if paramsAdj and paramsAdj.adjectif == true then
local nom = theme:gsub( ' ' .. adj:gsub( '(%p)', '%%%1'), '' )
params = getEbaucheTable( paramEbauche, nom, feminin )
if params then
return params, paramsAdj
end
end
end
-- aucun mot ne correspond à un adjectif, on essait une autre methode pour trouver une correspondance avec plusieurs mots
if theme:find( ' .+ ' ) then
for adj, paramsAdj in pairs( paramEbauche ) do
if paramsAdj.adjectif == true and theme:find( ' ' .. adj, 2, true ) then
local nom = theme:gsub( ' ' .. adj:gsub( '(%p)', '%%%1'), '' )
params = getEbaucheTable( paramEbauche, nom, feminin )
if params then
return params, paramsAdj
end
end
end
end
end
if feminin and ebauche and ebauche.feminin then
ebauche = paramEbauche[ ebauche.feminin ]
end
if ebauche then
for n, v in pairs( ebauche ) do
params[ n ] = v
end
else
params = nil
end
return params, nil
end
p.getEbaucheTable = getEbaucheTable
local function femininFromWikidata()
local entity = mw.wikibase.getEntity()
if entity then
local p31 = entity:getBestStatements( 'P31' )
local estHumain = type( p31 ) == 'table'
and #p31 == 1
and type( p31[ 1 ].mainsnak ) == 'table'
and type( p31[ 1 ].mainsnak.datavalue ) == 'table'
and type( p31[ 1 ].mainsnak.datavalue.value ) == 'table'
and p31[ 1 ].mainsnak.datavalue.value['numeric-id'] == 5
local p21 = entity:getBestStatements( 'P21' )
local estFeminin = type( p21 ) == 'table'
and #p21 == 1
and type( p21[ 1 ].mainsnak ) == 'table'
and type( p21[ 1 ].mainsnak.datavalue ) == 'table'
and type( p21[ 1 ].mainsnak.datavalue.value ) == 'table'
and p21[ 1 ].mainsnak.datavalue.value['numeric-id'] == 6581072
return estHumain, estFeminin
end
return false, false
end
p['_ébauche'] = function ( args )
local paramEbauche = mw.loadData( moduleEbauche )
local page = mw.title.getCurrentTitle()
local ebauches, gestionErreur = {}, {}
local humain, feminin = femininFromWikidata()
if args['féminin'] and args['féminin'] ~= '' then
feminin = yesno( args['féminin'], true )
end
local estFeminin
-- fonction qui retourne la valeur de param pour l'ébauche i, ou une valeur par défaut
local ebaucheParam = function( i, param )
if ebauches[ i ] and ebauches[ i ][ param ] ~= nil then
return ebauches[ i ][ param ]
else
return paramEbauche[''][ param ]
end
end
-- récupération des paramètres de tous les thèmes
for i, theme in ipairs( args ) do
theme = trim( theme )
if theme then
local t, tAdj = getEbaucheTable( paramEbauche, theme, feminin )
if t then
table.insert( ebauches, t )
table.insert( ebauches, tAdj )
else
table.insert(
gestionErreur,
erreur( theme, cfg.erreurEbaucheParam, 'div' )
)
end
end
end
-- récupération des différents titres, images et catégories
local images, titres, categs = {}, {}, {}
local tailleIcone = '45x35'
if #ebauches > 3 then
tailleIcone = '35x25'
end
for i, ebauche in ipairs( ebauches ) do
-- création du lien de l'image
local alt = ''
if ebauche.icone then
local classeIcone = ebauche.classeIcone or ''
local image = cfg.formatLien:format( ebauche.icone, tailleIcone, alt, classeIcone )
table.insert( images, image )
end
if math.fmod( #ebauches, 3 ) == 1 and ( #ebauches - i ) == 2
or math.fmod( i, 3 ) == 0 and ( #ebauches - i ) > 1
then
-- sur plusieurs lignes s'il y a plus de 3 images, avec minimum deux images sur la dernière ligne
table.insert( images, '<br> ' )
end
if i > 1 and ebauche.type and ebauche.type ~= paramEbauche[''].type then
-- remplace "Cet article par "Ce portail" ou autre en fonction du premier thème
table.insert(
gestionErreur,
erreur( ebauche.nom, cfg.erreurEbaucheType, 'div' )
)
end
-- récupère les différents noms de thème
if ebauche.adjectif and #titres > 0 then
local sujet = ebauche.sujet or ebauche.nom
if estFeminin then
sujet = ebauche.sujetF or sujet:gsub(
ebauche.nom:gsub( '(%p)', '%%%1') .. '%f[%W]',
ebauche.feminin
)
end
-- ajout du sujet de l'adjectif dans le sujet de l'ébauche précédente
local titre, subst = titres[ #titres ]:gsub(
'<(adj[^>]*)>',
{ adjectif = sujet, adj = ebauche.nom, adjF = ebauche.feminin }
)
if subst > 0 then
titres[ #titres ] = titre
else
titres[ #titres ] = titre .. ' ' .. sujet
end
else
table.insert( titres, ebauche.sujet )
estFeminin = ebauche.estFeminin or ( ebauche.sujet == '' and estFeminin )
end
-- mise en forme des catégories
if ebauche.adjectif then
-- tentative d'ajout du nom de l'adjectif dans les catégories précédentes
local modif = false
for k, v in ipairs( categs ) do
local cat, subst = v:gsub(
'<(adj[^>]*)>',
{ adj = ebauche.nom, adjF = ebauche.feminin, adjectif = ebauche.nom }
)
if subst == 0 then
cat = v .. ' ' .. ebauche.nom
end
if mw.title.new( 'Catégorie:Wikipédia:ébauche ' .. cat ).exists then
categs[ k ] = cat
modif = true
end
end
if not modif
and humain
and mw.title.new( 'Catégorie:Wikipédia:ébauche personnalité ' .. ebauche.feminin ).exists
then
table.insert( categs, 'personnalité ' .. ebauche.feminin )
end
end
table.insert( categs, ebauche.categ )
end
-- mise en forme des images
local image
if args['icône'] and args['icône'] ~= '' then
local theme = getEbaucheTable( paramEbauche, args['icône'] )
if theme and theme.icone then
image = cfg.formatLien:format(
theme.icone,
tailleIcone,
theme.altIcone or ( 'image illustrant ' .. theme.sujet ),
theme.classeIcone or ''
)
end
elseif #images == 1 then
image = images[ 1 ]
elseif #images > 1 then
image = cfg.ebaucheImage:format( table.concat( images, ' ' ) )
end
-- mise en forme du titre
local titre
if #titres > 0 then
titre = cfg.ebaucheTitreSujet:format(
ebaucheParam( 1, 'type' ),
mw.text.listToText( titres )
)
else
titre = cfg.ebaucheTitre:format( ebaucheParam( 1, 'type' ) )
end
-- mise en forme du texte
local texte
local message = ebaucheParam( 1, 'message' )
local selon = ebaucheParam( 1, 'selon' )
if #ebauches == 0 or selon == '' then
if not message:match( '[.,;:!?]$' ) then
message = message .. '.'
end
texte = message
else
-- ajout d'un point si le paramètre selon commence par un retour ligne ou une majuscule
if not message:match( '[.,;:!?]$' ) and ( selon:match( '^<[bB][rR] */?>' ) or mw.ustring.match( selon, '^%u' ) ) then
message = message .. '.'
end
if not selon:match( '[.,;:!?]$' ) then
selon = selon .. '.'
end
texte = message .. ' ' .. selon
end
-- ajout d'un texte s'il y a une liste de tâches
local todo = page.talkPageTitle and mw.title.new( page.talkPageTitle.fullText .. '/À faire' ) or nil
if todo and todo.exists then
texte = texte .. '\n\n'
.. 'Consultez la liste des <b>tâches à accomplir</b> en [['
.. page.talkPageTitle.prefixedText
.. '|page de discussion]].'
end
-- paramètres pour le bandeau
local parametres = {
niveau = 'ébauche',
['icône'] = image,
titre = titre:gsub( ' <adj[^>]*>', '' ),
texte = texte,
id = args.id
}
-- concaténation des différentes catégories (pas de catégorisation si nocat, ou page de discussion, ou espace utilisateur)
local categ = ''
if not ( yesno( args.nocat, true, false ) or page.isTalkPage or page.namespace == 2 ) then
if #categs > 0 then
for i = 1, #categs do
categs[ i ] = cfg.ebaucheCateg:format( categs[ i ] )
end
categ = table.concat( categs ):gsub( ' <[^>]*>', '' )
else
categ = cfg.ebaucheCateg:format('')
end
end
local messageErreur = ''
if #gestionErreur > 0 then
messageErreur = table.concat( gestionErreur )
if page.namespace == 2 then
messageErreur = messageErreur .. '[[Catégorie:Ébauche inconnue dans une page utilisateur]]'
else
messageErreur = messageErreur .. '[[Catégorie:Ébauche inconnue]]'
end
end
return p._bandeauAvertissement( parametres ) .. categ .. messageErreur
end
---
-- fonction retournant un paramètre d'une table d'ébauche.
-- Elle est prévue pour être appelée directement par #invoke:
-- avec pour paramètres le thème et le paramètre désiré
-- Cette fonction est principalement destinée à la page d'aide.
function p.parametreEbauche( frame )
local paramEbauche = mw.loadData( moduleEbauche )
local theme = frame.args[1]
local param = frame.args[2]
if paramEbauche[ theme ] then
return paramEbauche[ theme ][ param ]
elseif paramEbauche[ inverserCasse( theme ) ] then
return paramEbauche[ inverserCasse( theme ) ][ param ]
end
end
---
-- Fonction retournant le féminin d'un théme d'ébauche
-- Elle est prévue pour être appelée directement par #invoke:
-- avec pour paramètres le thème et le paramètre désiré
-- Cette fonction est principalement destinée au modèle {{Catégorie d'ébauche}}, donc une valeur n'est retournée que si les catégories sont identiques
function p.femininEbauche( frame )
local paramEbauche = mw.loadData( moduleEbauche )
local theme = frame.args[1]
local themeF
if theme then
local t = getEbaucheTable( paramEbauche, theme )
local tF, tAdjF = getEbaucheTable( paramEbauche, theme, true )
if t and tF and t.feminin and tF.categ == t.categ then
if tAdjF then
themeF = tF.nom .. ' ' .. tAdjF.feminin
else
themeF = tF.nom
end
return themeF
end
end
end
---
-- fonction qui contruit deux tableaux récapitulatif de l'ensemble des paramètres d'ébauche
function p.tableParametresEbauches( frame )
local paramEbauche = mw.loadData( moduleEbauche )
local currentFrame = mw.getCurrentFrame()
local languageObj = mw.getContentLanguage()
local function pagesInCategory( category )
return languageObj:formatNum( tonumber( currentFrame:callParserFunction( 'PAGESINCATEGORY', { category, 'R' } ) ) )
end
local params, paramAdj, paramType = {}, {}, {}
for clef, ebauche in pairs( paramEbauche ) do
local kEbauche = {}
for k, v in pairs( ebauche ) do
kEbauche[ k ] = v
end
kEbauche.clef = clef
if ebauche.type then
table.insert( paramType, kEbauche )
elseif ebauche.adjectif then
if clef == ebauche.nom or clef ~= ebauche.feminin then
table.insert( paramAdj, kEbauche )
end
else
table.insert( params, kEbauche )
end
end
local comp = function( eb1, eb2 )
return eb1.clef < eb2.clef
end
table.sort( params, comp )
table.sort( paramAdj, comp )
table.sort( paramType, comp )
local wikiTab = { '<table class="wikitable sortable" style="table-layout:fixed;">' }
wikiTab.insert = function ( t, value )
table.insert( t, value )
return t
end
wikiTab
:insert('\n=== Ébauches normales ===\n')
:insert('<caption>Liste des paramètres d\'ébauche</caption>')
:insert('<th scope=col style="width:15%;">nom</th>')
:insert('<th scope=col style="width:50px; box-sizing:border-box;">i</th>')
:insert('<th scope=col style="width:20%;">sujet</th>')
:insert('<th scope=col style="width:20%;">catégorie</th>')
:insert('<th scope=col style="width:20%;">compteur</th>')
:insert('<th scope=col>selon</th>')
for k, ebauche in ipairs( params ) do
wikiTab
:insert('<tr><td>')
:insert( ebauche.clef )
:insert('</td><td>')
if ebauche.icone then
wikiTab:insert( cfg.formatLien:format( ebauche.icone, '45x35', ebauche.altIcone or '', ebauche.classeIcone or '' ) )
end
wikiTab
:insert('</td><td>')
:insert( ebauche.sujet )
:insert('</td><td>')
if ebauche.categ then
wikiTab
:insert( '[[:Catégorie:Wikipédia:ébauche ' .. ebauche.categ .. '|' .. ebauche.categ .. ']]' )
end
wikiTab
:insert('</td><td>')
if ebauche.categ then
wikiTab
:insert( pagesInCategory( 'Wikipédia:ébauche ' .. ebauche.categ ) )
end
wikiTab
:insert('</td><td>')
:insert( ebauche.selon )
:insert('</td></tr>')
end
wikiTab:insert('</table>')
-- seconde table pour les adjectifs
wikiTab
:insert('\n=== Adjectifs ===\n')
:insert('<table class="wikitable">')
:insert('<caption>Liste des adjectifs</caption>')
:insert('<th scope=col>adjectif</th>')
:insert('<th scope=col>féminin</th>')
:insert('<th scope=col style="width:50px;">icone</th>')
:insert('<th scope=col>sujet</th>')
:insert('<th scope=col>sujet féminin</th>')
:insert('<th scope=col>catégorie</th>')
for k, ebauche in ipairs( paramAdj ) do
wikiTab
:insert('<tr><td>')
:insert( ebauche.clef )
:insert('</td><td>')
:insert( ebauche.feminin )
:insert('</td><td>')
if ebauche.icone then
wikiTab
:insert( cfg.formatLien:format( ebauche.icone, '45x35', ebauche.altIcone or '', ebauche.classeIcone or '' ) )
end
wikiTab
:insert('</td><td>')
:insert( ebauche.sujet )
:insert('</td><td>')
:insert( ebauche.sujetF or ebauche.sujet:gsub( ebauche.nom .. '%f[%W]', ebauche.feminin ) )
:insert('</td><td>')
if ebauche.categ then
wikiTab
:insert( '[[:Catégorie:Wikipédia:ébauche ' .. ebauche.categ .. '|' .. ebauche.categ .. ']]' )
end
wikiTab
:insert('</td></tr>')
end
wikiTab:insert('</table>')
-- troisième table pour les types
wikiTab
:insert('\n=== Types ===\n')
:insert('<table class="wikitable">')
:insert('<caption>Liste des paramètres de type</caption>')
:insert('<th scope=col style="width:15%;">nom</th>')
:insert('<th scope=col style="width:50px;">icone</th>')
:insert('<th scope=col style="width:20%;">type</th>')
:insert('<th scope=col style="width:15%;">sujet</th>')
:insert('<th scope=col style="width:15%;">catégorie</th>')
:insert('<th scope=col>message</th>')
for k, ebauche in ipairs( paramType ) do
wikiTab
:insert('<tr><td>')
:insert( ebauche.clef )
:insert('</td><td>')
if ebauche.icone then
wikiTab:insert( cfg.formatLien:format( ebauche.icone, '45x35', ebauche.altIcone or '', ebauche.classeIcone or '' ) )
end
wikiTab
:insert('</td><td>')
:insert ( ebauche.type )
:insert('</td><td>')
:insert( ebauche.sujet )
:insert('</td><td>')
if ebauche.categ then
wikiTab:insert( '[[:Catégorie:Wikipédia:ébauche ' .. ebauche.categ .. '|' .. ebauche.categ .. ']]' )
end
wikiTab
:insert('</td><td>')
:insert( ebauche.message )
:insert('</td></tr>')
end
wikiTab:insert('</table>')
-- parenthèses pour enlever la 2e valeur retournée par gsub (le nombre de remplacements effectués)
return (table.concat( wikiTab ):gsub( ' <adjF?>', '' ))
end
-- fonction destinée au gadget [[MediaWiki:Gadget-BandeauxEbauches.js]]
function p.listeEbauches( frame )
local paramEbauche = mw.loadData( moduleEbauche )
local liste = {}
for k in pairs( paramEbauche ) do
if k ~= "" then
table.insert( liste, k )
end
end
table.sort( liste )
return table.concat( liste, '\n' )
end
-- Insertion dans la table p des fonctions appelées par les
-- modèles à l'aide d'un adaptateur de fonction.
local function adaptateur(nomFonction)
return function (frame)
local args
if frame.args.texte or frame.args.titre then
args = frame.args
else
args = frame:getParent().args
end
return p[nomFonction](args)
end
end
local nomsFonction = {'bandeau', 'bandeauAvertissement', 'bandeauSection', 'ébauche' }
for _, nomFonction in ipairs(nomsFonction) do
p[nomFonction] = adaptateur('_' .. nomFonction)
end
return p