置顶公告:【置顶】关于临时开启评论区所有功能的公告(2022.10.22) | 【置顶】关于本站Widget恢复使用的公告
  • 你好~!欢迎来到萌娘百科镜像站!如需查看或编辑,请联系本站管理员注册账号。
  • 本镜像站和其他萌娘百科的镜像站无关,请注意分别。

Module:Sandbox/C8H17OH/ParamGroup

猛汉♂百科,万男皆可猛的百科全书!转载请标注来源页面的网页链接,并声明引自猛汉百科。内容不可商用。
跳到导航 跳到搜索
Template-info.svg 模块文档  [查看] [编辑] [历史] [刷新]
大萌字.svg
阅读本用户子页面的任何人都可以参与编辑

本模块用于将以一个参数的形式传入的“参数组”解析成多个参数并传给特定模板。

参数

本模块的接口函数名为main,参数包括:

参数名 描述 默认值
templatetl、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}}

用途

可以用于批量调用多参数模板。

详解

需求:批处理模板

有时候我们会试图利用解析器函数#fornumargs:或其他方法,在一个模板内多次调用另一个模板,将前者的每一个参数传给后者,同时可以批量添加一些分隔符等,从而避免在最终代码中多次调用后者和写入分隔符,起到减少最终代码的作用。这里前者称为“批处理模板”,后者称为“核模板”。

例如,假设我们想在{{人物信息}}的【发色】栏填写7种发色,那么代码一般为:

|发色={{发色|赤}}、{{发色|橙}}、{{发色|黄}}、{{发色|绿}}、{{发色|青}}、{{发色|蓝}}、{{发色|紫}}

假如我们有一个“批处理模板”{{多种发色}},那么代码就可以缩短为:

|发色={{多种发色|赤|橙|黄|绿|青|蓝|紫}}

对于熟练掌握fornumargs等解析器函数的资深编辑者,构造这样一个批处理模板并不是特别困难:

{{#fornumargs:num|value|{{#ifexpr:{{#var:num}}>1|、}}{{发色|{{#var:value}}}}

上面的例子中“核模板”{{发色}}有且只有一个参数。然而,我们的核模板常常是(或者需要是)具有多个参数的,参数的数量可能不固定,参数类型可能既有匿名又有实名,这时候构造一个批处理模板就很不简单了,至少本模块的创建者未能成功做到,直到创建并使用了本模块。

解决方案:参数组

如果我们可以把意图传入核模板的多个参数打包成一个“参数组”,在批处理模板的每个参数中填入一个参数组,似乎就可以实现批处理功能了。为此,观察模板使用的一般形式:

{{foo|arg1|arg2|key1=value1|key2=value2}}

{{foo|...}}中的...部分就是这里所说的“参数组”,即:

arg1|arg2|key1=value1|key2=value2

其中管道符|是组内两个参数之间的分隔符(delimiter),而等号是=连接每个实名参数的键(key,参数名)与值(value,参数值)的赋值号(assignment)。

为了将“参数组”打包在一个参数中,我们需要将管道符和等号替换成不会被直接解析的形式:

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
}}

如果嫌{{!}}{{=}}看着眼花,也可以改用其他的分隔符和赋值号,比如模仿CSS的风格,分别用分号和冒号:

{{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}}模板呢?

实现:使用本模块

可以利用本模块,构造{{foo batch}}如下:

{{#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}}
}}

用例

其他用途

当然,本模块也可以用于批处理模板以外的用途,虽然模块创建者并未想到其他必须这样构造“参数组”而不能直接给模板传参的场景。

注意事项

根据已有测试经验,与一般的模板使用类似:

  • 在分隔符、赋值号前后的空白字符不会影响正常使用。
  • 组内参数中不能出现分隔符,匿名参数的值中、实名参数的键中不能出现赋值号。
    • 对于这点,目前没有像{{!}}{{=}}一样的解决办法,只能要求尽可能选用不会出现的符号。

参见

  • 模块:Eval(调用本模块(保持delimassign为默认值)与调用{{eval|template|...}}等价)
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