Aller au contenu

Module:Discographie

Une page de Wikipédia, l'encyclopédie libre.
Ceci est une version archivée de cette page, en date du 1 avril 2018 à 15:45 et modifiée en dernier par Hlm Z. (discuter | contributions) (typo). Elle peut contenir des erreurs, des inexactitudes ou des contenus vandalisés non présents dans la version actuelle.

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

Ce module implémente les modèles {{Discographie des albums}} et {{Discographie des chansons}}. Voir la documentation des modèles pour les instructions d'utilisation. Le module produit un tableau discographique avec pour chaque ligne des informations détaillées de l'album ou d'une chanson. Il permet d'uniformiser et de simplifier la mise en forme des articles.

Fonctions exportables

  • main(frame) – Fonction implémentant le modèle {{Discographie des albums}} et {{Discographie des chansons}} – à appeler avec #invoke.
  • _main(args, classType) – Fonction qui peut être appelée dans un autre module avec require(). Ceci est une bonne pratique d'appeler cette fonction dans un autre module car cela permet d'omettre certains champs de l'objet frame, ce qui améliore les performances et simplifie la gestion des arguments. Le paramètre classType définit avec l'argument :
    • 'album' importera la discographie pour les albums,
    • 'chanson' importera la discographie pour les chansons.

Voir aussi

-- Ce module implémente les modèles {{Discographie des albums}} et {{Discographie des chansons}}.

local p = {}

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: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
	return p._main(argsParent, frame.args[1])
end

return p