Module:Bacasable
Apparence
La documentation de ce module est générée par le modèle {{Documentation module}}.
Les éditeurs peuvent travailler dans le bac à sable (créer).
Voir les statistiques d'appel depuis le wikicode sur l'outil wstat et les appels depuis d'autres modules.
local p = {}
-- * [pairs(args)] itère sur un couple (clé, valeur).
-- * [ipairs(args)] itère sur un couple (index, valeur) et ignore les clés,
-- s'arrète si valeur = nil.
-- * [mw.dumpObject(o)] et [ou mw.logObject(o)] affichent le contenu de o.
-- HtmlBuilder
local function creerEntete(html)
html
:tag('div')
:addClass('entete')
:wikitext('Entête')
end
function p.creerCorps(args)
local res = mw.html.create('div'):addClass('infobox')
creerEntete(res)
return tostring(res)
end
-- Création d'bjet
local objet = {}
objet.__index = objet
function objet.creerObjet()
local res = {a = 1, b = false, c}
return setmetatable(res, objet)
end
function objet:setB(b)
self.b = b
end
function objet.__tostring(t)
return t.a .. tostring(t.b) .. tostring(t.c)
end
function p.main2()
local o = objet.creerObjet()
o:setB(true)
return tostring(o)
end
-- Métatable
local mt = {}
mt.__index = mt
function mt:insert(...)
table.insert(self, ...)
return self
end
function mt:concat(...)
return table.concat(self, ...)
end
function p.new(...)
return setmetatable({...}, mt)
end
-- Test lambda
function p.estOrdonne(args, prefixe)
local sections, groupes, listes = {}, {}, {}
local indice
for cle, _ in pairs(args) do
indice = tostring(cle):match('^section(%d+)$')
if indice then
table.insert(res, tonumber(indice))
end
end
table.sort(res)
indice = 1
for cle, val in pairs(res) do
if indice ~= val then
return false
end
indice = indice + 1
end
return f(res), #res ~= 0
end
-- Gestion des arguments
local checkType = require('libraryUtil').checkType
local function foncDefaut(_, val)
local res = mw.text.trim(val)
if res == '' then
return nil
end
return res
end
function p.gestionArgs(frame, options)
checkType('gestionArgs', 1, frame, 'table', true)
checkType('gestionArgs', 2, options, 'table', true)
options = options or {}
local res = {}
if type(frame.args) == 'table'
and type(frame.getParent) == 'function' then
local argsFrame = frame.args or {}
local argsParent = frame:getParent().args or {}
-- Récupération unique des arguments passés via [#invoke].
if options.argsFrame then
res = argsFrame
-- Récupération unique des arguments de la page qui a appelé [#invoke].
elseif options.argsParent then
res = argsParent
-- Récupération de la totalité des arguments reçus via [#invoke].
else
for cle, val in pairs(argsParent) do
res[cle] = val
end
for cle, val in pairs(argsFrame) do
res[cle] = val
end
end
else
return frame
end
local foncIter = foncDefaut
if type(options.foncIter) == 'function'
or type(options.foncIter) == 'boolean' and not options.foncIter then
foncIter = options.foncIter
end
if foncIter then
for cle, val in pairs(res) do
res[cle] = foncIter(cle, val)
end
end
return res
end
local o = {}
o.__index = o
function o.Palette(args)
local html = mw.html.create('div')
:addClass('palette mw-collapsible')
local etat = args['état']
-- Configuration du paramètre [état].
if etat == 'fermé' then
res:addClass('mw-collapsed')
elseif etat == 'ouvert' then
res:addClass('mw-uncollapsed')
end
return setmetatable({ html = html, args = args }, o)
end
function o:test()
local res = mw.html.create('p')
local args = self.args
res:wikitext('Lorem : ' .. args.lorem)
self.html:node(res)
return self
end
function o:test2()
local res = mw.html.create('p')
local args = self.args
res:wikitext('Ipsum : ' .. args.ipsum)
self.html:node(res)
return self
end
function o.__tostring(o)
return tostring(o.html)
end
local function gestionArgs(frame)
local args = {}
local argsParent = frame:getParent().args
-- Paramètres vides interprétés par Lua.
for cle, val in pairs(argsParent) do
if val ~= '' then
args[cle] = mw.text.trim(val)
end
end
return args
end
function p.main2(frame)
local args = p.gestionArgs(frame)
--[[local palette = o.Palette(args)
palette
:test()
:test2()
return palette]]--
return mw.dumpObject(args)
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
local cfg = {
header = 'Liste des titres, avec positions dans les classements',
headerWithCertif = 'Liste des titres, avec positions dans les classements et certifications',
title = 'Titre',
details = "Détails de l'album",
year = 'Année',
position = 'Meilleure position',
sale = 'Ventes',
certif = '[[Disque de certification|Certifications]]',
album = 'Album',
footer = "« — » indique que le titre n'est pas sorti ou classé dans le pays.",
prefix = {
chart = 'pays',
ref = 'ref',
title = 'titre',
option = 'option',
details = 'détails',
year = 'année',
yearn = 'annéen',
position = 'position',
sale = 'vente',
certif = 'certif',
album = 'album',
albumn = 'albumn'
}
}
function getArgNums(args, prefix)
local nums = {}
for k, _ in pairs(args) do
local num = k:match('^' .. prefix .. '([1-9]%d*)$')
if num then
table.insert(nums, tonumber(num))
end
end
table.sort(nums)
return nums
end
local Discography = {}
Discography.__index = Discography
function Discography.new(args, cfg, classType)
args = args or {}
local cleanArgs = {}
for k, v in pairs(args) do
if type(k) == 'string' and v ~= '' then
cleanArgs[k] = mw.text.trim(v)
end
end
local fields = {
isAlbumType = classType == 'album',
args = cleanArgs,
cfg = cfg,
root = mw.html.create('table')
:addClass('wikitable')
:css('text-align', 'center'),
chartNums = getArgNums(cleanArgs, cfg.prefix.chart),
existsSale = #getArgNums(cleanArgs, cfg.prefix.sale) > 0,
existsCertif = #getArgNums(cleanArgs, cfg.prefix.certif) > 0
}
return setmetatable(fields, Discography)
end
function Discography:__tostring()
return tostring(self.root)
end
local function createTag(root, tag, text, attributes, styles)
root:tag(tag):attr(attributes or {}):css(styles or {}):wikitext(text)
end
local function createTagIf(exist, root, tag, text, attributes, styles)
if exist then createTag(root, tag, text, attributes, styles) end
end
function Discography:buildHeader()
local args = self.args
local cfg = self.cfg
-- Create titles header.
local titlesHeader = mw.html.create('tr')
local attr = { scope = 'col', rowspan = '2' }
local attrPosition = { scope = 'col', colspan = #self.chartNums }
createTag(titlesHeader, 'th', cfg.title, attr)
createTag(titlesHeader, 'th', self.isAlbumType and cfg.details or cfg.year, attr)
createTag(titlesHeader, 'th', cfg.position, attrPosition)
createTagIf(self.existsSale, titlesHeader, 'th', cfg.sale, attr)
createTagIf(self.existsCertif, titlesHeader, 'th', cfg.certif, attr)
createTagIf(not self.isAlbumType, titlesHeader, 'th', cfg.album, attr)
-- Create charts header.
local chartsHeader = mw.html.create('tr')
local attr = { scope = 'col' }
local css = { width = '2em', ['font-size'] = '90%' }
for _, chartNum in pairs(self.chartNums) do
local text = args[cfg.prefix.chart .. chartNum]
.. '<br>'
.. (args[cfg.prefix.ref .. chartNum] or '')
createTag(chartsHeader, 'th', text, attr, css)
end
self.root
:tag('caption')
:wikitext(self.existsCertif and cfg.headerWithCertif or cfg.header)
:done()
:node(titlesHeader)
:node(chartsHeader)
return self
end
local function optionTitle(optionValue)
if not optionValue then
return ''
end
return '<br><span style="font-size:89%">(' .. optionValue .. ')</span>'
end
local function splitBySemicolon(text)
local res = {}
if text then
for p in text:gmatch('([^; ]+)') do
table.insert(res, p)
end
end
return res
end
function Discography:buildAlbumRow(albumNum, args, prefix, css)
local root = mw.html.create('tr')
-- Create title column.
local text = args[prefix.title .. albumNum]
.. optionTitle(args[prefix.option .. albumNum])
createTag(root, 'td', text, {}, css)
-- Create album details column.
local text = args[prefix.details .. albumNum]
text = text and '\n' .. text
createTag(root, 'td', text, {}, css)
-- Create chart position columns.
local positions = splitBySemicolon(args[prefix.position .. albumNum])
for chartNum = 1, #self.chartNums do
root:tag('td'):wikitext(positions[chartNum] or '—'):done()
end
-- Create optional sale column.
local text = args[prefix.sale .. albumNum]
text = text and '\n' .. text
createTagIf(self.existsSale, root, 'td', text, {}, css)
-- Create optional certification column.
local text = args[prefix.certif .. albumNum]
text = text and '\n' .. text
createTagIf(self.existsCertif, root, 'td', text, {}, css)
return root
end
function Discography:buildSongRow(songNum, args, prefix, css)
local root = mw.html.create('tr')
-- Create title column.
local text = args[prefix.title .. songNum]
.. optionTitle(args[prefix.option .. songNum])
createTag(root, 'td', text, {}, css)
-- Create year column only if the previous yearn is not found.
local attr = { rowspan = args[prefix.yearn .. songNum] or 1 }
local text = args[prefix.year .. songNum]
createTagIf(text, root, 'td', text, attr)
-- Create chart position columns.
local positions = splitBySemicolon(args[prefix.position .. songNum])
for chartNum = 1, #self.chartNums do
root:tag('td'):wikitext(positions[chartNum] or '—'):done()
end
-- Create optional sale column.
local text = args[prefix.sale .. songNum]
text = text and '\n' .. text
createTagIf(self.existsSale, root, 'td', text, {}, css)
-- Create optional certification column.
local text = args[prefix.certif .. songNum]
text = text and '\n' .. text
createTagIf(self.existsCertif, root, 'td', text, {}, css)
-- Create album column only if the previous yearn is not found.
local attr = { rowspan = args[prefix.albumn .. songNum] or 1 }
local text = args[prefix.album .. songNum]
createTagIf(text, root, 'td', text, attr)
return root
end
function Discography:buildContent()
local args = self.args
local prefix = self.cfg.prefix
local css = { ['text-align'] = 'left' }
local buildRow = self.isAlbumType
and function (albumNum)
return self:buildAlbumRow(albumNum, args, prefix, css)
end
or function (songNum)
return self:buildSongRow(songNum, args, prefix, css)
end
for _, titleNum in pairs(getArgNums(args, prefix.title)) do
local currentRoot = buildRow(titleNum)
self.root:node(currentRoot)
end
return self
end
function Discography:buildFooter()
local rowNo = #self.chartNums
+ (self.isAlbumType and 2 or 3)
+ (self.existsCertif and 1 or 0)
+ (self.existsSale and 1 or 0)
self.root
:tag('tr')
:tag('td')
:attr('colspan', rowNo)
:css('font-size', '90%')
:wikitext(self.cfg.footer)
:done()
return self
end
-- Access in the module space.
function p._main(args, classType)
local discography = Discography.new(args, cfg, classType)
return tostring(discography:buildHeader():buildContent():buildFooter())
end
-- Access outside the module space.
function p.main(frame)
local argsParent = frame:getParent().args
return p._main(argsParent, frame.args[1])
end
return p