La documentation pour ce module peut être créée à Module:Univers/doc

-- <nowiki>
 
-------------------------------------------------------------------------------
--                              Module:Eras
--
-- This module renders the icons in the top-right corner of articles, as well
-- as the Canon and Legends tabs for pages with a Canon/Legends counterpart.
-- It also formats the page title with {{DISPLAYTITLE}}. It is a rewrite of
-- [[Template:Eras]].
-------------------------------------------------------------------------------
 
local DEBUG_MODE = false -- if true, errors are not caught
 
-------------------------------------------------------------------------------
-- Icon data
-------------------------------------------------------------------------------
 
--[[
-- This table stores data for all the icons displayed in the top-right. It can
-- have the following fields:
-- * image - the icon image name, minus any "File:" prefix (required).
-- * tooltip - the icon tooltip (optional).
-- * link - the page to link from the icon (optional).
-- * category - a category to go with the icon, minus any "Category:" prefix
--     (optional).
-- * protectionAction - for protection icons, an action such as "edit" or "move"
--     to check (optional).
-- * protectionLevel - for protection icons, the protection level to check,
--     such as "sysop". If the page doesn't have the right protection level
--     it is put in a tracking category and the icon is not displayed
--     (optional).
-- Note: this is just a convenient place to store the data. The subtables are
-- accessed from the code manually, so adding new subtables won't automatically
-- add new icons, and removing subtables may break things.
--]]
 
local iconData = {
	pre = {
		image = "Premium-Era-pre.png",
		tooltip = "Le sujet de cet article se place avant l\'Ère d\'Avant la République.",
		link = "Ère de l\'Empire Infini"
	},
	btr = {
		image = "Premium-Era-pre.png",
		tooltip = "Le sujet de cet article se place dans l\'Ère d\'Avant la République.",
		link = "Avant la République"
	},
	old = {
		image = "Premium-Era-old.png",
		tooltip = "Le sujet de cet article se place dans l\'Ère de l\'Ancienne République.",
		link = "Ère de l\'Ancienne République (publication)"
	},
	imp = {
		image = "Premium-Era-imp.png",
		tooltip = "Le sujet de cet article se place dans l\'Ère de l\'Avènement de l'Empire",
		link = "Montée en puissance de l\'Empire"
	},
	reb = {
		image = "Premium-Era-reb.png",
		tooltip = "Le sujet de cet article se place dans l\'Ère de la Rébellion.",
		link = "Ère de la Rébellion"
	},
	new = {
		image = "Premium-Era-new.png",
		tooltip = "Le sujet de cet article se place dans l\'Ère de la Nouvelle République.",
		link = "Ère de la Nouvelle République (publication)"
	},
	njo = {
		image = "Premium-Era-njo.png",
		tooltip = "Le sujet de cet article se place dans l\'Ère du Nouvel Ordre Jedi.",
		link = "Ère du Nouvel Ordre Jedi"
	},
	leg = {
		image = "Premium-Era-leg.png",
		tooltip = "Le sujet de cet article se place dans l\'Ère Héritage.",
		link = "Héritage"
	},
	inf = {
		image = "Premium-Era-inf.png",
		tooltip = "The subject of this article is considered part of Star Wars Infinities.",
		link = "Infinities",
		category = "Articles Hors-Continuité"
	},
	reel = {
		image = "Premium-Era-real.png",
		tooltip = "Le sujet de cet article existe dans le monde réel.",
		link = "Catégorie:Monde réel"
	},
	qualite = {
		image = "Premium-FeaturedIcon.png",
		tooltip = "Vous lisez un \"article de qualité.\"",
		link = "Star Wars Wiki:Articles de qualité",
		category = "Articles de qualité"
	},
	aqualite = {
		image = "Premium-DefeaturedIcon.png",
		tooltip = "Vous lisez un ancien article de qualité.",
		link = "Star Wars Wiki:Articles de qualité",
		category = "Articles de qualité"
	},
	bon = {
		image = "Premium-GoodIcon.png",
		tooltip = "Vous lisez un \"bon article.\"",
		link = "Star Wars Wiki:Bons articles",
		category = "Bons articles"
	},
	abon = {
		image = "Premium-FormerGAicon.png",
		tooltip = "Vous lisez un ancien \"bon article.\"",
		link = "Star Wars Wiki:Bons articles",
		category = "Bons articles"
	},
	comp = {
		image = "Premium-ComprehensiveArticle.png",
		tooltip = "This is a Wookieepedia Comprehensive Article.",
		link = "Wookieepedia:Comprehensive articles",
		category = "Wookieepedia comprehensive articles"
	},
	fca = {
		image = "Premium-FormerCAIcon.png",
		tooltip = "This is a former Wookieepedia Comprehensive Article.",
		link = "Wookieepedia:Comprehensive articles",
		category = "Wookieepedia former comprehensive articles"
	},
	fprot = {
		protectionAction = "edit",
		protectionLevel = "sysop",
		image = "Premium-Era-Fprotect.png",
		tooltip = "Cet article n'est pas éditable.",
		link = "Star Wars Wiki:Protection#Protection_complète",
		category = "Articles protégés"
	},
	sprot = {
		protectionAction = "edit",
		protectionLevel = "autoconfirmed",
		image = "Premium-Era-Sprotect.png",
		tooltip = "Cet article est semi-protégé.",
		link = "Star Wars Wiki:Protection#Semi-protection",
		category = "Articles semi-protéges"
	},
	ssprot = {
		image = "Premium-Era-Ssprotect.png",
		tooltip = "Cet article est super-semi-protégé.",
		link = "Star Wars Wiki:Protection#Super-semi-protection",
		category = "Articles semi-protégés"
	},
	mprot = {
		protectionAction = "move",
		protectionLevel = "sysop",
		image = "Premium-Era-Mprotect.png",
		tooltip = "Cet article est protégé contre le renommage.",
		link = "Star Wars Wiki:Protection#Protection contre le renommage",
		category = "Articles protégés contre le renommage"
	},
	uprot = {
		protectionAction = "upload",
		protectionLevel = "sysop",
		image = "Premium-Era-Uprotect.png",
		tooltip = "Ce fichier est protégé contre l'import.",
		link = "Star Wars Wiki:Protection#Protection contre l'import",
		category = "Upload protected files"
	},
	noncanon = {
		image = "Premium-Era-inf.png",
		tooltip = "Ce sujet ne fait pas partie de la continuité officielle de l'univers Star Wars.",
		category = "Articles Hors-Continuité"
	}
}
 
