Ce module a pour objectif d’aider à traiter les paramètres de modèles dans les modules LUA.
args
de type table
frame.args
ou frame:getParent().args
.defined_parameters
de type table
defined_parameters
dont la clé est le nom du paramètre et la valeur est une table qui peut contenir les entrées suivantes :
required
(booléen, défaut : false
) : indique que le paramètre est obligatoire.alias_of
(chaîne/entier) : le nom du paramètre dont ce paramètre est un alias.default
(chaîne/nombre/booléen) : la valeur par défaut, utilisée si l’argument n’est pas présent dans la table args.type
(chaîne) : le type du paramètre ; number
pour nombre, boolean
pour booléen, omit pour chaîne. Les valeurs autorisées pour le type booléen sont 1
, oui
et vrai
pour true
et 0
, non
et faux
pour false
.allow_empty
(booléen, défaut : false
) : indique si un paramètre obligatoire peut être laissé vide.checker
: précondition, fonction permettant de tester la valeur de l’argument ; elle doit posséder un seul paramètre et retourner un booléen. Ne peut pas être présent sur un alias.enum
: liste des valeurs autorisées pour le paramètre.alias_of
est présent, la valeur required
n’est pas prise en compte.required
est true
ou alias_of
n’est pas nil
, la valeur default
ne sera pas prise en compte.required
n’est pas présent ou est false
, la valeur allow_empty
ne sera pas prise en compte.alias_of
pointe vers un paramètre qui est lui-même un alias, n’existe pas ou vers lui-même, une erreur est lancée.checker
et enum
renseignés en même temps"Erreur interne :"
La fonction retourne les arguments avec leurs valeurs converties dans le type spécifié pour chaque paramètre.
On veut définir un modèle avec les paramètres pron
et lang
en tant qu’alias des paramètres 1
et 2
obligatoires.
local args = m_params.process(frame.args, { -- ou frame:getParent().args
= { required = true, allow_empty = true }, -- On autorise à laisser le paramètre vide.
= { required = true },
= { alias_of = 1 },
= { alias_of = 2 },
})
La variable args
est une table qui contient alors deux valeurs, aux indices 1
et 2
.
Même exemple qu’au-dessus sauf que cette fois-ci on veut passer sous silence les erreurs éventuelles levées par la fonction process
pour les traiter ultérieurement.
local args, success = m_params.process(frame.args, { -- ou frame:getParent().args
= { required = true, allow_empty = true }, -- On autorise à laisser le paramètre vide.
= { required = true },
= { alias_of = 1 },
= { alias_of = 2 },
}, true)
Si la fonction process
n’a pas rencontré d’erreurs, la variable args
est une table qui contient alors deux valeurs, aux indices 1
et 2
et la variable success contient une valeur booléenne égale à true
.
Si la fonction process
a rencontré une erreur, args
est une table de la forme { "valeur du paramètre erroné", "type de l’erreur", "message d’erreur" }
et success
vaut false
.
{ = { required = true } } -- paramètre positionnel
{ = { required = true } } -- paramètre nommé
{
= {},
= { alias_of = 1 }
}
{ = { default = "valeur par défaut" } }
{ = { type = "number" } } -- nombre
{ = { type = "boolean" } } -- booléen
{ = { } } -- chaîne
{ = { checker = function(s) return s == "a" or s == "b" end } }
{ = { enum = { "v1", "v2" } } }
{
= { required = true, allow_empty = true },
= { required = true },
= { alias_of = 1 },
= { alias_of = 2 }
}
La documentation de ce module est générée par le modèle {{Documentation module}}.
Elle est incluse depuis la page Module:paramètres/Documentation. Veuillez placer les catégories sur cette page-là.
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 m_table = require("Module:table")
local p = {}
-- Types
p.NUMBER = "number"
p.INT = "int"
p.FLOAT = "float"
p.BOOLEAN = "boolean"
-- Constantes d’erreur
p.UNKNOWN_PARAM = "unknown parameter"
p.MISSING_PARAM = "missing required parameter"
p.EMPTY_PARAM = "empty required parameter"
p.INVALID_VALUE = "invalid value"
p.VALUE_NOT_IN_ENUM = "value not in enum"
p.INVALID_TYPE = "invalid type"
p.ALIAS_TO_UNKNOWN = "alias to undefined parameter"
p.ALIAS_TO_ALIAS = "alias to alias parameter"
p.ALIAS_TO_ITSELF = "alias to itself"
p.ENUM_WITH_CHECKER = "enum with checker"
p.ENUM_INVALID_VALUE = "invalid enum values"
--- Liste des erreurs non masquées par le mode silencieux.
local UNCATCHABLE_ERRORS = {
p.INVALID_TYPE,
p.ALIAS_TO_UNKNOWN,
p.ALIAS_TO_ALIAS,
p.ALIAS_TO_ITSELF,
p.ENUM_WITH_CHECKER,
p.ENUM_INVALID_VALUE,
}
--- Liste des templates de messages d’erreur.
local ERROR_MESSAGES = {
= "Paramètre « %s » inconnu",
= "Paramètre requis « %s » absent",
= "Paramètre requis « %s » vide",
= 'Valeur invalide pour le paramètre « %s » ("%s") de type %s',
= 'Valeur invalide pour le paramètre « %s » ("%s")',
= 'Type inconnu pour le paramètre « %s » ("%s")',
= 'Paramètre « %s », alias vers un paramètre non défini « %s »',
= 'Paramètre « %s », alias vers un autre alias (« %s »)',
= 'Paramètre « %s », alias vers lui-même',
= "Le paramètre « %s » est une énumération avec une précondition",
= 'Valeur énumérée invalide pour le paramètre « %s » ("%s") de type %s',
}
--- Construit l’objet d’erreur.
--- @param errorType string Le type de l’erreur.
--- @vararg any Les données pour formater le message d’erreur.
--- @return table Un objet contenant le type d’erreur à l’indice "error_type" et les autres données à l’indice "error_data".
local function buildErrorMessage(errorType, ...)
return {
errorType = errorType,
errorData = { ... }
}
end
--- Convertit une chaîne en booléen.
--- true = "1", "oui" ou "vrai"
--- false = "0", "non" ou "faux"
--- @param argValue string La valeur à convertir.
--- @param argName string Le nom de l’argument correspondant à la valeur.
--- @param frTypeName string Le type attendu en français.
--- @return boolean La valeur booléenne du premier argument.
local function toBoolean(argValue, argName, frTypeName, errorType)
if m_table.contains({ "1", "oui", "vrai" }, argValue) then
return true
elseif m_table.contains({ "0", "non", "faux" }, argValue) then
return false
else
error(buildErrorMessage(errorType, argName, argValue, frTypeName))
end
end
--- Convertit une chaîne en nombre.
--- @param argValue string La valeur à convertir.
--- @param argName string Le nom de l’argument correspondant à la valeur.
--- @param toInt boolean Indique si le nombre doit être un entier.
--- @param frTypeName string Le type attendu en français.
--- @return number La valeur numérique du premier argument.
local function toNumber(argValue, argName, toInt, frTypeName, errorType)
local val = tonumber(argValue)
if val ~= nil then
if not toInt or toInt and val == math.floor(val) then
return val
end
end
error(buildErrorMessage(errorType, argName, argValue, frTypeName))
end
local function getValue(expectedType, rawValue, argName, errorType)
local value, frTypeName
-- Vérification des types des arguments.
if expectedType == nil then
frTypeName = "chaîne"
if type(rawValue) ~= "string" then
error(buildErrorMessage(errorType, argName, rawValue, frTypeName))
end
value = rawValue
elseif expectedType == p.NUMBER then
frTypeName = "nombre"
value = toNumber(rawValue, argName, false, frTypeName, errorType)
elseif expectedType == p.INT then
frTypeName = "entier"
value = toNumber(rawValue, argName, true, frTypeName, errorType)
elseif expectedType == p.FLOAT then
frTypeName = "flottant"
value = toNumber(rawValue, argName, false, frTypeName, errorType)
elseif expectedType == p.BOOLEAN then
frTypeName = "booléen"
value = toBoolean(rawValue, argName, frTypeName, errorType)
end
return value, frTypeName
end
--- Vérifie la validité des définitions des paramètres.
--- @param definedParameters table La définition des paramètres.
local function checkParametersDefinitions(definedParameters)
local validTypes = { p.BOOLEAN, p.NUMBER, p.INT, p.FLOAT }
for paramName, paramValue in pairs(definedParameters) do
if paramValue.type and not m_table.contains(validTypes, paramValue.type) then
error(buildErrorMessage(p.INVALID_TYPE, paramName, paramValue.type))
end
if paramValue.enum then
if paramValue.checker then
error(buildErrorMessage(p.ENUM_WITH_CHECKER, paramName))
else
for _, enumValue in ipairs(paramValue.enum) do
-- Vérification du type de la valeur.
getValue(paramValue.type, enumValue, paramName, p.ENUM_INVALID_VALUE)
end
end
end
if paramValue.alias_of then
local alias = paramValue.alias_of
if not definedParameters then
error(buildErrorMessage(p.ALIAS_TO_UNKNOWN, paramName, paramValue.alias_of))
elseif alias == paramName then
error(buildErrorMessage(p.ALIAS_TO_ITSELF, paramName))
elseif definedParameters.alias_of then
error(buildErrorMessage(p.ALIAS_TO_ALIAS, paramName, paramValue.alias_of))
end
end
end
end
--- Extrait la clé de l’argument donné après avoir résolu l’alias éventuel.
--- @param param table La définition du paramètre.
--- @param processedArgs table Les paramètres en cours de traitement.
--- @param argName string Le nom du paramètre.
--- @param processedArgs table La définition des paramètres.
--- @return string|nil,table|nil Le nom du paramètre à utiliser et le paramètre réel ou nil si le paramètre
--- est un alias dont l’argument de base a déjà une valeur.
local function extractArgumentKey(param, processedArgs, argName, definedParameters)
local key
local outParam
if param.alias_of then
-- L’alias n’écrase pas la valeur du paramètre de base.
if not processedArgs then
key = param.alias_of
outParam = definedParameters
end
else
key = argName
outParam = param
end
return key, outParam
end
--- Extrait la valeur de l’argument donné.
--- @param param table La définition du paramètre.
--- @param key string Le nom de l’argument après résolution de l’alias.
--- @param argName string Le nom de l’argument de base.
--- @param processedArgs table Les arguments en cours de traitement.
local function extractArgumentValue(param, key, argName, argValue, processedArgs)
if argValue then
argValue = mw.text.trim(argValue)
end
if argValue == "" then
-- Un paramètre requis vide doit avoir la propriété allow_empty à true
-- pour ne pas lancer d’erreur.
if param.required and param.allow_empty or not param.required then
argValue = nil
processedArgs = nil
else
error(buildErrorMessage(p.EMPTY_PARAM, argName))
end
end
if argValue then
-- Récupération de la valeur après transtypage éventuel.
local value, frTypeName = getValue(param.type, argValue, argName, p.INVALID_VALUE)
-- Vérification des contraintes d’énumération ou de la précondition.
if type(param.enum) == "table" and not m_table.contains(param.enum, value) then
error(buildErrorMessage(p.VALUE_NOT_IN_ENUM, argName, value))
elseif type(param.checker) == "function" and not param.checker(value) then
error(buildErrorMessage(p.INVALID_VALUE, argName, value, frTypeName))
end
processedArgs = value
end
end
--- Traite les arguments.
--- @param args table Les arguments à traiter.
--- @param definedParameters table La définition des paramètres.
--- @return table Les arguments traités.
local function parseArguments(args, definedParameters)
local processedArgs = {}
for argName, argValue in pairs(args) do
local param = definedParameters
if param then
local key, actualParam = extractArgumentKey(param, processedArgs, argName, definedParameters)
if key then
extractArgumentValue(actualParam, key, argName, argValue, processedArgs)
end
else
-- Les paramètres non définis lancent une erreur.
error(buildErrorMessage(p.UNKNOWN_PARAM, argName))
end
end
return processedArgs
end
--- Vérifie que les paramètre requis sont effectivement renseignés.
--- @param processedArgs table Les arguments retournés par la fonction parse_args.
--- @param definedParameters table La définition des paramètres.
local function checkRequiredParameters(processedArgs, definedParameters)
for paramName, paramValue in pairs(definedParameters) do
if processedArgs == nil and paramValue.alias_of == nil then
if paramValue.required and not paramValue.allow_empty then
error(buildErrorMessage(p.MISSING_PARAM, paramName))
elseif paramValue.default ~= nil then
processedArgs = paramValue.default
end
end
end
end
--- Fonction permettant de traiter les arguments du module appelant.
--- Pour plus de détails, voir la documentation du module.
--- @param args table Les arguments du module appelant.
--- @param definedParameters table Les paramètres définis.
--- @param silentErrors boolean Si true, les paramètres problématiques sont retournés au lieu de lancer une erreur ; ne devrait être utilisé que dans le cas où un comportement précis est nécessaire.
--- @return table|string|number,boolean Une table contenant les paramètres traités ou le nom du paramètre ayant déclanché une erreur et un booléen indiquant le statut.
function p.process(args, definedParameters, silentErrors)
local success, result = pcall(function()
checkParametersDefinitions(definedParameters)
local processedArgs = parseArguments(args, definedParameters)
checkRequiredParameters(processedArgs, definedParameters)
return processedArgs
end)
if not success then
local errorType = result.errorType
local errorData = result.errorData
local errorMessage = mw.ustring.format(ERROR_MESSAGES, unpack(errorData))
if silentErrors and not m_table.contains(UNCATCHABLE_ERRORS, errorType) then
local argName = errorData
local argValue = type(argName) == "number" and tonumber(argName) or argName
return { argValue, errorType, errorMessage }, false
-- Ajout d’une mention pour les erreurs internes.
elseif m_table.contains(UNCATCHABLE_ERRORS, errorType) then
errorMessage = "Erreur interne : " .. errorMessage
end
-- Suppression de la trace de l’erreur, on garde juste le message.
error(errorMessage, 0)
end
return result, true
end
function p.checkParametersFromTemplate(frame)
local templateName = mw.ustring.sub(frame:getParent():getTitle(), 8)
local expectedArgs = {}
for _, arg in ipairs(frame.args) do expectedArgs = true end
local templateArgs = frame:getParent().args
local cats = ''
for templateArg, _ in pairs(templateArgs) do
if not expectedArgs then
cats = cats .. ']'
if not mw.title.new('Catégorie:Appel du modèle ' .. templateName .. ' avec le paramètre inconnu « ' .. templateArg .. ' »').exists then
cats = cats .. ']'
end
end
end
return cats
end
return p