Módulo:Argumentos
Plantilla:Traducción
Este módulo provee un procesamiento fácil a los argumentos que pasan de #invoke
. Es un metamódulo, pensado para ser usado por otros módulos, y no debería ser llamado directamente desde #invoke
. Entre sus características se incluyen:
- Eliminar espacios en blanco al principio y final de los valores (no implementado todavía)
- Eliminar parámetros vacíos (no implementado todavía)
- Los argumentos pueden ser pasados por el marco actual y el marco padre a la vez (no implementado todavía)
- Los argumentos pueden ser pasados por otro módulo Lua o desde la consola de depuración.
- La mayoría de las características pueden ser personalizadas.
Uso básico
Para empezar, se debe cargar el módulo. Contiene una función, llamada obtenerArgumentos
.
<syntaxhighlight lang="lua"> local dameArgs = require('Módulo:Argumentos').obtenerArgumentos </syntaxhighlight>
En el escenario más básico, se puede usar obtenerArgumentos dentro de la función principal (usualmente main
).
La variable args
es una tabla que contiene los argumentos de #invoke.
<syntaxhighlight lang="lua"> local dameArgs = require('Módulo:Argumentos').obtenerArgumentos local p = {}
function p.main(marco) local args = dameArgs(marco) -- El código principal del módulo vas acá end
return p </syntaxhighlight>
Sin embargo, se recomienda usar una función solo para procesar los argumentos de #invoke. Esto significa que si se llama al módulo desde otro módulo Lua, no es necesario tener un objeto marco disponible, mejorando el rendimiento.
<syntaxhighlight lang="lua"> local dameArgs = require('Módulo:Argumentos').obtenerArgumentos local p = {}
function p.main(marco) local args = dameArgs(marco) return p._main(args) end
function p._main(args) -- El código principal del módulo vas acá end
return p </syntaxhighlight>
Si se quiere múltiples funciones que usen los argumentos, y que también sean accesibles desde #invoke, puede usarse una función envolvente.
<syntaxhighlight lang="lua"> local dameArgs = require('Módulo:Argumentos').obtenerArgumentos
local function hazFuncInvoke(fn) return function (marco) local args = dameArgs(marco) return p[fn](args) end end
local p = {}
p.func1 = hazFuncInvoke('_func1')
function p._func1(args) -- El código de la primera función va acá end
p.func2 = hazFuncInvoke('_func2')
function p._func2(args) -- El código de la segunda función va acá end
return p </syntaxhighlight>
Opciones
Las siguientes opciones están disponible, y son explicadas en las secciones de abajo.
<syntaxhighlight lang="lua"> local args = dameArgs(marco, { limpiarEspacios = false, removerVacios = false, fnValores = function (clave, valor) -- Código para procesar un argumento
end,
soloMarco = true, soloPadre = true, padrePrimero = true, envolventes = { 'Plantilla:Una plantilla envolvente', 'Plantilla:Otra plantilla envolvente'
},
soloLectura = true, noSobreescribir = true }) </syntaxhighlight>
Eliminar espacios y vacios
<syntaxhighlight lang="lua"> local args = dameArgs(marco, { limpiarEspacios = false, removerVacios = false }) </syntaxhighlight>
Personalización del formato de los argumentos
Algunas veces se desea remover algunos argumentos en blanco pero no otros, o tal vez poner todos los argumentos posicionales en minúscula. Para hacer cosas como estas, se usa la opción fnValores
. La entrada a esta opción debe ser una función que toma dos parámetros, clave
and value
, y devuelve un valor sencillo. Este valor es lo que se obtiene cuando acceda al campo clave
en la tabla de args
Ejemplo 1: esta función preserva los espacio en blanco para el primer argumento posicional, pero los elimina de los otros argumentos, y los elimina si quedan vacíos: <syntaxhighlight lang="lua"> local args = dameArgs(marco, { fnValores = function (clave, valor) if 1 == clave then return valor elseif valor then valor = mw.text.trim(valor) -- Elimina los espacios al comienzo y final del valor if ~= valor then -- Si el valor no quedó vacío return valor -- Lo devuelve end end return nil -- En otros casos, devuelve el valor nulo (es decir, no incluir el valor) end }) </syntaxhighlight>
Ejemplo 2: esta función elimina los argumentos vacíos y convierte todos los argumentos a minúsculas, pero no elimina los espacios del comienzo y final de los parámetros posicionales. <syntaxhighlight lang="lua"> local args = dameArgs(marco, { fnValores = function (clave, valor) if not valor then return nil end value = mw.ustring.lower(valor) if mw.ustring.find(valor, '%S') then return valor end return nil end }) </syntaxhighlight>
Nota: las funciones de arriba fallarán si se les pasa una entrada que no sea de tipo string
or nil
. Esto puede suceder si se usa la función dametArgs
en la función principal del módulo, y esa función es llamada desde otro módulo Lua. En este caso, es necesario comprobar el tipo de la entrada. Esto no es un problema cuando se usa una función específicamente para obtener los argumentos de #invoke; por ejemplo, cuando se usa una función para ese caso (usualmente p.main
) y otra ser usada por otros módulos (usualmente p._main
).
También, es importante destacar que la función fnValores
es llamada aproximadamente cada vez que se pide un argumento de la tabla args
. Por lo tanto, si se quiere mejorar el rendimiento debería verificarse no estar haciando nada ineficiente en ese código.
Marcos y marcos padre
Los argumentos de la tabla args
pueden ser pasados desde el marco actual o del marco padre a la vez. Para enteder qué significa esto, es más fácil dar un ejemplo. Digamos que tenemos un módulo llamado Módulo:EjemploArgs
, qu eimprime los primeros dos parámetros posicionales que se le pasen:
Envolventes
La opción envolventes se usa para indicar un número limitado de plantillas que funcionan como envolentes; es decir, cuyo único propósito es llamar al módulo. Si el módulo detecta que es llamado desde una de estas plantillas, solo comprobará los argumentos del marco padre; de lo contrario solo lo hará con el marco pasado a dameArgs
. Esto le permite al módulo ser llamado tanto desde #invoke como desde una envolvente sin la pérdida de rendimiento asociada a tener que comprobar ambos marcos (el actual y el padre) por cada argumento.
Escribiendo en la tabla args
Etiquetas ref
Limitaciones conocidas
local z = {} function z.obtenerArgumentos(frame) if frame.args[1] then return frame.args end return frame:getParent().args end function z.obtenerArgumentosConValor(frame) if frame == mw.getCurrentFrame() then argumentos = frame:getParent().args else argumentos = frame.args or frame end return require('Módulo:Tablas').copiarElementosConValor(argumentos) end -- Obtiene los argumentos con valores de la plantilla en minúsculas y con las -- tildes removidas, en caso de que las tenga de forma que sea más sencillo -- trabajar con las distintas variantes en los módulos. -- -- Nota: En caso de que haya parámetros duplicados tras la normalización solo -- se mantendrá el último valor procesado por la función. -- -- Parámetros de entrada: -- frame: El marco utilizado por el módulo -- -- Parámetros de salida: -- argumentosNormalizados: los argumentos con valor y nombre normalizado -- argumentosDuplicados: si la plantilla tiene varias veces el mismo -- argumento tras la normalización o no function z.obtenerArgumentosConValorNormalizados(frame) local argumentos = z.obtenerArgumentosConValor(frame) local argumentosNormalizados = {} local nombreNormalizado local argumentosDuplicados = false for nombre, valor in pairs(argumentos) do nombreNormalizado = nombre nombreNormalizado = mw.ustring.lower( nombreNormalizado ) nombreNormalizado = string.gsub(nombreNormalizado, "[á]", "a") nombreNormalizado = string.gsub(nombreNormalizado, "[é]", "e") nombreNormalizado = string.gsub(nombreNormalizado, "[í]", "i") nombreNormalizado = string.gsub(nombreNormalizado, "[ó]", "o") nombreNormalizado = string.gsub(nombreNormalizado, "[úü]", "u") if argumentosNormalizados[nombreNormalizado] then argumentosDuplicados = true end argumentosNormalizados[nombreNormalizado] = valor end return argumentosNormalizados, argumentosDuplicados end --[[ @name obtenerTablaDeArgumentos @global args @param frame @return table @descr Obtiene una tabla de argumentos tomando los parámetros recibidos tando desde la plantilla como desde la invocación de un módulo. En caso de duplicado tiene preferencia el valor de la invocación. Por ejemplo: con la plantilla: {{Plantilla |campo=valor |key=clave }} y la invocación: {{#invoke:Módulo |key=value }} se obtiene: { ['campo'] = 'valor', ['key'] = 'value' } --]] function z.obtenerTablaDeArgumentos(frame) -- global args args = {} local function paramMerge(orig, copy) local data = {} for key, val in pairs(orig) do data[key] = val end for key, val in pairs(copy) do data[key] = val end return data end if frame then -- parentArgs = frame:getParent().args or {} if type(frame.getParent) == 'function' then local parent = frame:getParent() if parent then args = paramMerge(args, parent.args) end end -- invokeArgs = frame.args or frame or {} if type(frame.args) == 'table' then args = paramMerge(args, frame.args) elseif type(frame) == 'table' then args = paramMerge(args, frame) end end return args end --[[ @name obtenerValorDeArgumentos @global args @param list @return string or nil @descr Obtiene el primer argumento válido desde una tabla de parámetros. Esta tabla de parámetros es una lista que contiene los nombres de los argumentos u otras tablas con las funciones para obtenerlos. Parámetros: con los argumentos: { ['campo'] = 'valor', ['key'] = 'value' } y usando la llamada: obtenerValorDeArgumentos{'dato', 'campo', 'key'} se obtiene el valor: 'valor' pues 'dato' no es un argumento y 'campo' es el primero encontrado Funciones: también se puede llamar con una función de la forma obtenerValorDeArgumentos{'dato', { obtenerDato, '1', '2' }} de forma que si el argumento 'dato' no existe se llama a la función obtenerDato('1', '2') --]] function z.obtenerValorDeArgumentos(list) -- global args local lang = mw.language.getContentLanguage() local err, key if type(list) == 'number' then key = args[list] elseif type(list) == 'string' then key = args[list] or args[lang:ucfirst(list)] elseif type(list) == 'table' then for num, val in ipairs(list) do if type(val) == 'string' then key = z.obtenerValorDeArgumentos(val) elseif type(val) == 'function' then err, key = pcall(val) if err ~= true then key = nil end elseif type(val) == 'table' then if val[1] and type(val[1]) == 'function' then err, key = pcall(val[1], unpack(val, 2)) if err ~= true then key = nil end end end if key ~= nil and key ~= '' then return key -- break end end end return key end return z