-------------------------------------------------------------------------------
-- Helper functions
-------------------------------------------------------------------------------
 
-- Find whether the specified page exists. We use pcall to catch errors if we
-- are over the expensive parser function count limit, or a number of other
-- juicy errors. This function increases the expensive parser function count
-- for every new page called.
local function exists(page)
	local success, title = pcall(mw.title.new, page)
	return success and title and title.exists or false
end
 
-------------------------------------------------------------------------------
-- Eras class
-------------------------------------------------------------------------------
 
-- The eras class does all of the heavy lifting in the module. We use a class
-- rather than normal functions so that we can avoid passing lots of different
-- values around for each different function.
 
local Eras = {}
Eras.__index = Eras -- Set up inheritance for tables that use Eras as a metatable.
 
-- This function makes a new eras object. Here we set all the values from the
-- arguments and do any preprocessing that we need.
function Eras.new(args, title)
	local obj = setmetatable({}, Eras) -- Make our object inherit from Eras.
	obj.title = title or mw.title.getCurrentTitle()
 
	-- Set object structure
	obj.categories = {}
 
	-- Set display title parameters
	obj.noDisplayTitle = args.notitre
	obj.displayTitleBase = args.titre
	obj.displayTitleParen = args.titre2
 
	-- Set hidden status
	obj.isHidden = args.hide
 
	-- Set the continuity override (the "type" parameter)
	if args.type then
		local override = args.type:lower()
		if override ~= 'canon' and override ~= 'légendes' then
			obj:raiseError("si le paramètre 'type' est précisé, sa valeur attendue " ..
				"est 'canon' ou 'légendes'")
		end
		obj.continuityOverride = override
		obj.typeArgs = override
	end
 
	-- Set canon and legends article names for the subject
	obj.legendsArticle = args.legends
	obj.canonArticle = args.canon
 
	-- Get the icon data.
	do
		local icons = {}
		for _, v in ipairs(args) do
			local t = iconData[string.lower(v)]
			if t then
				icons[string.lower(v)] = t
			else
				-- The specified icon wasn't found in the icon data, so set a
				-- tracking category flag.
				obj.hasBadParameter = true
			end
		end
		obj.icons = icons
	end
 
	return obj
