Module:Sandbox/C8H17OH/ParamGroup
本模块用于将以一个参数的形式传入的“参数组”解析成多个参数并传给特定模板。
参数
本模块的接口函数名为main
,参数包括:
参数名 | 描述 | 默认值 |
---|---|---|
template 、tl 、1 |
模板名 | (必填) |
args 、2 |
“参数组” | 空 |
delim |
组内参数间分隔符 | {{!}}
|
assign |
键-值间赋值号 | {{=}}
|
regex |
是否使用正则表达式,非空为真 | 空 |
示例
以下各行
{{#invoke:Sandbox/C8H17OH|main|template=foo|args=arg1{{!}}arg2{{!}}key1{{=}}value1{{!}}key2{{=}}value2}} {{#invoke:Sandbox/C8H17OH|main|template=foo|args=arg1; arg2; key1:value1; key2:value2|delim=;|assign=:}} {{#invoke:Sandbox/C8H17OH|main|template=foo|args=arg1; arg2;key1:value1; key2:value2|delim=[;;]|assign=[::]|regex=on}}
结果都等同于
{{foo|arg1|arg2|key1=value1|key2=value2}}
用途
可以用于批量调用多参数模板。
详解 |
---|
需求:批处理模板有时候我们会试图利用解析器函数 例如,假设我们想在{{人物信息}}的【发色】栏填写7种发色,那么代码一般为: |发色={{发色|赤}}、{{发色|橙}}、{{发色|黄}}、{{发色|绿}}、{{发色|青}}、{{发色|蓝}}、{{发色|紫}} 假如我们有一个“批处理模板” |发色={{多种发色|赤|橙|黄|绿|青|蓝|紫}} 对于熟练掌握fornumargs等解析器函数的资深编辑者,构造这样一个批处理模板并不是特别困难: {{#fornumargs:num|value|{{#ifexpr:{{#var:num}}>1|、}}{{发色|{{#var:value}}}} 上面的例子中“核模板”{{发色}}有且只有一个参数。然而,我们的核模板常常是(或者需要是)具有多个参数的,参数的数量可能不固定,参数类型可能既有匿名又有实名,这时候构造一个批处理模板就很不简单了,至少本模块的创建者未能成功做到,直到创建并使用了本模块。 解决方案:参数组如果我们可以把意图传入核模板的多个参数打包成一个“参数组”,在批处理模板的每个参数中填入一个参数组,似乎就可以实现批处理功能了。为此,观察模板使用的一般形式: {{foo|arg1|arg2|key1=value1|key2=value2}}
arg1|arg2|key1=value1|key2=value2 其中管道符 为了将“参数组”打包在一个参数中,我们需要将管道符和等号替换成不会被直接解析的形式: arg1{{!}}arg2{{!}}key1{{=}}value1{{!}}key2{{=}}value2 这样在批处理模板中就可以这样填写: {{foo batch |case1_arg1{{!}}case1_arg2{{!}}key1{{=}}case1_value1{{!}}key2{{=}}case1_value2 |case2_arg1{{!}}case2_arg2{{!}}key1{{=}}case2_value1{{!}}key2{{=}}case2_value2 |case3_arg1{{!}}case3_arg2{{!}}key1{{=}}case3_value1{{!}}key2{{=}}case3_value2 }} 如果嫌 {{foo batch |case1_arg1; case1_arg2; key1:case1_value1; key2:case1_value2 |case2_arg1; case2_arg2; key1:case2_value1; key2:case2_value2 |case3_arg1; case3_arg2; key1:case3_value1; key2:case3_value2 }} 从批处理模板的使用者的角度,这样的代码已经非常简洁和清晰了。那么,如何实现 实现:使用本模块可以利用本模块,构造 {{#fornumargs:num|value| {{#invoke:Sandbox/C8H17OH|main|template=foo|args={{#var:value}}}} }} 如果替换了分隔符和赋值号,则为: {{#fornumargs:num|value| {{#invoke:Sandbox/C8H17OH|main|tl=foo|args={{#var:value}}|delim=;|assign=:}} }} 还可以启用正则表达式来实现更丰富的分隔符和赋值号,例如令二者都支持全角和半角: {{#fornumargs:num|value| {{#invoke:Sandbox/C8H17OH|main|foo|{{#var:value}}|delim=[;;]|assign=[::]|regex=on}} }} 用例其他用途当然,本模块也可以用于批处理模板以外的用途,虽然模块创建者并未想到其他必须这样构造“参数组”而不能直接给模板传参的场景。 |
注意事项
根据已有测试经验,与一般的模板使用类似:
- 在分隔符、赋值号前后的空白字符不会影响正常使用。
- 组内参数中不能出现分隔符,匿名参数的值中、实名参数的键中不能出现赋值号。
- 对于这点,目前没有像
{{!}}
和{{=}}
一样的解决办法,只能要求尽可能选用不会出现的符号。
- 对于这点,目前没有像
参见
local module = {} local getArgs = require('Module:Arguments').getArgs local String = require('Module:String') function module._main(args, frame) local template = args['template'] or args['tl'] or args[1] local argtext = args['args'] or args[2] or '' local delim = args['delim'] or '|' local assign = args['assign'] or '=' -- argtext = mw.text.decode(mw.text.unstripNoWiki(argtext)) -- delim = mw.text.decode(mw.text.unstripNoWiki(delim)) -- assign = mw.text.decode(mw.text.unstripNoWiki(assign)) if not args['regex'] then delim = String._escapePattern(delim) assign = String._escapePattern(assign) end local kvargs = mw.text.split(argtext, delim) local results = {} for i, kv in ipairs(kvargs) do local pos = mw.ustring.find(kv, assign) if (pos == nil) then results[#results + 1] = kv else local k = mw.ustring.sub(kv, 1, pos - 1) local v = mw.ustring.sub(kv, pos + 1) results[k] = v end end return frame:expandTemplate{title = template, args = results} end function module.main(frame) local args = getArgs(frame) return module._main(args, frame) end return module