模板扩展语法
帮助导航 |
---|
关于萌娘百科 • 常见问题FAQ |
入门 |
Wiki使用指南 • 萌百入门教程 创建新条目 • 寻找原图 上传图片 • 使用图片 重定向建立&修正 • 消歧义 日语的处理 • 繁简处理 制作投票 • 测试用沙盒 |
编辑 |
编辑规范 • 条目命名 条目编写 • 模板规范 收录范围 • 魔术字 媒体帮助 • 帮助列表 |
模板扩展语法是一个MediaWiki扩展,包含多个解析函数解释器。本扩展的典型语法是:
- {{#函数名: 参数1 | 参数2 | 参数 3 …}}
目前有预定义的函数:expr,if,ifeq,ifexpr,switch(rand暂时被废除)等。
各函数名都对大小写不敏感。
语句中的空格、换行等空白字符将被省略。
函数
变量
#vardefine
vardefine函数,用于定义变量和变量赋值。语法为:
- 定义
{{ #vardefine: 变量名 | 表达式}}
- 使用
{{ #var: 变量名 | 备用值}}
变量名不需要声明,直接可以隐式赋值,在后面的例子中会用到。
在使用时,可以在#var第二个参数中填入一个备用值,在变量本身的值为空时,输出这个备用值。
#vardefineecho
{{ #vardefineecho: 变量名 | 表达式}}
#vardefineecho会在赋值的同时输出表达式的结果,相当于:{{ #vardefine:test | hello }}{{ #var:test }}
#var_final
输出变量的最终值。因为它会在处理完整个页面之后再展开,所以可以统计整个页面的数据。比如可以在Template:Legendary_Song定义变量Vocaloid_Song_Counter作为计数器,然后就可以在条目开头用{{#var_final:Vocaloid_Song_Counter}}
来显示整个页面上这个模板的使用总数(Vocaloid传说曲就是这么统计传说曲总数的)。如果是普通的#var,在条目开头就只能显示出空字串了。
{{ #vardefine: test | hello }} {{ #var: test}} // 显示“hello” {{ #var_final: test}} // 显示“你好” {{ #vardefine: test | 你好 }}
计算
#expr
expr函数,计算数学表达式。语法为:
{{ #expr: 表达式 }}
表达式支持的运算符有:
运算符 | 名称 | 优先级 | 元数 | 结合性 | 样例 |
---|---|---|---|---|---|
+ | 正 | 9 | 1 | 右 | {{#expr: + 7}} = 7 |
- | 负 | 9 | 1 | 右 | {{#expr: - 7}} = -7 |
not | 逻辑非 | 9 | 1 | 右 | {{#expr: not 7}} = 0 |
* | 乘 | 8 | 2 | 左 | {{#expr: 30 * 7}} = 210 |
/ | 除 | 8 | 2 | 左 | {{#expr: 30 / 7}} = 4.2857142857143 |
div | 除 | 8 | 2 | 左 | {{#expr: 30 div 7}} = 4.2857142857143 |
mod | 模 | 8 | 2 | 左 | {{#expr: 30 mod 7}} = 2 |
+ | 加 | 6 | 2 | 左 | {{#expr: 30 + 7}} = 37 |
- | 减 | 6 | 2 | 左 | {{#expr: 30 - 7}} = 23 |
round | 舍入 | 5 | 2 | 左 | {{#expr: 30 / 7 round 7}} = 4.2857143 |
= | 等于 | 4 | 2 | 左 | {{#expr: 30 = 7}} = 0 |
< | 小于 | 4 | 2 | 左 | {{#expr: 30 < 7}} = 0 |
> | 大于 | 4 | 2 | 左 | {{#expr: 30 > 7}} = 1 |
<= | 小于等于 | 4 | 2 | 左 | {{#expr: 30 <= 7}} = 0 |
>= | 大于等于 | 4 | 2 | 左 | {{#expr: 30 >= 7}} = 1 |
<> | 不等于 | 4 | 2 | 左 | {{#expr: 30 <> 7}} = 1 |
!= | 不等于 | 4 | 2 | 左 | {{#expr: 30 != 7}} = 1 |
and | 逻辑与 | 3 | 2 | 左 | {{#expr: 30 and 7}} = 1 |
or | 逻辑或 | 2 | 2 | 左 | {{#expr: 30 or 7}} = 1 |
round运算对运算数正负,位数正负都有不同的表现,参见下例。
逻辑运算符把假映射为0,把真映射为非0,且返回值只有0或1。
同一表达式中先计算高优先级运算。括号优先级高于一切。
条件
#if
if函数是一个if-then-else结构。语法是:
{{#if: <判断字符串> | <then字符串> [| <else字符串> ]}}
若判断字符串为非空字符串(忽略前导或后缀空格),则函数返回then字符串,否则函数返回else字符串。else字符可被省略而不会造成错误,但函数在判断字符串为空时便会返回空字符串。
#ifeq
ifeq比较两个字符串,返回比较结果。语法为:
{{#ifeq: <字符串1> | <字符串2> [| <相等时返回的字符串> [| <不相等时返回的字符串> ]]}}
注意:两个空字符串是相等的。
#ifexist
ifexist根据指定名称的页面是否存在,返回两个参数中的一个。注意,该解析器函数开销较高!
- 用法
- {{#ifexist:待测页面标题|存在文字|不存在文字}}
示例:
- {{#ifexist:test|有test页面|无test页面}} 得到 无test页面
- {{#ifexist:user:sex|该用户存在|该用户不存在}} 得到 该用户不存在
- {{#ifexist:Calculation|Yes|Oops}} 得到 Oops
#ifexpr
ifexpr计算数学表达式,并根据计算结果返回字符串。
{{ #ifexpr: <表达式> | <then字符串> [| <else字符串>] }}
若表达式经计算不为0,则函数返回then字符串,否则函数返回else字符串。表达式语法与expr相同。
#switch
switch将一个值与多个预设值比较,若有匹配时则返回指定字符串,即双射。语法是:
{{ #switch: <比较值> | <预设值1> [= <结果1>] | <预设值2> [= <结果2>] | ... | <预设值n> [= <结果n>] | [#default = ]<缺省结果> }}
switch将从从左往右逐一尝试,直到出现匹配。函数将返回第一个匹配值对应的结果,而忽略后面的匹配值。如果没有匹配,函数将返回缺省结果。如果缺省结果没有设置,函数将返回空串。
注意:“缺省结果”是最后一个没有等号的预设值或“#default”预设值对应的结果;如果期望把一个包含“=”号的字符串作为缺省结果,则必须采用“#default”预设值形式。例如:
#default = <span style="color:red;">red</span>
switch也可用作满射(多对一,避免重复设置结果)。即某预设值后未设置结果,这样如果该预设值与比较值匹配,则函数返回第一个有结果的预设值的结果。例如:
{{ #switch: <比较值> | <预设值1> | <预设值2> | <预设值3> = <结果3> | <缺省结果> }}
如果比较值与预设值1或预设值2匹配,都将返回结果3。注意:“#default”后必须有“=”,但其它预设值可以使用“#default”的结果。
循环
#while
while执行一个循环(即它反复解析给定的wiki标记块语句),直到条件的标记评估为空。
{{ #while: | <condition text> | <block statement> }}
- 例如
{{ #vardefine: i | 0 }}{{ #while: | {{ #ifexpr: {{ #var: i }} < 5 | true }} | {{ #var: i }}{{ #vardefine: i | {{ #expr: {{ #var: i }} + 1 }} }}<br /> }}
输出:
0
1
2
3
4
{{#while}} 也能用于构建模板内的复杂参数。比如"Template:Loops Test"拥有下面这段代码:
{{#vardefine: i | 0}} {{#while: | {{{ arg{{#var: i }} |}}} | * {{{ arg{{#var: i }} }}}{{ #vardefine: i | {{ #expr: {{ #var: i }} + 1 }} }} }}
则在其他页面上调用Loop Test的代码为:
{{Loops Test |arg0=zero |arg1=one |arg2=two |arg3=three |arg4=four }}
输出结果:
- zero
- one
- two
- three
- four
需重点指出的是,空白字符,包括换行符,制表符和空格,是从这些解析函数从头到尾的所有参数中删除。如果这是不可取的,添加任何非空白字符(包括HTML编码的空白字符   )将防止进一步的删除(因此上面例子标记了 <nowiki/> )。
#dowhile
{{#dowhile}} 和 {{#while}} 基本一样。但与{{#while}}不同的是,此类循环是先执行一次后判断是否符合循环条件,所以可保证循环至少执行了一次。
#loop
{{ #loop: <变量> | <初始值> | <循环次数> | <输出的wiki内容> }}
{{#loop}} 将会重复分析执行 <输出的wiki内容>一定次数,其次数等于 <循环次数>的绝对值。 <初始值> 会被存放在变量 (可使用解析器函数VariablesExtension{{#var:}}进行访问)内, 变量名为 <变量>。每循环一次,若<循环次数>为正数,<变量>的值会加1;若<循环次数>为负数,<变量>的值会减1;
注释: 在所有循环函数中 #loop
的表现是最好的 , 因为它每次循环都是无条件执行 。但一个页面中loop或while循环执行总数太多(超过100次)会导致页面出错,谨慎使用。
- 示例
下列代码
{{#loop: varname | 4 | 4 | 这是第{{#var:varname}}轮, 还剩下{{#expr: 7- {{#var:varname}}}}轮<br /> }}
输出
这是第4轮, 还剩下3轮
这是第5轮, 还剩下2轮
这是第6轮, 还剩下1轮
这是第7轮, 还剩下0轮
#forargs (Experimental)
{{#forargs}}函数被用在模板中。它可以将模板内的实参储存在变量内。变量可以用 解析器函数{{#var:}}进行访问。
{{ #forargs: <prefix> | <key> | <value> | <block statement> }}
这个函数会逐步访问模板内每个以<prefix>开头的实参,每访问一次都会将实参名去掉<prefix>后,存放在<key>中, 就好像进行{{#vardefine: <key> }}操作一样。这个函数也会用类似的方法,将这些实参的值储存在<value>中。<block statement>是其扩展。你可以在<block statement>写入{{#var: <key> }}和{{#var: <value> }}来访问并修改加工被储存的实参。
- 栗子
如果页面"Template:Loops Test" 包含:
{{ #forargs: arg | key | value | * {{#var: key}} = {{#var: value}} }}
那么下面的wiki代码
{{Loops Test | arg1=val1 | spam=spammity | arg5=val5 | argument=value }}
就会输出
- 1 = val1
- 5 = val5
- ument = value
#fornumargs (Experimental)
{{ #fornumargs: <key> | <value> | <block statement> }}
{{#fornumargs}}与{{#forargs}}功能类似,但有两点主要的不同:1.它不会去掉实参的前缀。2.它只对数字实参有效,无论其是被准确地数字命名:
{{Template | 1=one | 2=two }}
还是不准确地命名:
{{Template | one | two }}
在同一模板混合使用这两种命名方式可能会导致实参值被覆盖,千万注意!
- 栗子
如果 "Template:Loops Test" 中含有:
{{ #fornumargs: number | value | * {{#var: number}} = {{#var: value}} }}
那么
{{Loops Test | Apricot | B = Bolognese | Caramel slice | 5 = Eclair }}
会输出
- 1 = Apricot
- 2 = Caramel slice
- 5 = Eclair
系统
#language
#language
得到指定语言代码的该语言名称。
- {{#language:de}} 得到 Deutsch
- {{#language:en}} 得到 English
- {{#language:ja}} 得到 日本语
- {{#language:nl}} 得到 Nederlands
- {{#language:zh}} 得到 中文
- {{#language:zh-cn}} 得到 中文(中国大陆)
- {{#language:zh-tw}} 得到 中文(台湾)
- {{#language:zh-hk}} 得到 中文(香港)
- {{#language:zh-sg}} 得到 中文(新加坡)
#time
time是一个时间日期格式化函数,它的语法为:
{{ #time: 格式参数 }}
或者
{{ #time: 格式参数 | 时间参数 }}
如果时间参数未指定,则使用该条目被转换为HTML的时间(值)。注意到由于缓存的缘故,这与条目被浏览的时间可能会有高达1星期的偏差。因此可能需要手工更新,方法是加上action=purge参数访问页面。
格式参数是一种格式字符,与在PHP的date中的用法相似。
下列格式代码与在PHP中的意义一样。所不同的是...
如果时间未被指定,则显示文章最后一次被转换成HTML的时间。由于缓存的关系,此时间和你浏览文章的时间可能有最长一个星期的差别。所以有时可能需要人工更新数据,方法是编辑文章但不做任何修改即保存。
参数format是表示格式的字符串,类似于PHP的时间格式.
以下格式代码和PHP中date()函数意义相同。除了国际化(主要是语言)造成的差别以外,所有和PHP的不同点都应当作为软件的错误进行报告。其中所有的数字输出都会被替换成当地语言的时间格式,可以使用xn(见下文)恢复成显示原来的数字。
代码 | 描述 | 输出(示例) |
---|---|---|
d | 一个月中的第 n 天,不足两位补充0 | 04 |
D | 星期的缩写,通常不国际化 | 三 |
j | 一个月中的第 n 天,不足两位不补0 | 3 |
l | 星期的全称,通常不国际化 | 星期三 |
F | 月份的的全称,通常需要国际化 | 10月 |
m | 数字表示的月份,不足两位补充0 | 01-12 |
M | 月份的的缩写,通常需要国际化 | 10月 |
n | 数字表示的月份,不足两位不补0 | 1-12 |
Y | 四位年份 | 2006 |
y | 二位年份 | 06 |
H | 小时,不足两位补充0 | 00-23 |
i | 分钟,不足两位补充0 | 00-59 |
s | 秒,不足两位补充0 | 00-59 |
以下代码是对PHP作出的扩展:
代码 | 描述 |
---|---|
xn | 将接下来的数字代码恢复成ASCII中的阿拉伯数字例如,在印地语中,{{ #time:H, xnH}}输出०६, 06。 |
xr | 将接下来的数字代码显示成罗马数字 |
xg | 输出月份名字的属格,只针对那些区分主格和属格的语言。 |
xx | 输出"x" |
任何其他字符都将不做处理直接输出。你也可以用引号来输出未经处理的字符串。
- 引号中的字符直接输出(但不输出引号),没有配对的引号也直接输出。例如:
- {{; #time: "现在是" F}} → 现在是 10月
- {{ #time:i's"}} → 20'11"
- 像PHP的date()函数一样的反斜杠转义也是支持的。 \H 直接输出 H , \" 直接输出 " 。
未来可能会增加更多格式代码,可能是完善PHP中已有功能,也可能是增加新功能。
参数time的格式参照PHP的strtotime()函数。它同时支持相对时间,如"+10 hours",用来表示时区转换。更多信息参见the GNU tar manual。
下表以国际协调时间(UTC)2024年10月30日(星期三)12时01分42秒(北京时间2024年10月30日(星期三)20时01分42秒)为例说明各格式参数的作用。
格式参数 | 说明 | 显示结果 |
---|---|---|
A | 显示AM或PM | PM |
a | 显示am或pm | pm |
c | 显示长日期 | 2024-10-30T12:01:42+00:00 |
D | 星期数,以一个汉字显示 | 三 |
d | 日期日数,有0补齐, | 30 |
F或M | 月份 | 10月 |
G或g | 当前UTC时间小时数,1位或2位数字 | 12 |
H或h | 小时数,2位数字 | 12 |
i | 分钟数,2位数字 | 01 |
j | 日数,2位数字 | 30 |
L | 日期星期数,1位数字,星期日为1,星期六为7 | 1 |
l | 日期星期数,3位汉字 | 星期三 |
m | 月份数,2位数字 | 10 |
N | 星期数,星期一为1,星期日为7 | 3 |
n | 月份数,1位或2位数字 | 10 |
r | 英文长日期格式 | Wed, 30 Oct 2024 12:01:42 +0000 |
s | 秒数 | 42 |
t | 该月天数 | 31 |
U | 1730289702 | |
W | 日期周数,显示日期为当年第几周 | 44 |
w | 星期数,星期日为0,星期六为6 | 3 |
Y | 日期年份,4位数字 | 2024 |
y | 日期年份,2位数字 | 24 |
z | 显示日期为当年第几日 | 303 |
系统默认的时间参数为当前UTC+0时间,可以使用{{#time:参数|+8 hours}}
得到当前北京时间(UTC+8时间)。
时间参数可以使用绝对时间,如“2008-12-31 23:59:59
”,也可以使用相对时间,如“+7 days
”或者“-5 hours
”得到默认时间7日之后或默认时间5小时之前的时间。也可以二者混合使用,比如{{#time:Y-m-d H:i:s|2001-2-3 04:05:06 +1 year +2 months +3 days +4 hours +5 minutes +6 seconds}}
返回
2002-04-06 08:10:12
使用xr
可以在其后显示罗马数字,如{{#time:xrY年xrm月xrd日|2008-12-31}}
显示为MMVIII年XII月XXXI日
#rel2abs
这个函数把一个相对文件路径转换为绝对文件路径。
{{#rel2abs: 路径 }}
{{#rel2abs: 路径 | 基础路径 }}
如下的 路径
的输入是符合语法的:
.
→ 当前层级..
→ 前往上一级/foo
→ 前往下一级的子目录 foo
如果 基础路径
没有被指定,那么当前页面的全页面名就会被使用:
{{#rel2abs: /quok | Help:Foo/bar/baz }}
→ Help:Foo/bar/baz/quok{{#rel2abs: ./quok | Help:Foo/bar/baz }}
→ Help:Foo/bar/baz/quok{{#rel2abs: ../quok | Help:Foo/bar/baz }}
→ Help:Foo/bar/quok{{#rel2abs: ../. | Help:Foo/bar/baz }}
→ Help:Foo/bar
不合规的语法,诸如 /.
或者 /./
会被忽略。因为没有任何两个以上的连续全停止被允许使用,这样的错误语法序列可以用于分割连续的序列:
{{#rel2abs: ../quok/. | Help:Foo/bar/baz }}
→ Help:Foo/bar/quok{{#rel2abs: ../../quok | Help:Foo/bar/baz }}
→ Help:Foo/quok{{#rel2abs: ../../../quok | Help:Foo/bar/baz }}
→ quok{{#rel2abs: ../../../../quok | Help:Foo/bar/baz }}
→ 错误:无效路径深度:“Help:Foo/bar/baz/../../../../quok”(尝试访问根节点以上节点)
#titleparts
这个函数将页面标题(页面名)用斜杠分割成段,并返回其中的一些段。
{{#titleparts: 页面标题(页面名) | 欲要返回的段数量 | 第一个返回的段 }}
如果参数 欲要返回的段数量 没有被指定,其默认值是 0,也就是返回从 第一个返回的段 开始的所有段(包括第一个返回的段)。如果 第一个返回的段 没有被指定,或者它的值是 0,其默认值是 1:
{{#titleparts: Talk:Foo/bar/baz/quok }}
→ Talk:Foo/bar/baz/quok{{#titleparts: Talk:Foo/bar/baz/quok | 1 }}
→ Talk:Foo See also {{Template:Ll}}.{{#titleparts: Talk:Foo/bar/baz/quok | 2 }}
→ Talk:Foo/bar{{#titleparts: Talk:Foo/bar/baz/quok | 2 | 2 }}
→ bar/baz{{#titleparts: Talk:Foo/bar/baz/quok | | 2 }}
→ bar/baz/quok
这里的两个参数都可以接受负值输入。给第一个参数 返回段的数量 传入负值将会从字符串尾端开始截取段。给第二个参数 第一个返回的段 传入负值意味从字符串右端开始计量段的数量:
{{#titleparts: Talk:Foo/bar/baz/quok | -1 }}
→ Talk:Foo/bar/baz 从字符串末尾截取一段。另请参阅 {{BASEPAGENAME}} 。{{#titleparts: Talk:Foo/bar/baz/quok | -4 }}
→ 从字符串末尾截取全部四段。{{#titleparts: Talk:Foo/bar/baz/quok | -5 }}
→ 从末尾开始截取五段(事实上欲截取的数量超过了实际数量)。{{#titleparts: Talk:Foo/bar/baz/quok | | -1 }}
→ quok 返回最后一段。另请参阅 {{SUBPAGENAME}}。{{#titleparts: Talk:Foo/bar/baz/quok | -1 | 2 }}
→ bar/baz 从字符串末尾开始截取一段并返回第二段和其前面的内容{{#titleparts: Talk:Foo/bar/baz/quok | -1 | -2 }}
→ baz 从倒数第二个元素开始复制,从字符串末尾开始截取一段
在处理前,页面标题(页面名)参数是没有被 HTML 编码的。如果它包含一些标准 HTML 字符,它们会被转换为纯文本(在内部以 UTF-8 编码,也就是和使用这个解析器函数的 MediaWiki 源代码页相同的编码)。
- 举个例子,在页面标题(页面名)里的任何
"
,"
或者"
都会被替换为"
。 - 其他从 HTML 到纯文本的转换不会被执行,因此即使在页面标题里的 HTML 标签的存在是不合法的,它们依旧会被保留。
subst
subst:可以像应用到模板和系统变量一样应用到模板扩展,但是在subst:和#之间不能有空格,否则无法正常工作。
表格
模板扩展函数中由于使用了“|”管道符做参数分隔符,所以不能包括表格所需要的“|”符。要想在输出中包含表格,可以通过以下三个办法达到:
- 通过使用魔术字
{{!}}
代替一个“|”符。在旧版本MediaWiki中,这个功能通过名为“!”的模板实现;更新版本的MediaWiki已将其升格为魔术字。 - 通过嵌套模板来达到隐藏“|”的目的。比如旧版MediaWiki中的
{{!}}
和现在仍在使用的{{(!}}
、{{!-}}
等。 - 使用HTML语法。