end
 
-- Raise an error. If DEBUG_MODE is set to false, then errors raised here
-- are caught by the export function p._main.
function Eras:raiseError(msg)
	local level
	if DEBUG_MODE then
		level = nil
	else
		level = 0 -- Suppress module name and line number in the error message.
	end
	error(msg, level)
end
 
-- Add a category, to be rendered at the very end of the template output.
function Eras:addCategory(cat, sort)
	table.insert(self.categories, {category = cat, sortKey = sort})
end
 
-- Shortcut method for getting an icon data subtable.
function Eras:getIconData(code)
	return self.icons[code]
end
 
-- Whether the current title ends with /Canon.
function Eras:hasCanonTitle()
	return self.title.text:find('/Canon$')
end
 
-- Whether the current title ends with /Legends.
function Eras:hasLegendsTitle()
	return self.title.text:find('/Légendes$')
end
 
-- Returns a boolean showing whether any of the icons were specified by the
-- user.
function Eras:hasAnyOfIcons(...)
	for i = 1, select('#', ...) do
		if self:getIconData(select(i, ...)) then
			return true
		end
	end
	return false
end	
 
-- Analyses the page name and sets {{DISPLAYTITLE}}.
function Eras:renderDisplayTitle()
	local pagename = self.title.text
 
	-- Exit if we have been told not to set a title or if the title begins with
	-- an opening parenthesis.
	if self.noDisplayTitle or pagename:find('^%(') then
		return nil
	end
 
	-- Find the display base and the display parentheses.
	local dBase = self.displayTitleBase
	local dParen = self.displayTitleParen
	if not dBase or not dParen then
		-- Analyse the pagename to find base part and any ending parentheses.
		-- /Canon is removed, and parentheses are only recognised if they are
		-- at the end of the pagename.
		local trimmedPagename = pagename:gsub('/Canon$', '')
		trimmedPagename = pagename:gsub('/Légendes$', '')
		local base, paren = trimmedPagename:match('^(.*)%s*%((.-)%)$')
		if not base then
			base = trimmedPagename
		end
		-- Use the values we found, but only if a value has not already been
		-- specified.
		dBase = dBase or base
		dParen = dParen or paren
	end
 
	-- Build the display string
	local display
	if dParen then
		display = string.format('%s <small>(%s)</small>', dBase, dParen)
	else
		display = dBase
	end
	if self.title.namespace ~= 0 then
		display = mw.site.namespaces[self.title.namespace].name .. ':' .. display
	end
 
	-- Return the expanded DISPLAYTITLE parser function.
	return mw.getCurrentFrame():preprocess(string.format(
		'{{DISPLAYTITLE:%s}}',
		display
	))
end
 
