« Module:Bandeau » : différence entre les versions

Une page de Wikipédia, l'encyclopédie libre.
Contenu supprimé Contenu ajouté
si pas de texte, auparavant on avait le résultat voulu parce que ces newlines étaient "trimés" après que htmlTexte ait été transmis à la fonction suivante _bandeau() ; comme je fais là, on évite de reposer par chance sur ce trim
Catégorie:Ébauche inconnue contient actuellement seulement 12 pages, mais Huster a corrigé plusieurs dizaines de pages ; comme il peut être utile de repérer les pages utilisateur avec des thèmes non reconnus, mais que l'on ne veut pas polluer la catégorie, je les range dans une nouvelle sous-catégorie Catégorie:Ébauche inconnue dans une page utilisateur
 
(19 versions intermédiaires par 2 utilisateurs non affichées)
Ligne 14 : Ligne 14 :
local trim = require('Module:Outils').trim
local trim = require('Module:Outils').trim
local yesno = require('Module:yesno')
local yesno = require('Module:yesno')
local class = mw.loadData('Module:Bandeau/Class')
local classData = mw.loadData('Module:Bandeau/Class')
local moduleEbauche = 'Module:Bandeau/Ébauche'
local moduleEbauche = 'Module:Bandeau/Ébauche'
-- local paramEbauche = mw.loadData(moduleEbauche) -- ne sera chargé que pour un bandeau d'ébauche.
-- local paramEbauche = mw.loadData(moduleEbauche) -- ne sera chargé que pour un bandeau d'ébauche.
Ligne 24 : Ligne 24 :
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 56 : Ligne 56 :
local cells = mw.html.create()
local cells = mw.html.create()
local icone = trim(args.image) or trim(args['icône'])
local icone = trim(args.image) or trim(args['icône'])
local backgroundIcone = icone and class.icones[icone:gsub('_', ' ')] or false
local backgroundIcone = icone and classData.icones[icone:gsub('_', ' ')] or false
local texte = (trim(args.texte) or erreur('texte', cfg.erreurArgument))
local texte = (trim(args.texte) or erreur('texte', cfg.erreurArgument))


Ligne 63 : Ligne 63 :
end
end


res :addClass('bandeau-container')
res :addClass('bandeau-container metadata')
:addClass(class.formes[args.forme] or cfg.forme)
:addClass(classData.formes[args.forme] or cfg.forme)
:addClass(class.niveau[args.niveau] or cfg.niveau)
:addClass(classData.niveau[args.niveau] or cfg.niveau)

:addClass('plainlinks')
:addClass(args.class)
if args.class and args.class ~= '' then
:cssText(args.style)
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
cells = mw.html.create('div')
cells = mw.html.create('div')
Ligne 78 : Ligne 83 :
end
end


if args['icône bma'] == 'oui' then
if args['icône bma'] and args['icône bma'] ~= 'non' then
cells:wikitext( mw.getCurrentFrame():expandTemplate{ title = 'Bma' } )
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
end


Ligne 97 : Ligne 106 :
:css(rustineFoucMobile)
:css(rustineFoucMobile)
:wikitext(iconeWiki)
:wikitext(iconeWiki)
:done()
end
end


Ligne 108 : Ligne 116 :
:wikitext(texte)
:wikitext(texte)
:newline() -- sert à la génération automatique de <p> encadrant le contenu
:newline() -- sert à la génération automatique de <p> encadrant le contenu
:done()


if trim(args.droite) then
if trim(args.droite) then
Ligne 118 : Ligne 125 :
:newline()
:newline()
:wikitext(args.droite)
:wikitext(args.droite)
:done()
end
end

res :node(cells)
res :node(cells)
if trim(args['supplément']) then
if trim(args['supplément']) then
res :tag('div')
res :tag('div')
:wikitext(args['supplément'])
:wikitext(args['supplément'])
:done()
end
end
return tostring(res)
return tostring(res)
Ligne 138 : Ligne 143 :
if suffixeDate then
if suffixeDate then
-- pour rendre insécable, seulement si le paramètre semble bien être une date valide
-- pour rendre insécable, seulement si le paramètre semble bien être une date valide
suffixeDate = (require 'Module:Date').modeleDate{suffixeDate, nolinks=true, onerror='input'}
suffixeDate = (require 'Module:Date').modeleDate{suffixeDate, nolinks=true, afficherErreurs=false, categoriserErreurs=false}


