Module:Bandeau
Révision datée du 13 décembre 2016 à 11:47 par Hercule (discussion) (retour de la gestion du féminin cet élément ne fait que gérer les accords, il n'apporte pas une information dans l'article)
La documentation pour ce module peut être créée à Module:Bandeau/doc
--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 class = 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]]', tailleIcone = '45x45', public = 'domaine public', 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]].', erreurEbaucheType = 'le thème « %s » doit apparaître en tête de liste du modèle [[Modèle:Ébauche|{{é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]]', } 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 = class.icones[icone] or '' local texte = (trim(args.texte) or erreur('texte', cfg.erreurArgument)) res :attr{ id = args.id } :addClass(class.formes[args.forme] or cfg.forme) :addClass(class.niveau[args.niveau] or cfg.niveau) :addClass('plainlinks') :addClass(args.class) :cssText(args.style) 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 icone and backgroundIcone == '' then local iconeWiki = icone if not icone:match('%[') then local alt = args.alt or args['légende'] or '' if alt:lower() == cfg.public then alt = '|link=' end 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') :wikitext(iconeWiki) :done() elseif backgroundIcone ~= '' and args.forme == 'section' then texte = ' ' .. texte end cells :tag('div') :addClass('bandeau-cell ' .. backgroundIcone) :wikitext(texte) :newline() :done() if trim(args.droite) then cells :tag('div') :addClass('bandeau-cell') :css( 'padding-left', '1em' ) :newline() :wikitext(args.droite) :done() end res :node(cells) if trim(args['supplément']) then res :tag('p') :wikitext(args['supplément']) :done() end return tostring(res) end function p._bandeauAvertissement(args) local htmlTexte = mw.html.create() htmlTexte :tag('strong') :addClass('bandeau-titre') :wikitext(trim(args.titre) or erreur('titre', cfg.erreurArgument)) :done() :wikitext(args.date) :newline():newline() :wikitext(args.texte) 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), ['supplément'] = args['supplément'], } return p._bandeau(parametres) end function p._bandeauSection(args) local res = mw.html.create('div') local icone = trim(args.image) or trim(args['icône']) local backgroundIcone = class.icones[icone] or '' local texte = ' ' .. (trim(args.texte) or erreur('texte', cfg.erreurArgument)) res :addClass('bandeau-section') :addClass(class.niveau[args.niveau] or cfg.niveau) if icone and backgroundIcone == '' then local iconeWiki = icone if not icone:match('%[') then local alt = args.alt or args['légende'] or '' if alt:lower() == cfg.public then alt = '|link=' end iconeWiki = cfg.formatLien:format(icone, 'text-top|20x17', alt) end res :wikitext(iconeWiki) :done() end res :addClass(backgroundIcone) :wikitext(texte) :done() 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() feminin = yesno( args["féminin"], true ) or feminin 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 = ebauche.altIcone if not alt then if ebauche.sujet then alt = 'image illustrant ' .. ebauche.sujet else alt = '' end end 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 ) table.insert( categs, ebauche.categ2 ) end -- mise en forme des images local image if trim( 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 = mw.title.makeTitle( mw.site.namespaces[ page.namespace ].talk.id, page.text .. '/À faire' ) if 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 = '' local messageErreur = table.concat( gestionErreur ) 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 if #gestionErreur > 0 then messageErreur = messageErreur .. '[[Catégorie:Ébauche inconnue]]' end end return p._bandeauAvertissement( parametres ) .. messageErreur .. categ 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.feminin and tF.categ == t.categ then if tAdjF then themeF = tF.nom .. ' ' .. tAdjF.feminin elseif tF then 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 params, paramAdj, paramType = {}, {}, {} local wikiTab = { '<table class="wikitable sortable" style="table-layout:fixed;">' } wikiTab.insert = function ( t, value ) table.insert( t, value ) return t end 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 ) 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>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 if ebauche.cageg2 then wikiTab :insert('<br>') :insert( '[[:Catégorie:Wikipédia:ébauche ' .. ebauche.categ2 .. '|' .. ebauche.categ2 .. ']]' ) 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>') return table.concat( wikiTab ):gsub( ' <adjF?>', '' ) end -- fonction destiné 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