-- Renders an eras icon from the given icon data. It deals with the image,
-- tooltip, link, and the category, but not the protection fields.
function Eras:renderIcon(data)
	-- Render the category at the end if it exists.
	if data.category then
		self:addCategory(data.category)
	end
	-- Render the icon and return it.
	local ret = {}
	ret[#ret + 1] = '[[File:'
	ret[#ret + 1] = data.image
	if data.tooltip then
		ret[#ret + 1] = '|'
		ret[#ret + 1] = data.tooltip
	end
	if data.link then
		ret[#ret + 1] = '|link='
		ret[#ret + 1] = data.link
	end
	ret[#ret + 1] = ']]'
	return table.concat(ret)
end
 
-- Renders a protection eras icon from the given data. If the page doesn't have
-- the specified protection level, returns nil and adds a flag to add a
-- tracking category later on in processing.
function Eras:renderProtectionIcon(data)
	if not data.protectionAction then
		return self:renderIcon(data)
	end
	local protectionLevel = self.title.protectionLevels[data.protectionAction]
	protectionLevel = protectionLevel and protectionLevel[1]
	if protectionLevel and protectionLevel == data.protectionLevel then
		return self:renderIcon(data)
	else
		self.hasIncorrectProtectionIcon = true
	end
end
 
-- Renders the first icon, either Canon or Legends, or nil if the continuity
-- couldn't be determined. This is equivalent to the previous {{Eraicon/canon}}
-- template.
function Eras:renderContinuityIcon()
	-- First, find what continuity to use, if any.
	local continuity, isUsingCategory
	if self.continuityOverride == 'légendes' then
		continuity = 'légendes'
		if not self:hasAnyOfIcons('reel') then
		    isUsingCategory = true
		else
		    if self.typeArgs == 'légendes' then
			    isUsingCategory = true
			else
			    isUsingCategory = false
			end
		end
	elseif self.title.namespace == 0 then
		if self:hasLegendsTitle() then
			continuity = 'légendes'
			isUsingCategory = true
		elseif self:hasCanonTitle() then
			continuity = 'canon'
			isUsingCategory = true
		elseif self.legendsArticle then
			continuity = 'canon'
			isUsingCategory = true
		elseif self.canonArticle then
			continuity = 'légendes'
			isUsingCategory = true
		elseif exists(self.title.text .. '/Légendes') then
			continuity = 'canon'
			isUsingCategory = true
		elseif exists(self.title.text .. '/Canon') then
			continuity = 'légendes'
			isUsingCategory = true
		elseif self:hasAnyOfIcons('pre', 'btr', 'old', 'imp', 'reb', 'new',
			'njo', 'leg')
		then
			continuity = 'légendes'
			if self:hasAnyOfIcons('reel') then
			    if self.typeArgs == 'légendes' then
			        isUsingCategory = true
			    else
			        isUsingCategory = false
			    end
			else
				isUsingCategory = true
			end
		elseif self:hasAnyOfIcons('inf', 'noncanon') then
			continuity = 'noncanon'
			isUsingCategory = true
		elseif self:hasAnyOfIcons('reel') then
			if self.continuityOverride == 'canon' then
				continuity = 'canon'
				if self.typeArgs == 'canon' then
			        isUsingCategory = true
			    else
			        isUsingCategory = false
			    end
			end
		else
			continuity = 'canon'
			isUsingCategory = true
		end
	end
 
	-- Generate the icon data and make the icon.
	if continuity == 'canon' then
		local data = {
			image = 'Premium-Eras-canon.png',
			tooltip = 'Cet article parle d\'un sujet considéré comme Canon.',
			link = 'Univers officiel'
		}
		if isUsingCategory then
			data.category = 'Articles Canon'
		end
		return self:renderIcon(data)
	elseif continuity == 'légendes' then
		local data = {
			image = 'Premium-Eras-legends.png',
			tooltip = 'Cet article parle d\'un sujet considéré comme Légendes.',
			link = 'Univers étendu'
		}
		if isUsingCategory then
			data.category = 'Articles Légendes'
		end
		return self:renderIcon(data)
	elseif continuity == 'noncanon' then
	    local data = {
		image = "Premium-Era-inf.png",
		tooltip = "Ce sujet ne fait pas partie de la continuité officielle de l'univers Star Wars.",
		category = "Articles Hors-Continuité"
	    }
	    return self:renderIcon(data)
	end
end
 
-- Renders the icons that respond to a publishing era.
function Eras:renderPublishingIcons()
	if self.continuityOverride ~= 'canon'
		and not self.legendsArticle
		and not self:hasCanonTitle()
	then
		local ret = {}
		local codes = {'pre', 'btr', 'old', 'imp', 'reb', 'new', 'njo', 'leg', 'inf'}
		for _, code in ipairs(codes) do
			local data = self:getIconData(code)
			if data then
				ret[#ret + 1] = self:renderIcon(data)
			end
		end
		return table.concat(ret)
	end
end
 
-- Renders other icons, e.g. featured article status and protection status.
function Eras:renderNonPublishingIcons()
	local ret = {}
	local codes = {'reel', 'qualite', 'aqualite', 'bon', 'abon', 'comp', 'fca'}
	for _, code in ipairs(codes) do
		local data = self:getIconData(code)
		if data then
			ret[#ret + 1] = self:renderIcon(data)
		end
	end
	local protectionCodes = {'fprot', 'sprot', 'ssprot', 'mprot', 'uprot'}
	for _, code in ipairs(protectionCodes) do
		local data = self:getIconData(code)
		if data then
			ret[#ret + 1] = self:renderProtectionIcon(data)
		end
	end
	return table.concat(ret)
end
 
-- Render all the icons and eclose them in a surrounding div tag.
function Eras:renderIcons()
	local icons = {}
	icons[#icons + 1] = self:renderContinuityIcon()
	icons[#icons + 1] = self:renderPublishingIcons()
	icons[#icons + 1] = self:renderNonPublishingIcons()
	icons = table.concat(icons)
 
	local root = mw.html.create('div')
	root
		:attr('id', 'title-eraicons')
		:css('float', 'right')
		:css('position', 'static')
		:css('display', 'none')
		:wikitext(icons)
 
	return tostring(root)
end
 
-- Renders the Canon and Legends tabs for articles that are in both
-- continuities.
function Eras:renderCanonTab()
	if self.isHidden or self.title.namespace ~= 0 then
		-- Exit if we have been explicitly hidden or if we are not in the main
		-- namespace.
		return nil
	end
 
	-- Find the page type, canon title, and légendes title.
	local pageType, canonTitle, legendsTitle
	if self.legendsArticle then
		pageType = 'canon'
		canonTitle = self.title.text
		legendsTitle = self.legendsArticle
	elseif self.canonArticle then
		pageType = 'légendes'
		canonTitle = self.canonArticle
		legendsTitle = self.title.text
	elseif self:hasCanonTitle() then
		pageType = 'canon'
		canonTitle = self.title.text
		legendsTitle = canonTitle:match('^(.*)/Canon$') or canonTitle
	elseif self:hasLegendsTitle() then
		pageType = 'légendes'
		legendsTitle = self.title.text
		canonTitle = legendsTitle:match('^(.*)/Légendes$') or legendsTitle
	elseif exists(self.title.text .. '/Légendes') then
		pageType = 'canon'
		legendsTitle = self.title.text .. '/Légendes'
		canonTitle = self.title.text
	elseif exists(self.title.text .. '/Canon') then
		pageType = 'légendes'
		canonTitle = self.title.text .. '/Canon'
		legendsTitle = self.title.text
	else
		-- Could not determine that the article has both a Canon and a Legends
		-- version, so exit.
		canonTitle = ''
		legendsTitle = ''
		return nil
	end
 
	-- Add categories.
	--if pageType == 'canon' then
	--	self:addCategory('Articles Canon avec des Legends counterparts')
	--elseif pageType == 'legends' then
	--	self:addCategory('Legends articles with canon counterparts')
	--else
	--	self:addCategory('Outliers')
	--end
 
	-- Make the table root.
	local root = mw.html.create('table')
	root
		:attr('id', 'canontab')
		:css('text-align', 'center')
		:css('padding', '0')
		:css('margin', '0 0 5px 0')
		:css('border-left', '0')
		:css('border-right', '0')
		:css('border-top', '0')
		:css('border-bottom', '3px solid #002e54')
		:css('border-spacing', '0')
		:css('border-collapse', 'collapse')
		:css('width', '100%')
		:css('vertical-align', 'top')
 
	local row = root:tag('tr')
 
	-- This makes one Canon/Legends cell. Having this as a function rather than
	-- doing it with chaining allows us to avoid putting the same code in twice.
	local function makeCell(id, color, image, link, tooltip)
		local cell = mw.html.create('td')
		cell
			:attr('id', id)
			:css('padding', '0 0 5px 0')
			:css('background-color', color)
			:css('line-height', '0.75em')
			:css('font-size', '150%')
			:css('font-weight', 'bold')
			:css('width', '20px')
			:css('vertical-align', 'top')
			:tag('span')
				:addClass('content-bg rtop')
				:css('background', '#ffffff')
				:tag('span')
					:addClass('r1')
					:css('background', color)
					:done()
				:tag('span')
					:addClass('r2')
					:css('background', color)
					:done()
				:tag('span')
					:addClass('r3')
					:css('background', color)
					:done()
				:tag('span')
					:addClass('r4')
					:css('background', color)
					:done()
				:done()
			:wikitext(string.format(
				' [[File:%s|link=%s|%s]]',
				image, link, tooltip
			))
		return cell
	end
 
	local foregroundColor = '#002e54'
	local backgroundColor = '#d8e9fc'
 
	-- Make the canon cell.
	do
		local id = 'canontab-canon'
		local link = canonTitle
		local color, image, tooltip
		if pageType == 'canon' then
			color = foregroundColor
			image = 'Tab-canon-white.png'
			tooltip = 'Cet article couvre la version Canon de ce sujet.'
		else
			color = backgroundColor
			image = 'Tab-canon-black.png'
			tooltip = "Cliquer ici pour voir la version Canon de ce sujet."
		end
		row:node(makeCell(id, color, image, link, tooltip))
	end
 
	-- First separator cell
	row:tag('td')
		:attr('id', 'canontab-separator1')
		:css('width', '3px')
		:wikitext('&nbsp;')
 
	-- Make the legends cell
	do
		local id = 'canontab-legends'
		local link = legendsTitle
		local color, image, tooltip
		if pageType ~= 'canon' then -- is a Legends page
			color = foregroundColor
			image = 'Tab-legends-white.png'
			tooltip = 'Cet article couvre la version Légendes de ce sujet.'
		else -- is a Canon page
			color = backgroundColor
			image = 'Tab-legends-black.png'
			tooltip = "Cliquer ici pour voir la version Légendes de ce sujet."
		end
		row:node(makeCell(id, color, image, link, tooltip))
	end
 
	-- Second separator cell
	row:tag('td')
		:attr('id', 'canontab-separator2')
		:css('width', '3000px')
		:wikitext('&nbsp;')
 
	return tostring(root)
end
 
-- Render all the categories that were specified using Eras:addCategory or with
-- category flags.
function Eras:renderCategories()
	local fullPagename = self.title.prefixedText
	if fullPagename == 'Template:Eras' or fullPagename == 'Template:Eraicon' then
		-- Exit if we are on a blacklisted page.
		return nil
	end
 
	local pagename = self.title.text
 
	-- Renders one category.
	local function renderCategory(cat, sort)
		return string.format(
			'[[%s:%s|%s]]', 'Category', cat, sort or pagename
		)
	end
 
	local ret = {}
 
	-- Render categories from Eras:addCategory
	for i, t in ipairs(self.categories) do
		ret[i] = renderCategory(t.category, t.sortKey)
	end
 
	-- Render categories from category flags.
	if self.hasBadParameter then
		ret[#ret + 1] = renderCategory(
			'Articles avec de mauvais paramètre dans le Modèle:Univers'
		)
	end
	if self.hasIncorrectProtectionIcon then
		ret[#ret + 1] = renderCategory(
			'Articles avec un icône de protection incorrect.'
		)
	end
 
	return table.concat(ret)
end
 
-- This method is called when the tostring function is used on the Eras object.
-- (This works in a similar fashion to Eras.__index above.) It calls all the
-- top-level render methods and returns the final output.
function Eras:__tostring()
	local ret = {}
	ret[#ret + 1] = self:renderDisplayTitle()
	ret[#ret + 1] = self:renderIcons()
	ret[#ret + 1] = self:renderCanonTab()
	ret[#ret + 1] = self:renderCategories()
	return table.concat(ret)
end
 
-------------------------------------------------------------------------------
-- Exports
-------------------------------------------------------------------------------
 
local p = {}
 
-- This function is the entry point from other Lua modules.
function p._main(args)
	-- Define a function to call from pcall so that we can catch any errors
	-- and display them to the user rather than the cryptic "Script error".
	-- (It's not so cryptic if you click on it to see the error message, but
	-- not so many users know to do that.)
	local function getErasResult ()
		local erasObj = Eras.new(args)
		return tostring(erasObj)
	end
 
	-- Get the result. We only catch errors if debug mode is set to false.
	local success, result
	if DEBUG_MODE then
		success = true
		result = getErasResult()
	else
		success, result = pcall(getErasResult)
	end
 
	-- Return the result if there were no errors, and a formatted error message 
	-- if there were.
	if success then
		return result
	else
		return string.format(
			'<strong class="error">[[Template:Eras]] error: %s.</strong>' ..
			'[[' .. 'Catégorie:Articles avec de mauvais paramètres dans le Modèle:Univers]]',
			result -- this is the error message
		)
	end
end
 
-- This is the function accessed from wikitext. It must be accessed through
-- a template. The template should transclude only the text
-- "{{#invoke:Eras|main}}", and then when that template is used, any arguments
-- passed to it are magically sent through to the module.
function p.main(frame)
	local args = {}
	for k, v in pairs(frame:getParent().args) do
		v = v:match('^%s*(.-)%s*$') -- trim whitespace
		if v ~= '' then
			args[k] = v
		end
	end
	return p._main(args)
end
 
return p
 
-- </nowiki>
-- [[Category:Espace Modèle]]
* DIVULGATION : Certains des liens ci-dessus sont des liens d'affiliation, ce qui signifie que, sans frais supplémentaires pour vous, Fandom percevra une commission si vous cliquez et effectuez un achat.Sauf mention contraire, le contenu de la communauté est disponible sous licence CC-BY-SA.