titre = titre:gsub('%.$', '')
titre = titre:gsub('%.$', '')
Ligne 165 : Ligne 170 :
niveau = args.niveau,
niveau = args.niveau,
id = args.id,
id = args.id,
class = 'metadata ambox ' .. ( args.class or '' ),
class = args.class,
['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'],
Ligne 186 : Ligne 191 :
local res = mw.html.create('div')
local res = mw.html.create('div')
local icone = trim(args.image) or trim(args['icône'])
local icone = trim(args.image) or trim(args['icône'])
local backgroundIcone = icone and class.icones[icone:gsub('_', ' ')] or false
local backgroundIcone = icone and classData.icones[icone:gsub('_', ' ')] or false
local texte = (trim(args.texte) or erreur('texte', cfg.erreurArgument))
local texte = (trim(args.texte) or erreur('texte', cfg.erreurArgument))


res :addClass('bandeau-container bandeau-section metadata')
res :addClass('bandeau-container bandeau-section metadata')
:addClass(class.niveau[args.niveau] or cfg.niveau)
:addClass(classData.niveau[args.niveau] or cfg.niveau)

if icone and not backgroundIcone then
if icone and not backgroundIcone then
local iconeWiki = icone
local iconeWiki = icone
Ligne 204 : Ligne 209 :
:addClass('bandeau-cell bandeau-icone')
:addClass('bandeau-cell bandeau-icone')
:wikitext(iconeWiki)
:wikitext(iconeWiki)
:done()
end
end
res :tag('div')
res :tag('div')
Ligne 210 : Ligne 214 :
:addClass(backgroundIcone and ('bandeau-icone-css ' .. backgroundIcone) or nil)
:addClass(backgroundIcone and ('bandeau-icone-css ' .. backgroundIcone) or nil)
:wikitext(texte)
:wikitext(texte)
:done()


return tostring(res)
return tostring(res)
Ligne 224 : Ligne 227 :
return mw.ustring.lower( premierCar ) .. mw.ustring.sub( str, 2 )
return mw.ustring.lower( premierCar ) .. mw.ustring.sub( str, 2 )
end
end
end
end
end
end


Ligne 259 : Ligne 262 :
end
end
end
end
if feminin and ebauche and ebauche.feminin then
if feminin and ebauche and ebauche.feminin then
ebauche = paramEbauche[ ebauche.feminin ]
ebauche = paramEbauche[ ebauche.feminin ]
end
end
Ligne 300 : Ligne 303 :
local ebauches, gestionErreur = {}, {}
local ebauches, gestionErreur = {}, {}
local humain, feminin = femininFromWikidata()
local humain, feminin = femininFromWikidata()
feminin = yesno( args["féminin"], true, false ) or feminin
if args['féminin'] and args['féminin'] ~= '' then
feminin = yesno( args['féminin'], true )
end
local estFeminin
local estFeminin

-- 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 )
Ligne 318 : Ligne 323 :
else
else
table.insert(
table.insert(
gestionErreur,
gestionErreur,
erreur( theme, cfg.erreurEbaucheParam, 'div' )
erreur( theme, cfg.erreurEbaucheParam, 'div' )
)
)
Ligne 324 : Ligne 329 :
end
end
end
end

