« Module:Pistes » : différence entre les versions
Apparence
Modèle:Pistes>Od1n correctif pour le cas où le modèle contiendrait inopinément des paramètres non-nommés (problème signalé ici) ; la cause sous-jacente est que les paramètres sont stockés dans une unique table, pour éviter la confusion il faudrait utiliser deux tables séparées (une pour les "foobar42" et une autre pour le reste) |
m 56 versions importées |
||
| (27 versions intermédiaires par un autre utilisateur non affichées) | |||
| Ligne 1 : | Ligne 1 : | ||
-- luacheck: globals mw, no max line length | |||
local p = {} | local p = {} | ||
local langue = require 'Module:Langue' | local langue = require 'Module:Langue' | ||
function p.tableauPistes( frame ) | |||
function p. | |||
-- 1. Lecture des paramètres | -- 1. Lecture des paramètres | ||
local args = {} | local args = {} | ||
local rowArgsTable = {} | |||
local maxNumPiste = 0 | |||
-- map de noms de paramètres "alias → nom canonique" (attention à bien utiliser le nom canonique dans le code du module) | |||
local aliases = { | |||
headline = 'titre', | |||
total_length = 'total_temps', | |||
lyrics_credits = 'credits_paroles', | |||
music_credits = 'credits_musique', | |||
writing_credits = 'credits_ecriture', | |||
extra_column = 'colonne_extra', | |||
} | |||
-- même chose avec les paramètres "trucmucheN" | |||
local aliasesN = { | |||
title = 'piste', | |||
length = 'temps', | |||
lyrics = 'paroles', | |||
music = 'musique', | |||
writer = 'auteur', | |||
} | |||
for k, v in pairs(frame:getParent().args) do | for k, v in pairs(frame:getParent().args) do | ||
-- match: foobar42 | --[[ | ||
match: | |||
local param, | * foobar42 | ||
if param | * foo21bar42 (digits in base name) | ||
* 21foo42 (leading digits in base name) | |||
* foobar0 (track zero) | |||
do not match: | |||
* 42 (only digits) | |||
* foobar (no digits suffix) | |||
* foobar042 (leading zeroes) | |||
alternative pattern: ^(.+)%f[%d]([1-9]%d*)$ | |||
--]] | |||
local param, num = string.match( k, '^(.*%D)([1-9]%d*)$' ) -- in this specific case, multibyte mw.ustring.match() is not needed | |||
if not param then | |||
param, num = string.match( k, '^(.*%D)(0)$' ) -- also search for track zero | |||
end | |||
if param then | |||
if aliasesN[param] then | |||
param = aliasesN[param] | |||
end | |||
if v ~= "" or param == "numero" then -- il est possible de renseigner des paramètres « numeroN » vides | |||
num = tonumber(num) | |||
if rowArgsTable[num] == nil then | |||
if num > maxNumPiste then | |||
maxNumPiste = num | |||
end | |||
rowArgsTable[num] = {} | |||
end | end | ||
rowArgsTable[num][param] = v | |||
end | end | ||
if | else | ||
if aliases[k] then | |||
k = aliases[k] | |||
end | end | ||
local trimmed = ( type(k) == "number" ) and mw.text.trim(v) or v | |||
if trimmed ~= "" then | if trimmed ~= "" then | ||
args[k] = trimmed | args[k] = trimmed | ||
| Ligne 38 : | Ligne 78 : | ||
:addClass( "overflow pistes-marge" ) | :addClass( "overflow pistes-marge" ) | ||
:css({ | :css({ | ||
['margin-bottom'] = | ['margin-bottom'] = args.total_temps and '0.5em' or '1em' | ||
}) | }) | ||
local tabPistes = divPistes | local tabPistes = divPistes | ||
| Ligne 46 : | Ligne 86 : | ||
-- 3. Éventuel code avant l'entête du tableau (titre ou boîte repliable) | -- 3. Éventuel code avant l'entête du tableau (titre ou boîte repliable) | ||
if args.titre | if args.titre then | ||
tabPistes | tabPistes | ||
:tag( "tr" ) | :tag( "tr" ) | ||
| Ligne 53 : | Ligne 93 : | ||
:attr( "scope", "col" ) | :attr( "scope", "col" ) | ||
:attr( "colspan", "10" ) | :attr( "colspan", "10" ) | ||
:wikitext( (args["langue titre"] or args["langue titres"]) and langue.langue({ args["langue titre"] or args["langue titres"], args.titre | :wikitext( (args["langue titre"] or args["langue titres"]) and langue.langue({ args["langue titre"] or args["langue titres"], args.titre }) or args.titre ) | ||
elseif args.collapsed == 'oui' then | elseif args.collapsed == 'oui' then | ||
tabPistes | tabPistes | ||
| Ligne 64 : | Ligne 104 : | ||
-- 4. Création de l'entête du tableau | -- 4. Création de l'entête du tableau | ||
local nbColonnesExtra = | local nbColonnesExtra = (args.credits_paroles and 1 or 0) + (args.credits_musique and 1 or 0) + (args.credits_ecriture and 1 or 0) + (args.colonne_extra and 1 or 0) | ||
local entetesPistes = tabPistes | local entetesPistes = tabPistes | ||
| Ligne 87 : | Ligne 127 : | ||
:wikitext( "Titre" ) | :wikitext( "Titre" ) | ||
:done() | :done() | ||
if args.credits_paroles | if args.credits_paroles == 'oui' then -- Colonne « Paroles » | ||
entetesPistes | entetesPistes | ||
:tag( "th" ) | :tag( "th" ) | ||
| Ligne 98 : | Ligne 138 : | ||
:done() | :done() | ||
end | end | ||
if args.credits_musique | if args.credits_musique == 'oui' then -- Colonne « Musique » | ||
entetesPistes | entetesPistes | ||
:tag( "th" ) | :tag( "th" ) | ||
| Ligne 109 : | Ligne 149 : | ||
:done() | :done() | ||
end | end | ||
if args.credits_ecriture | if args.credits_ecriture == 'oui' then -- Colonne « Auteur » | ||
entetesPistes | entetesPistes | ||
:tag( "th" ) | :tag( "th" ) | ||
| Ligne 120 : | Ligne 160 : | ||
:done() | :done() | ||
end | end | ||
if args.colonne_extra | if args.colonne_extra then -- Colonne extra | ||
entetesPistes | entetesPistes | ||
:tag( "th" ) | :tag( "th" ) | ||
| Ligne 128 : | Ligne 168 : | ||
width = ({[1]='40%', [2]='30%', [3]='20%', [4]='20%'})[nbColonnesExtra] | width = ({[1]='40%', [2]='30%', [3]='20%', [4]='20%'})[nbColonnesExtra] | ||
}) | }) | ||
:wikitext( args.colonne_extra | :wikitext( args.colonne_extra ) | ||
:done() | :done() | ||
end | end | ||
| Ligne 144 : | Ligne 184 : | ||
-- 5. Tracé des lignes du tableau | -- 5. Tracé des lignes du tableau | ||
for i = | for i = 0, maxNumPiste do -- on commence à 0, pour éventuel [[morceau caché]] dans le [[prégap]] | ||
local rowArgs = rowArgsTable[i] | |||
if | if rowArgs and (rowArgs.piste or rowArgs.note or rowArgs.temps) then | ||
local ligne = tabPistes:tag( 'tr' ) | local ligne = tabPistes:tag( 'tr' ) | ||
local numero | local numero | ||
if | if rowArgs.numero == '' then | ||
numero = '' | numero = '' | ||
else | else | ||
numero = ( | numero = (rowArgs.numero or tostring(i)) .. '.' | ||
end | end | ||
ligne | ligne | ||
| Ligne 160 : | Ligne 201 : | ||
:attr{ scope = 'row' } | :attr{ scope = 'row' } | ||
:wikitext( numero ) | :wikitext( numero ) | ||
local titrePiste = | local titrePiste = rowArgs.piste | ||
if titrePiste then | if titrePiste then | ||
if | if langue.nonLatin( titrePiste ) then | ||
titrePiste = "'' | titrePiste = '<cite style="font-style:normal">' .. titrePiste .. '</cite>' | ||
else | |||
titrePiste = '<cite>' .. titrePiste .. '</cite>' | |||
end | end | ||
if | if rowArgs["langue titre"] or args["langue titres"] then -- "langue titreN" puis "langue titres" | ||
titrePiste = langue.langue({ | titrePiste = langue.langue({ rowArgs["langue titre"] or args["langue titres"], titrePiste }) | ||
end | end | ||
else | else | ||
titrePiste = 'Sans titre' | titrePiste = 'Sans titre' | ||
end | end | ||
ligne:tag( 'td' ):wikitext(titrePiste .. ( | ligne:tag( 'td' ):wikitext(titrePiste .. (rowArgs.note and (' <small>(' .. rowArgs.note .. ')</small>') or '') ) | ||
if args.credits_paroles | if args.credits_paroles == 'oui' then | ||
ligne:tag( 'td' ):wikitext( | ligne:tag( 'td' ):wikitext( rowArgs.paroles ) | ||
end | end | ||
if args.credits_musique | if args.credits_musique == 'oui' then | ||
ligne:tag( 'td' ):wikitext( | ligne:tag( 'td' ):wikitext( rowArgs.musique ) | ||
end | end | ||
if args.credits_ecriture | if args.credits_ecriture == 'oui' then | ||
ligne:tag( 'td' ):wikitext( | ligne:tag( 'td' ):wikitext( rowArgs.auteur ) | ||
end | end | ||
if args.colonne_extra | if args.colonne_extra then | ||
ligne:tag( 'td' ):wikitext( | ligne:tag( 'td' ):wikitext( rowArgs.extra ) | ||
end | end | ||
ligne:tag('td') | ligne:tag('td') | ||
:addClass( 'pistes-duree' ) | :addClass( 'pistes-duree' ) | ||
:wikitext( | :wikitext( rowArgs.temps ) | ||
end | end | ||
end | end | ||
-- 6. Affichage de la durée totale le cas échéant | -- 6. Affichage de la durée totale le cas échéant | ||
if args.total_temps | if args.total_temps then | ||
tabPistes:tag( 'tr' ):tag('td') | tabPistes:tag( 'tr' ):tag('td') | ||
:addClass( 'pistes-dureetotale' ) | :addClass( 'pistes-dureetotale' ) | ||
:attr( 'colspan', '10' ) | :attr( 'colspan', '10' ) | ||
:wikitext( args.total_temps | :wikitext( args.total_temps ) | ||
end | end | ||
Dernière version du 12 mars 2026 à 00:58
La documentation pour ce module peut être créée à Module:Pistes/doc
-- luacheck: globals mw, no max line length
local p = {}
local langue = require 'Module:Langue'
function p.tableauPistes( frame )
-- 1. Lecture des paramètres
local args = {}
local rowArgsTable = {}
local maxNumPiste = 0
-- map de noms de paramètres "alias → nom canonique" (attention à bien utiliser le nom canonique dans le code du module)
local aliases = {
headline = 'titre',
total_length = 'total_temps',
lyrics_credits = 'credits_paroles',
music_credits = 'credits_musique',
writing_credits = 'credits_ecriture',
extra_column = 'colonne_extra',
}
-- même chose avec les paramètres "trucmucheN"
local aliasesN = {
title = 'piste',
length = 'temps',
lyrics = 'paroles',
music = 'musique',
writer = 'auteur',
}
for k, v in pairs(frame:getParent().args) do
--[[
match:
* foobar42
* foo21bar42 (digits in base name)
* 21foo42 (leading digits in base name)
* foobar0 (track zero)
do not match:
* 42 (only digits)
* foobar (no digits suffix)
* foobar042 (leading zeroes)
alternative pattern: ^(.+)%f[%d]([1-9]%d*)$
--]]
local param, num = string.match( k, '^(.*%D)([1-9]%d*)$' ) -- in this specific case, multibyte mw.ustring.match() is not needed
if not param then
param, num = string.match( k, '^(.*%D)(0)$' ) -- also search for track zero
end
if param then
if aliasesN[param] then
param = aliasesN[param]
end
if v ~= "" or param == "numero" then -- il est possible de renseigner des paramètres « numeroN » vides
num = tonumber(num)
if rowArgsTable[num] == nil then
if num > maxNumPiste then
maxNumPiste = num
end
rowArgsTable[num] = {}
end
rowArgsTable[num][param] = v
end
else
if aliases[k] then
k = aliases[k]
end
local trimmed = ( type(k) == "number" ) and mw.text.trim(v) or v
if trimmed ~= "" then
args[k] = trimmed
end
end
end
-- 2. Initialisation du tableau de la liste des titres
local divPistes = mw.html.create( 'div' )
:addClass( "overflow pistes-marge" )
:css({
['margin-bottom'] = args.total_temps and '0.5em' or '1em'
})
local tabPistes = divPistes
:tag( "table" )
:addClass( "tracklist" .. (args.collapsed == 'oui' and " collapsible collapsed" or "") )
:attr( 'cellpadding', "0" )
-- 3. Éventuel code avant l'entête du tableau (titre ou boîte repliable)
if args.titre then
tabPistes
:tag( "tr" )
:tag( "th" )
:addClass( "tlheader pistes-titre" )
:attr( "scope", "col" )
:attr( "colspan", "10" )
:wikitext( (args["langue titre"] or args["langue titres"]) and langue.langue({ args["langue titre"] or args["langue titres"], args.titre }) or args.titre )
elseif args.collapsed == 'oui' then
tabPistes
:tag( "tr" )
:tag( "th" )
:addClass( "tlheader pistes-titre" )
:attr( "colspan", "10" )
:wikitext( " " )
end
-- 4. Création de l'entête du tableau
local nbColonnesExtra = (args.credits_paroles and 1 or 0) + (args.credits_musique and 1 or 0) + (args.credits_ecriture and 1 or 0) + (args.colonne_extra and 1 or 0)
local entetesPistes = tabPistes
:tag( "tr" )
:tag( "th" ) -- Colonne « Numéro »
:addClass( "tlheader pistes-entete" )
:attr( "scope", "col" )
:css({
width = '20px',
['padding-left'] = '10px',
['padding-right'] = '10px',
['text-align'] = 'right'
})
:wikitext( '<abbr class="abbr" title="Numéro">N<sup>o</sup></abbr>' ) -- résultat de {{Numéro avec majuscule|espace=non}}
:done()
:tag( "th" ) -- Colonne « Titre »
:addClass( "tlheader pistes-entete" )
:attr( "scope", "col" )
:css({
width = ({[0]='100%', [1]='60%', [2]='40%', [3]='30%', [4]='20%'})[nbColonnesExtra]
})
:wikitext( "Titre" )
:done()
if args.credits_paroles == 'oui' then -- Colonne « Paroles »
entetesPistes
:tag( "th" )
:addClass( "pistes-entete" )
:attr( "scope", "col" )
:css({
width = ({[1]='40%', [2]='30%', [3]='20%', [4]='20%'})[nbColonnesExtra]
})
:wikitext( "Paroles" )
:done()
end
if args.credits_musique == 'oui' then -- Colonne « Musique »
entetesPistes
:tag( "th" )
:addClass( "pistes-entete" )
:attr( "scope", "col" )
:css({
width = ({[1]='40%', [2]='30%', [3]='20%', [4]='20%'})[nbColonnesExtra]
})
:wikitext( "Musique" )
:done()
end
if args.credits_ecriture == 'oui' then -- Colonne « Auteur »
entetesPistes
:tag( "th" )
:addClass( "pistes-entete" )
:attr( "scope", "col" )
:css({
width = ({[1]='40%', [2]='30%', [3]='20%', [4]='20%'})[nbColonnesExtra]
})
:wikitext( "Auteur" )
:done()
end
if args.colonne_extra then -- Colonne extra
entetesPistes
:tag( "th" )
:addClass( "pistes-entete" )
:attr( "scope", "col" )
:css({
width = ({[1]='40%', [2]='30%', [3]='20%', [4]='20%'})[nbColonnesExtra]
})
:wikitext( args.colonne_extra )
:done()
end
entetesPistes
:tag( "th" ) -- Colonne « Durée »
:addClass( "tlheader pistes-entete" )
:attr( "scope", "col" )
:css({
width = '60px',
['padding-right'] = '10px',
['text-align'] = 'right'
})
:wikitext( "Durée" )
:done()
-- 5. Tracé des lignes du tableau
for i = 0, maxNumPiste do -- on commence à 0, pour éventuel [[morceau caché]] dans le [[prégap]]
local rowArgs = rowArgsTable[i]
if rowArgs and (rowArgs.piste or rowArgs.note or rowArgs.temps) then
local ligne = tabPistes:tag( 'tr' )
local numero
if rowArgs.numero == '' then
numero = ''
else
numero = (rowArgs.numero or tostring(i)) .. '.'
end
ligne
:addClass( (i%2 == 0) and 'pistes-pair' or 'pistes-impair' )
:tag( 'th' )
:addClass( "pistes-numero" )
:attr{ scope = 'row' }
:wikitext( numero )
local titrePiste = rowArgs.piste
if titrePiste then
if langue.nonLatin( titrePiste ) then
titrePiste = '<cite style="font-style:normal">' .. titrePiste .. '</cite>'
else
titrePiste = '<cite>' .. titrePiste .. '</cite>'
end
if rowArgs["langue titre"] or args["langue titres"] then -- "langue titreN" puis "langue titres"
titrePiste = langue.langue({ rowArgs["langue titre"] or args["langue titres"], titrePiste })
end
else
titrePiste = 'Sans titre'
end
ligne:tag( 'td' ):wikitext(titrePiste .. (rowArgs.note and (' <small>(' .. rowArgs.note .. ')</small>') or '') )
if args.credits_paroles == 'oui' then
ligne:tag( 'td' ):wikitext( rowArgs.paroles )
end
if args.credits_musique == 'oui' then
ligne:tag( 'td' ):wikitext( rowArgs.musique )
end
if args.credits_ecriture == 'oui' then
ligne:tag( 'td' ):wikitext( rowArgs.auteur )
end
if args.colonne_extra then
ligne:tag( 'td' ):wikitext( rowArgs.extra )
end
ligne:tag('td')
:addClass( 'pistes-duree' )
:wikitext( rowArgs.temps )
end
end
-- 6. Affichage de la durée totale le cas échéant
if args.total_temps then
tabPistes:tag( 'tr' ):tag('td')
:addClass( 'pistes-dureetotale' )
:attr( 'colspan', '10' )
:wikitext( args.total_temps )
end
return tostring( divPistes )
end
return p