Cette page est semi-protégée.

Module:Articles de la semaine

Aller à la navigation Aller à la recherche
 Documentation[modifier] [purger]

Le module : Articles de la semaine sert à faire fonctionner le modèle : Articles de la semaine, et donc la page Vikidia : Article de la semaine et ses sous-pages correspondant aux années (par exemple, la page Vikidia : Article de la semaine/2020).

Il expose une unique fonction, Liste, qui génère la liste des articles d’une année, avec le titre de section au début.

Le code généré utilise une flexbox (tutoriel en anglais), ce qui permet que le nombre de colonnes varie en fonction de la largeur de l’écran : une seule sur un écran peu large comme celui d’un smartphone, a priori jusque cinq sur certains écrans d’ordinateurs.

À faire

  • Le code devrait utiliser mw.html.
  • Les fonctions qui concernent les calculs de dates pourraient finir dans un module : Lib dates dédié.
local p = {}

--
-- Fonctions utilitaires
--

local function premierJourPremiereSemaine( annee )
	local lang = mw.language.getContentLanguage()

	local debut = tostring( annee - 1 ) -- l’année ISO 8601 peut commencer le 29 décembre précédent, confer
	           .. '-12-29'              -- https://fr.wikipedia.org/wiki/Num%C3%A9rotation_ISO_des_semaines

	local i = 0
	while lang:formatDate( 'W', debut .. ' +' .. tostring( i ) .. ' days') ~= "01" do i = i + 1 end
	return lang:formatDate( 'Y-m-d', debut .. ' +' .. tostring( i ) .. ' days')
end

local function intervalle( annee, semaine )
	local lang = mw.language.getContentLanguage()

	local debut = premierJourPremiereSemaine( annee )
	local jour1  = lang:formatDate( 'j', debut .. ' +' .. tostring( semaine * 7 - 7 ) .. ' days' )
	local mois1  = lang:formatDate( 'F', debut .. ' +' .. tostring( semaine * 7 - 7 ) .. ' days' )
	local annee1 = lang:formatDate( 'Y', debut .. ' +' .. tostring( semaine * 7 - 7 ) .. ' days' )
	local jour2  = lang:formatDate( 'j', debut .. ' +' .. tostring( semaine * 7 - 1 ) .. ' days' )
	local mois2  = lang:formatDate( 'F', debut .. ' +' .. tostring( semaine * 7 - 1 ) .. ' days' )
	local annee2 = lang:formatDate( 'Y', debut .. ' +' .. tostring( semaine * 7 - 1 ) .. ' days' )

	if jour1 == '1' then
		jour1 = '<abbr title="premier" class="abbr">1<sup>er</sup></abbr>'
	elseif jour2 == '1' then
		jour2 = '<abbr title="premier" class="abbr">1<sup>er</sup></abbr>'
	end

	if annee1 ~= annee2 then
		return jour1 .. '&nbsp;' .. mois1 .. ' ' .. annee1 .. ' au ' .. jour2 .. '&nbsp;' .. mois2 .. ' ' .. annee2
	elseif mois1 ~= mois2 then
		return jour1 .. '&nbsp;' .. mois1 .. ' au ' .. jour2 .. '&nbsp;' .. mois2 .. ' ' .. annee2
	else
		return jour1 .. ' au ' .. jour2 .. '&nbsp;' .. mois2 .. ' ' .. annee2
	end
end

local function nombreSemaines( annee )
	local premierJour = premierJourPremiereSemaine( annee )

	-- toutes les années qui commencent par un jeudi ont 53 semaines ISO 8601
	if premierJour == tostring( annee - 1 ) .. '-12-29' then
		return 53
	end

	-- les années bissextiles qui commencent par un mercredi ont 53 semaines ISO 8601
	local lang = mw.language.getContentLanguage()
	if premierJour == tostring( annee - 1 ) .. '-12-30' and
	   lang:formatDate( 't', tostring( annee ) .. '-02-01') == '29' then
		return 53
	end

	-- les autres années ont 52 semaines ISO 8601
	return 52
end

local function article( frame, annee, semaine )
	local page = 'Vikidia:Article de la semaine/' .. annee .. ' ' .. semaine
	local retour = '<li style="display:flex; padding:0.2em 1em 1em 1em; flex-basis:33em; flex-grow:2; border:1px solid #AAAAAA; background:#FFFFFF; flex-direction:column;">'
	            .. mw.ustring.format( '<h3>Semaine %s (%s)</h3>',
	                                  semaine,
	                                  intervalle( tonumber( annee ) or error( 'année non comprise' ),
	                                              tonumber( semaine ) or error( 'numéro de semaine non compris' )))
	            .. '<div style="width:100%; text-align:right; height:2em; margin-top:-2em;"><small>[['
	            .. page
	            .. [=[|Voir]]</small></div>
<div>]=]
	            .. frame:preprocess( '{{' .. page .. '}}' )
	            .. '</div></li>'

	return retour
end

--
-- Fonction à appeler depuis le modèle
--

-- [[modèle : Articles de la semaine]]
function p.Liste( frame )
	local args = frame:getParent().args
	local annee = tonumber( mw.text.trim( args[1] )) or error( 'année non reconnue dans le modèle : Articles de la semaine' )
	local semaine = nombreSemaines( annee )

	local retour = mw.ustring.format( '<h2>Calendrier de %s</h2>', tostring( annee ))
	            .. '<ul style="display:flex; flex-wrap:wrap; align-items:stretch; width:100%; margin-left:0; margin-right:0; padding:0; justify-content:space-between; gap:10px;">'
	while semaine > 14 or annee ~= 2007 and semaine > 1 do -- les premières semaines de 2007 manquent
		retour = retour .. article( frame, annee, tostring( semaine ))
		                .. article( frame, annee, tostring( semaine - 1 ))
		semaine = semaine - 2
	end

	if annee ~= 2007 and semaine == 1 then -- 2007 est spéciale car c’est la mise en place du système
		retour = retour .. article( frame, annee, "1" )
	end
	retour = retour .. '</ul>'

	return retour
end

return p