Module:Discographie
Aller à la navigation
Aller à la recherche
Le module : Truc sert à…
La documentation de ce module est incluse depuis sa sous-page de documentation (modifier | historique).
Veuillez placer les catégories dans la sous-page /Documentation.
Les éditeurs peuvent travailler dans le bac à sable (créer).
-- Ce module implémente les modèles {{Discographie des albums}} et {{Discographie des chansons}}.
-- luacheck: globals mw
local p = {}
local cfg = {
header = 'Liste des titres, avec positions dans les classements',
headerWithAll = ', ventes cumulées et certifications',
headerWithSale = ' et ventes cumulées',
headerWithCertif = ' 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'
}
}
local 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 fields = {
args = args,
cfg = cfg,
isAlbumType = classType == 'album',
root = mw.html.create('table')
:addClass('wikitable')
:css('text-align', 'center'),
chartNums = getArgNums(args, cfg.prefix.chart),
existsSale = #getArgNums(args, cfg.prefix.sale) > 0,
existsCertif = #getArgNums(args, 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 self.existsSale
and cfg.header .. cfg.headerWithAll
or self.existsCertif and cfg.header .. cfg.headerWithCertif
or self.existsSale and cfg.header .. cfg.headerWithSale
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 match in text:gmatch('([^;]+)') do
table.insert(res, mw.text.trim(match))
end
end
return res
end
function Discography:buildRow(titleNum, args, prefix, css)
local root = mw.html.create('tr')
-- Create title column.
local text = args[prefix.title .. titleNum]
.. optionTitle(args[prefix.option .. titleNum])
createTag(root, 'td', text, {}, css)
-- Create album details column.
-- Album type only.
local text = args[prefix.details .. titleNum]
text = text and '\n' .. text
createTagIf(self.isAlbumType, root, 'td', text, {}, css)
-- Create year column only if the previous yearn is not found.
-- Song type only.
local attr = { rowspan = args[prefix.yearn .. titleNum] or 1 }
local text = args[prefix.year .. titleNum]
createTagIf(text and not self.isAlbumType, root, 'td', text, attr)
-- Create chart position columns.
local positions = splitBySemicolon(args[prefix.position .. titleNum])
for chartNum = 1, #self.chartNums do
root:tag('td'):wikitext(positions[chartNum] or '—'):done()
end
-- Create optional sale column.
local text = args[prefix.sale .. titleNum]
text = text and '\n' .. text
createTagIf(self.existsSale, root, 'td', text, {}, css)
-- Create optional certification column.
local text = args[prefix.certif .. titleNum]
text = text and '\n' .. text
createTagIf(self.existsCertif, root, 'td', text, {}, css)
-- Create album column only if the previous yearn is not found.
-- Song type only.
local attr = { rowspan = args[prefix.albumn .. titleNum] or 1 }
local text = args[prefix.album .. titleNum]
createTagIf(text and not self.isAlbumType, root, 'td', text, attr)
return root
end
function Discography:buildContent()
local args = self.args
local prefix = self.cfg.prefix
local css = { ['text-align'] = 'left' }
for _, titleNum in pairs(getArgNums(args, prefix.title)) do
local currentRoot = self:buildRow(titleNum, args, prefix, css)
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
local cleanArgs = {}
for k, v in pairs(argsParent) do
if type(k) == 'string' and v ~= '' then
cleanArgs[k] = mw.text.trim(v)
end
end
return p._main(cleanArgs, frame.args[1])
end
return p