-- récupération des différents titres, images et catégories
-- récupération des différents titres, images et catégories
local images, titres, categs = {}, {}, {}
local images, titres, categs = {}, {}, {}
Ligne 338 : Ligne 343 :
table.insert( images, image )
table.insert( images, image )
end
end
if math.fmod( #ebauches, 3 ) == 1 and ( #ebauches - i ) == 2
if math.fmod( #ebauches, 3 ) == 1 and ( #ebauches - i ) == 2
or math.fmod( i, 3 ) == 0 and ( #ebauches - i ) > 1
or math.fmod( i, 3 ) == 0 and ( #ebauches - i ) > 1
then
then
Ligne 344 : Ligne 349 :
table.insert( images, '<br> ' )
table.insert( images, '<br> ' )
end
end

if i > 1 and ebauche.type and ebauche.type ~= paramEbauche[''].type then
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
-- remplace "Cet article par "Ce portail" ou autre en fonction du premier thème
table.insert(
table.insert(
gestionErreur,
gestionErreur,
erreur( ebauche.nom, cfg.erreurEbaucheType, 'div' )
erreur( ebauche.nom, cfg.erreurEbaucheType, 'div' )
)
)
end
end

-- récupères les différents noms de thème
-- récupères les différents noms de thème
if ebauche.adjectif and #titres > 0 then
if ebauche.adjectif and #titres > 0 then
Ligne 358 : Ligne 363 :
if estFeminin then
if estFeminin then
sujet = ebauche.sujetF or sujet:gsub(
sujet = ebauche.sujetF or sujet:gsub(
ebauche.nom:gsub( '(%p)', '%%%1') .. '%f[%W]',
ebauche.nom:gsub( '(%p)', '%%%1') .. '%f[%W]',
ebauche.feminin
ebauche.feminin
)
)
end
end
-- ajout du sujet de l'adjectif dans le sujet de l'ébauche précédente
-- ajout du sujet de l'adjectif dans le sujet de l'ébauche précédente
local titre, subst = titres[ #titres ]:gsub(
local titre, subst = titres[ #titres ]:gsub(
'<(adj[^>]*)>',
'<(adj[^>]*)>',
{ adjectif = sujet, adj = ebauche.nom, adjF = ebauche.feminin }
{ adjectif = sujet, adj = ebauche.nom, adjF = ebauche.feminin }
)
)
Ligne 376 : Ligne 381 :
estFeminin = ebauche.estFeminin or ( ebauche.sujet == '' and estFeminin )
estFeminin = ebauche.estFeminin or ( ebauche.sujet == '' and estFeminin )
end
end

-- mise en forme des catégories
-- mise en forme des catégories
if ebauche.adjectif then
if ebauche.adjectif then
Ligne 382 : Ligne 387 :
local modif = false
local modif = false
for k, v in ipairs( categs ) do
for k, v in ipairs( categs ) do
local cat, subst = v:gsub(
local cat, subst = v:gsub(
'<(adj[^>]*)>',
'<(adj[^>]*)>',
{ adj = ebauche.nom, adjF = ebauche.feminin, adjectif = ebauche.nom }
{ adj = ebauche.nom, adjF = ebauche.feminin, adjectif = ebauche.nom }
)
)
Ligne 394 : Ligne 399 :
end
end
end
end
if not modif
if not modif
and humain
and humain
and mw.title.new( 'Catégorie:Wikipédia:ébauche personnalité ' .. ebauche.feminin ).exists
and mw.title.new( 'Catégorie:Wikipédia:ébauche personnalité ' .. ebauche.feminin ).exists
then
then
Ligne 403 : Ligne 408 :
table.insert( categs, ebauche.categ )
table.insert( categs, ebauche.categ )
end
end

-- mise en forme des images
-- mise en forme des images
local image
local image
if trim( args['icône'] ) then
if args['icône'] and args['icône'] ~= '' then
local theme = getEbaucheTable( paramEbauche, args['icône'] )
local theme = getEbaucheTable( paramEbauche, args['icône'] )
if theme and theme.icone then
if theme and theme.icone then
image = cfg.formatLien:format(
image = cfg.formatLien:format(
theme.icone,
theme.icone,
tailleIcone,
tailleIcone,
theme.altIcone or ( 'image illustrant ' .. theme.sujet )
theme.altIcone or ( 'image illustrant ' .. theme.sujet )
)
)
Ligne 420 : Ligne 425 :
image = cfg.ebaucheImage:format( table.concat( images, ' ' ) )
image = cfg.ebaucheImage:format( table.concat( images, ' ' ) )
end
end

-- mise en forme du titre
-- mise en forme du titre
local titre
local titre
if #titres > 0 then
if #titres > 0 then
titre = cfg.ebaucheTitreSujet:format(
titre = cfg.ebaucheTitreSujet:format(
ebaucheParam( 1, 'type' ),
ebaucheParam( 1, 'type' ),
mw.text.listToText( titres )
mw.text.listToText( titres )
)
)
Ligne 431 : Ligne 436 :
titre = cfg.ebaucheTitre:format( ebaucheParam( 1, 'type' ) )
titre = cfg.ebaucheTitre:format( ebaucheParam( 1, 'type' ) )
end
end

-- mise en forme du texte
-- mise en forme du texte
local texte
local texte
Ligne 454 : Ligne 459 :
.. '|page de discussion]].'
.. '|page de discussion]].'
end
end

-- paramètres pour le bandeau
-- paramètres pour le bandeau
local parametres = {
local parametres = {
Ligne 463 : Ligne 468 :
id = args.id
id = args.id
}
}

-- 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 = ''
local messageErreur = table.concat( gestionErreur )
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
for i = 1, #categs do
Ligne 475 : Ligne 479 :
categ = cfg.ebaucheCateg:format('')
categ = cfg.ebaucheCateg:format('')
end
end
end
if #gestionErreur > 0 then

local messageErreur = table.concat( gestionErreur )
if #gestionErreur > 0 then
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 ) .. messageErreur .. categ
return p._bandeauAvertissement( parametres ) .. categ .. messageErreur
end
end


Ligne 501 : Ligne 509 :
end
end


---
---
-- Fonction retournant le féminin d'un théme d'ébauche
-- Fonction retournant le féminin d'un théme d'ébauche
-- Elle est prévue pour être appelée directement par #invoke:
-- Elle est prévue pour être appelée directement par #invoke:
Ligne 513 : Ligne 521 :
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 tF.categ == t.categ then
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
elseif tF then
themeF = tF.nom
themeF = tF.nom
end
end
Ligne 528 : Ligne 536 :
function p.tableParametresEbauches( frame )
function p.tableParametresEbauches( frame )
local paramEbauche = mw.loadData( moduleEbauche )
local paramEbauche = mw.loadData( moduleEbauche )

local currentFrame = mw.getCurrentFrame()
local currentFrame = mw.getCurrentFrame()
local languageObj = mw.getContentLanguage()
local languageObj = mw.getContentLanguage()
Ligne 534 : Ligne 542 :
return languageObj:formatNum( tonumber( currentFrame:callParserFunction( 'PAGESINCATEGORY', { category, 'R' } ) ) )
return languageObj:formatNum( tonumber( currentFrame:callParserFunction( 'PAGESINCATEGORY', { category, 'R' } ) ) )
end
end

local params, paramAdj, paramType = {}, {}, {}
local params, paramAdj, paramType = {}, {}, {}
for clef, ebauche in pairs( paramEbauche ) do
for clef, ebauche in pairs( paramEbauche ) do
Ligne 558 : Ligne 566 :
table.sort( paramAdj, comp )
table.sort( paramAdj, comp )
table.sort( paramType, comp )
table.sort( paramType, comp )

local wikiTab = { '<table class="wikitable sortable" style="table-layout:fixed;">' }
local wikiTab = { '<table class="wikitable sortable" style="table-layout:fixed;">' }
wikiTab.insert = function ( t, value )
wikiTab.insert = function ( t, value )
Ligne 564 : Ligne 572 :
return t
return t
end
end

wikiTab
wikiTab
:insert('\n=== Ébauches normales ===\n')
:insert('\n=== Ébauches normales ===\n')
Ligne 602 : Ligne 610 :
end
end
wikiTab:insert('</table>')
wikiTab:insert('</table>')

-- seconde table pour les adjectifs
-- seconde table pour les adjectifs
wikiTab
wikiTab
Ligne 639 : Ligne 647 :
end
end
wikiTab:insert('</table>')
wikiTab:insert('</table>')

-- troisième table pour les types
-- troisième table pour les types
wikiTab
wikiTab
Ligne 674 : Ligne 682 :
end
end
wikiTab:insert('</table>')
wikiTab:insert('</table>')

-- parenthèses pour enlever la 2e valeur retournée par gsub (le nombre de remplacements effectués)
-- parenthèses pour enlever la 2e valeur retournée par gsub (le nombre de remplacements effectués)
return (table.concat( wikiTab ):gsub( ' <adjF?>', '' ))
return (table.concat( wikiTab ):gsub( ' <adjF?>', '' ))
Ligne 707 : Ligne 715 :
end
end
end
end

local nomsFonction = {'bandeau', 'bandeauAvertissement', 'bandeauSection', 'ébauche' }
local nomsFonction = {'bandeau', 'bandeauAvertissement', 'bandeauSection', 'ébauche' }
for _, nomFonction in ipairs(nomsFonction) do
for _, nomFonction in ipairs(nomsFonction) do
p[nomFonction] = adaptateur('_' .. nomFonction)
p[nomFonction] = adaptateur('_' .. nomFonction)

Dernière version du 26 août 2023 à 03:39

 Documentation[voir] [modifier] [historique] [purger]

Ce module implémente les modèles de bandeau.

Utilisation

Fonctions exportables :

Autres fonctions :

  • les fonctions ci-dessus avec un « _ » avant le nom peuvent être appelées directement depuis lua, avec les paramètres dans une table.

Modules externes et autres éléments dont ce module a besoin pour fonctionner :

Exemples

{{#invoque:Bandeau|bandeauAvertissement
 | niveau = modéré
 | icône = 2017-fr.wp-orange-source.svg
 | légende = icône représentant un livre ouvert
 | titre = Cet article [[Wikipédia:Citez vos sources|ne cite pas suffisamment ses sources]]
 | date = {{{date|{{{2|}}}}}}
 | texte = Si vous disposez d'ouvrages ou d'articles de référence ou si vous connaissez des sites web de qualité traitant du thème abordé ici, merci de compléter l'article en donnant les références utiles à sa vérifiabilité et en les liant à la section [[Aide:Note|« Notes et références »]] ([{{fullurl:{{FULLPAGENAME}}|action=edit}} modifier l'article]). }} {{#ifeq:{{NAMESPACE}}|| {{#if:{{{1|}}} |{{À sourcer/avec clétri |clétri={{{1}}} |date={{{date|{{{2| }}} }}} }} |{{À sourcer/sans clétri |date={{{date|{{{2| }}} }}} }} }}[[Catégorie:Article manquant de référence/Liste complète]]
}}
--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]]',
	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
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
			iconeWiki = cfg.formatLien:format(icone, taille, alt)
		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()
			: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'],
		['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
			iconeWiki = cfg.formatLien:format(icone, 'text-top|20x17', alt)
		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ètre 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
			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 )
		return ebauches[ i ] and ebauches[ i ][ param ] or paramEbauche[''][ param ]
	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 image = cfg.formatLien:format( ebauche.icone, tailleIcone, alt )
			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ères 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 )
			)
		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
	if #ebauches == 0 then
		texte = ( ebaucheParam( 1, 'message' ) ) .. '.'
	else
		local message = ebaucheParam( 1, 'message' )
		local selon = ebaucheParam( 1, 'selon' )
		-- ajout d'un point si le paramètre selon commence par un retour ligne ou une majuscule
		if message:sub( -1 ) == ')' and ( selon:sub( 1, 3 ) == '<br' or mw.ustring.match( selon, '^%u' ) ) then
			texte = ( ebaucheParam( 1, 'message' ) ) .. '. ' .. ( ebaucheParam( 1, 'selon' ) ) .. '.'
		else
			texte = ( ebaucheParam( 1, 'message' ) ) .. ' ' .. ( ebaucheParam( 1, 'selon' ) ) .. '.'
		end
	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
		for i = 1, #categs do
			categs[ i ] = cfg.ebaucheCateg:format( categs[ i ] )
		end
		categ = table.concat( categs ):gsub( ' <[^>]*>', '' )
		if categ == '' then
			categ = cfg.ebaucheCateg:format('')
		end
	end

	local messageErreur = table.concat( gestionErreur )
	if #gestionErreur > 0 then
		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()
	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 '' ) )
		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 '' ) )
		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 '' ) )
		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