解析器函数(未完成)
阅读
2024-11-20更新
最新编辑:史诗级的肉卷丝
阅读:
更新日期:2024-11-20
最新编辑:史诗级的肉卷丝
这个页面还没有完成,或仍有细节有待商榷。
你是不是在找:
初识模板
什么是模板?
模板,是一个标准wiki页面,可以被嵌入其它页面中。所有模板的页面名称前会有一个"模板:"作为它的命名空间。
创建一个模板很容易,就像其它页面一样。
接下来,举例一个最简单的模板使用案例:
有一个模板,页面名为"模板:欢迎"。它的全部内容如下:
你好,欢迎来到克鲁赛德战记wiki!
这样,它就是一个可用的模板了。如果你在其它页面输入{{欢迎}},就可以看到它显示了上面的文本。这也就是,模板的内容被"嵌入"了页面,与页面的内容进行了整合。
这个模板一经创建,就可以在wiki的任何页面(甚至是另一个模板!)中使用,输入{{欢迎}}就可以用来欢迎来访页面的人。
想象一下下面这个场景:有一百个页面需要欢迎别人,于是你Ctrl+C+V+V+V…全部录入完成了。但是,这个时候,你想改动欢迎别人的文本。如果不使用文本替换工具的话,又得一个个复制粘贴回去,这多麻烦!但是,假如你一开始使用的是{{欢迎}}模板,那么你只要改动模板页面的内容,就可以间接更改这一百个页面的内容。因为,这些页面是引用这个模板的。
怎么使用一个模板?
下面的方式可以使用一个模板:
{{模板名}}
或{{模板:模板名}}
:像上面提的那样,输入就可以使用。当带有这个模板链接的页面被加载时,模板的内容会动态地更新。
{{subst:模板名}}
:如此输入后,模板页面的内容就会直接成为页面的一部分,下次编辑时可以看到。如此引用模板的话,即使模板的内容更新,在该页面的模板的内容也不会更新。
{{safesubst:模板名}}
:递归替换的一种实现方式。具体效果未知。
{{msgnw:模板名}}
:直接引用模板内容的源代码,类似于使用了<nowiki>。
实际上,一个普通的wiki页面也可以被引用而嵌入其它页面,只需要指定其名字空间。
{{讨论:页面名}}
和{{:页面名}}
都可以直接引用以显示其包含的内容,而非创建超链接。
如果某个输入的命名空间不存在,则视为模板。如输入{{哈哈哈:模板名}}
,会调用[[模板:哈哈哈:模板名]]
的页面的内容。
参数
wiki允许一个模板调用和显示参数。由于模板起作用的方式,参数可以让模板能够适应更多情况,拥有更多功能。
假如你需要在某个页面感谢某人,例如:
感谢张三大佬对wiki的鼓励和支持。来自李四。
那么,如果想将这串文本的应用范围扩大至任何被感谢者和任何感谢者,仅仅在模板内加入一段纯文本是肯定不行的。于是,我们需要一个感谢模板来干这事。我们将上面的内容格式化一下,就是“固定文本+变量(被感谢者)+固定文本+变量(感谢者)+固定文本”的模式。现在我们创建一个页面,名为"模板:感谢",输入下列内容:
感谢{{{1}}}大佬对wiki的鼓励和支持。来自{{{2}}}。
看到了陌生的表示方式?这里的{{{1}}}和{{{2}}}即是所谓参数。所有的参数都是被三组花括号({{{}}}
)包围的。
在使用模板的时候,需要为参数赋值。否则,参数名和三组花括号都会显示出来(原 形 毕 露)。
在调用模板时,不同的参数之间需要用一个管道符(就是这个→|
)进行分隔。wiki允许三种为变量赋值的方式。
隐式赋值
按一定的顺序赋值。例如,我们在引用上面的感谢模板时,输入
{{感谢|张三|李四}}
于是输出
感谢张三大佬对wiki的鼓励和支持。来自李四。
隐式赋值时,必须注意各参数被赋值的顺序。假如把上面的输出的赋值顺序调换:
{{感谢|李四|张三}}
于是输出
感谢李四大佬对wiki的鼓励和支持。来自张三。
这样,感谢者变成了被感谢者,被感谢者变成了感谢者,倒 反 天 罡,就不符合我们的预期了。
编号赋值
按编号赋值。例如,我们在引用上面的感谢模板时,输入
{{感谢|2=李四|1=张三}}
这样,虽然没有按照变量声明的次序进行赋值,但是模板也正常显示:
感谢张三大佬对wiki的鼓励和支持。来自李四。
如果等号的右边仍有等号,则等号会被正常加入进模板。
输入 {{感谢|2=李四=|1==张三}} 输出 感谢=张三大佬对wiki的鼓励和支持。来自李四=。
名称赋值
与上面的编号赋值类似,这种方法只是将数字换成了更易理解的名称。CQwiki中99.9%的赋值方式都是这个。
现在,假设模板页面是这样的:
感谢{{{被感谢者}}}大佬对wiki的鼓励和支持。来自{{{感谢者}}}。
我们用了{{{被感谢者}}}
和{{{感谢者}}}
标记了参数。接下来,在引用这个模板时,输入
{{感谢|感谢者=李四|被感谢者=张三}}
就会输出
感谢张三大佬对wiki的鼓励和支持。来自李四。
这些命了名的参数是区分大小写的。并且,如果同一个名字的变量被赋值两次,写在页面更下方的值将被应用。
如果模板没有正常地被赋值的话,如上所述,会暴露出源代码即{{{变量名}}}。对于一些不想赋值或赋值内容过于重复的模板,可以加入默认值简化引用的过程。假设我们将感谢模板的页面内容更改如下:
感谢{{{被感谢者|每一位}}}大佬对wiki的鼓励和支持。来自{{{感谢者|wiki组全员}}}。
这样,直接输入{{感谢}}就会得到如下输出:
感谢每一位大佬对wiki的鼓励和支持。来自wiki组全员。
通常,默认值可以指定参数空缺或为空值时的内容。还可以通过嵌套来指定更多默认值:
{{{变量A|{{{变量B|}}}}}}
当变量A赋值变量B不赋值,或变量A和变量B都赋值时,显示变量A;变量A未赋值且变量B赋值时,显示变量B;变量A和变量B都没有赋值时,将输出空值。
数组的构建与处理
#arraydefine
分割一个字符串,并创建为数组变量。
默认的分隔符是,
。分隔符可以是:
- 一个简单符号,如
,
或、
。(实际上也属于字符串) - 一个字符串,如
233
、我是分隔符
。 - 一个正则表达式,如
/\s*,\s*/
。
在处理字符串的时候,分隔符周围的半角空格将被忽略。
创建一个空数组是允许的。
选项只有在指定了分隔符后才会应用,包括unique
、sort
和print
三个值。
- unique:将在数组定义完成后除去空值和重复值。
- sort:需要额外输入
none
/desc
/asce
/asc
/random
/reverse
以确认排序方式。具体见本页的#arraysort部分。将在数组定义完成后改变元素的排列顺序。 - print:需要额外输入
list
/pretty
以确认输出方式。将在数组定义完成后输出之。
输入{{#arraydefine:勇士里昂|里昂,成长的里昂,名人里昂,命运里昂,宿命里昂,光明剑士里昂|,|print=list}}
输出里昂、成长的里昂、名人里昂、命运里昂、宿命里昂、光明剑士里昂
(创建了数组变量:勇士里昂:里昂,成长的里昂,名人里昂,命运里昂,宿命里昂,光明剑士里昂
)
#arraysearcharray
在数组中提取包含关键字的元素,并利用这些元素创建一个新数组。
(并没有太理解,不过总之Ctrl+C+V好了)
-1表示无上限
勇士里昂:里昂,成长的里昂,名人里昂,命运里昂,宿命里昂,光明剑士里昂
输入{{#arraysearcharray:勇士里昂2|勇士里昂|/\s*命\s*/}}
输出(并没有输出)
(创建了数组变量:勇士里昂2:命运里昂,宿命里昂
)
勇士里昂:里昂,成长的里昂,名人里昂,命运里昂,宿命里昂,光明剑士里昂
输入{{#arraysearcharray:勇士里昂3|勇士里昂|/\s*命\s*/|0|1|时}}
输出(并没有输出)
(创建了数组变量:勇士里昂3:时运里昂
)
勇士里昂:里昂,成长的里昂,名人里昂,命运里昂,宿命里昂,光明剑士里昂
输入{{#arraysearcharray:勇士里昂4|勇士里昂|/\s*命\s*/|4|1|时}}
输出(并没有输出)
(创建了数组变量:勇士里昂4:宿时里昂
)
#arrayslice
在数组内截取一段指定范围的元素,并利用这些元素创建一个新数组。
偏移:数字,开始取的元素的索引值,可以是负数(将从数组末端开始索引)。如果偏移小于等于数组的元素数,函数将返回一个空数组;如果偏移不大于数组的元素数的相反数,则新数组将包含待处理数组中所有的元素。
长度:要提取的元素的数量。如果省略这个参数,则新数组将包含从 开始取的元素 到 数组末尾的元素 的所有元素。
勇士里昂:里昂,成长的里昂,名人里昂,命运里昂,宿命里昂,光明剑士里昂
输入{{#arrayslice:勇士里昂5|勇士里昂|2|2}}
输出(并没有输出)
(创建了数组变量:勇士里昂5:名人里昂,命运里昂
)
#arrayunique
清除数组中的空元素和重复元素。
勇士里昂6:里昂,成长的里昂,成长的里昂,,,光明剑士里昂
输入{{#arrayunique:勇士里昂6}}
输出(并没有输出)
(改变了数组变量:勇士里昂6:里昂,成长的里昂,光明剑士里昂
)
#arrayreset
重置数组,即删除数组所有元素及自定义过的选项。可以同时操作多个数组变量。
仅输入{{#arrayreset:}}的话,将清空所有之前定义的数组。
这些数组实际上会变成“未定义”状态。如果对它们进行检测,会发现它们已经不存在了。
勇士里昂3:时运里昂
,勇士里昂4:宿时里昂
,勇士里昂6:里昂,成长的里昂,光明剑士里昂
输入{{#arrayreset:勇士里昂3|勇士里昂4|勇士里昂6}}
输出(并没有输出)
(改变了数组变量:勇士里昂3:
勇士里昂4:
勇士里昂6:
)
#arraysort
对数组按一定法则进行排序。
排序方法中,可用的值:
- none:无。不对数组进行排序。
- desc:降序。将数组内的元素按倒序排序(从大到小)。
- asce或asc:升序。将数组内的元素按升序排序(从小到大)。
- random:随机。随机排列数组内的元素。
- reverse:倒序。将元素的排序反转,第一项成为最后一项,第二项成为倒数第二项,最后一项成为第一项。以此类推。
里昂,成长的里昂,名人里昂,命运里昂,宿命里昂,光明剑士里昂
输入勇士里昂:{{#arraysort:勇士里昂|random}}
输出(并没有输出)
(改变了数组变量:勇士里昂:里昂,成长的里昂,名人里昂,命运里昂,宿命里昂,光明剑士里昂
)
#arraymerge
#arrayunion
合并两个或更多个的数组为一个新的数组。arrayunion会忽略这些数组中的重复值。
勇士里昂2:命运里昂,宿命里昂
,勇士里昂5:名人里昂,命运里昂
输入{{#arraymerge:勇士里昂7|勇士里昂2|勇士里昂5}}
输出(并没有输出)
(创建了数组变量:勇士里昂7:命运里昂,宿命里昂,名人里昂,命运里昂
)
勇士里昂2:命运里昂,宿命里昂
,勇士里昂5:名人里昂,命运里昂
输入{{#arrayunion:勇士里昂8|勇士里昂2|勇士里昂5}}
输出(并没有输出)
(创建了数组变量:勇士里昂8:命运里昂,宿命里昂,名人里昂
)
#arraydiff
#arrayintersect
对比数组。
#arraydiff将从第一个数组中删去所有数组的交集元素,将剩下的元素合成为一个新数组,再去掉重复的元素和空元素;
#arrayintersect将取出所有数组的交集元素,将这些元素合成为一个新数组,再去掉重复的元素和空元素。
勇士里昂2:命运里昂,宿命里昂
,勇士里昂5:名人里昂,命运里昂
输入{{#arraydiff:勇士里昂9|勇士里昂2|勇士里昂5}}
输出(并没有输出)
(创建了数组变量:勇士里昂9:宿命里昂
)
勇士里昂2:命运里昂,宿命里昂
,勇士里昂5:名人里昂,命运里昂
输入{{#arrayintersect:勇士里昂10|勇士里昂2|勇士里昂5}}
输出(并没有输出)
(创建了数组变量:勇士里昂10:命运里昂
)
利用数组进行输出
#arrayprint
#arraymap
#arraymaptemplate
#arrayprint将数组变量的元素以字符串方式输出或操作。
#arraymap与其类似,不过输入的是一个形似数组的字符串,而不是数组。
#arraymaptemplate:未知的函数。
这些函数的输出都是字符串。
在操作中,若它们的输出包括管道符(作为其它函数的一部分),则需要转义为{{!}}。
如果待处理的数组不存在或是个空数组,则将输出空值。
默认的分隔符由wiki使用的语言决定。对于简中而言是、
。
选项只有在指定了分隔符后才会应用,包括unique
、sort
和print
三个值。
- unique:将在数组定义完成后除去空值和重复值。
- sort:需要额外输入
none
/desc
/asce
/asc
/random
/reverse
以确认排序方式。具体见本页的#arraysort部分。将在数组定义完成后改变元素的排列顺序。 - print:需要额外输入
list
/pretty
以确认输出方式。将在数组定义完成后输出之。
勇士里昂:里昂,成长的里昂,名人里昂,命运里昂,宿命里昂,光明剑士里昂
输入{{#arrayprint:勇士里昂|,|@hero|@hero好厉害啊}}
输出里昂好厉害啊,成长的里昂好厉害啊,名人里昂好厉害啊,命运里昂好厉害啊,宿命里昂好厉害啊,光明剑士里昂好厉害啊
输入{{#arraymap:里昂,成长的里昂,名人里昂,命运里昂,宿命里昂,光明剑士里昂|,|@hero|@hero好厉害啊|/}}
输出里昂好厉害啊/成长的里昂好厉害啊/名人里昂好厉害啊/命运里昂好厉害啊/宿命里昂好厉害啊/光明剑士里昂好厉害啊
#arrayindex
在一个数组中,返回第[索引值]项的内容。
注:我们看到的“数组的第一项”的索引值是0,第二项的索引值是1,以此类推。
索引值可以是负数,将从末尾开始进行索引。
例如,索引值为-1
,则将输出最后一个元素;-2
将输出倒数第二个元素。
下列的情况将导致输出默认值。
- 索引值不是数字。
- 数组不存在。
- 数组中不存在待索引的元素。(如数组有5项,索引值是5)
- 索引出的元素是空值。
勇士里昂:里昂,成长的里昂,名人里昂,命运里昂,宿命里昂,光明剑士里昂
输入{{#arrayindex:勇士里昂|2}}
输出名人里昂
勇士里昂:里昂,成长的里昂,名人里昂,命运里昂,宿命里昂,光明剑士里昂
输入{{#arrayindex:勇士里昂|233|你要找的是哪只里昂呢}}
输出你要找的是哪只里昂呢
#arraysize
返回一个数组的元素的数量。
如果指定的数组不存在,函数将输出数字0。这可以用于检查某个数组是否存在。
勇士里昂:里昂,成长的里昂,名人里昂,命运里昂,宿命里昂,光明剑士里昂
输入{{#arraysize:勇士里昂}}
输出6
#arraysearch
在数组中查找完全匹配的元素,并返回该元素的索引值或内容。
若数组中存在相同的两个元素,只取索引值更小的那个元素。
勇士里昂:里昂,成长的里昂,名人里昂,命运里昂,宿命里昂,光明剑士里昂
输入{{#arraysearch:勇士里昂|宿命里昂}}
输出4
创建与使用变量
#vardefine
#vardefineecho
用于定义一个变量。
定义数组用的是arraydefine。
#vardefineecho可以直接替换#vardefine。区别在于,#vardefineecho会在变量定义完成后输出之。
#var
可以使用一个变量,也可以用于定义变量。
#varexists
用于检测一个变量是否存在。
这个函数使用后,如果该变量存在将输出1,否则输出0。
这个函数使用后,如果该变量存在将输出<if-value>
,否则输出<else-value>
。
#var_final
函数将输出页面加载完成后,变量名的值。
如果你要使用#var_final的输出作为某个参数的话,请一定注意这个值是很多变的,需要自己检查代码避免bug。
条件函数
#ifeq
进行一次判断,并根据判断结果进行不同的操作。
{{#ifeq:<值1>|<值2>|<为真时输出>|<否则输出>}}
<值1>:字符串。可以是空值。 <值2>:字符串。可以是空值。 <为真时输出>:如果<值1>和<值2>完全相等,输出该值。 <否则输出>:如果<值1>和<值2>不完全相等,输出该值。
这个函数是大小写敏感的。
#if
这个函数用于检测某个值是否存在。
{{#if:<值>|<存在时输出>|<否则输出>}}
<值>:待检测的值。如果不是空值,则输出<存在时输出>。 <存在时输出>:<值>不是空值时的输出。 <否则输出>:<值>是空值或者不存在时的输出。
#switch
分支操作,根据变量的不同输出不同的值。
{{#switch:<关键词> |<分支1>=<输出1> |<分支2>=<输出2> |<分支3>=<输出3> |…… |<分支n>=<输出n> |#default=<默认输出> }}
<关键词>:待检测的输入值。它应该是变量,但也可以是定值。 <分支n>:如果<关键词>和任何一个分支值相同,输出<输出n>。 <输出n>:该值作为输出。 <默认输出>:如果<关键词>和任何一个值都不同,输出该值。
此外,多个值可以共同一个输出值。
{{#switch:{{#var:x}} |1|2|3=x是1到3的整数 |#default=x不是1到3的整数 }}
在上面这个示例中,当x是1、2或3时,都会输出同一个值,也就是“x是1到3的整数”。
只要是没有使用到的分支,解析器都会将其忽略。因此,很多看似很大一块的#switch其实相当节省内存。一个#switch通常只能流畅支持1000~1300条分支,当分支数达到2000时会大幅度降低页面加载速度。解决方法之一是,通过#ifeq或#ifexpr函数将字符串分割为几块,再分别使用#switch。
#ifexist(高开销)
这个函数可以用于检测站内网页是否存在(以https://wiki.biligame.com/cq/
为根目录)。引申的用法为检测一个文件是否存在。
{{#ifexist:<url>|<存在时输出>|<否则输出>}}
<url>:字符串。根目录后的内容,如“蕊儿”。 用于检测文件时,输入格式为“file:文件名.文件后缀名”。 <存在时输出>:如果这个页面/文件存在的话,输出这个值。 <否则输出>:如果这个页面/文件不存在的话,输出这个值。
下面是几个简单的示例:
{{#ifexist:蕊儿|1|2}}
1
{{#ifexist:file:蕊儿.png|1|2}}
1
{{#ifexist:这什么花里胡哨|1|2}}
2
#ifexist在Wikipedia语言中被视为“高开销函数”,这样的函数使用过多将导致性能问题。每个页面的高开销函数的使用总数会受到限制,多于这个数量的高开销函数不会执行。对于CQBwiki而言,这个限制数是100。
#iferror
这个函数可以用于检测某个函数是否报错(必须是报错,有的函数在无效时只是输出空值而已)。
字符串函数
参见>>解析器函数/字符串函数页面。
其它函数
#expr
进行一次表达式运算,然后输出运算结果或布尔值(以1和0表示真/假),再或者报错。
如果表达式中包括不等式运算符或等号,则将输出1或0。
常用的运算符号:
符号 | 运算 | 符号 | 运算 |
+ | 加 | - | 减 |
* | 乘 | / | 除 |
floor() | 向下取整 | ceil() | 向上取整 |
循环函数
#while
#dowhile
创建一个循环,在条件满足时会不断执行。
{{#while: |<条件文本> |<操作> }}
条件文本:如果这个位置的文本是true,则执行操作。
操作:你要执行的操作。
如果<条件文本>
是true,则该循环会不断执行<操作>
。死循环会导致wiki宕机,直接表现是网页加载时间远远长于平时。如果发现网络没问题但网页加载了很久也没有显示,多半是出现了死循环。硬等的话会出现“该网站未发送任何数据”等字样。
#dowhile可以用于直接替换#while,取得的输出完全相同。区别在于,#dowhile会确保循环至少执行一次。
条件文本
必须是true,循环才会执行。其它的任何值或空值都会退出循环。
#loop
创建一个循环,并使其执行可控的次数。
{{#loop:<变量名> |<初始值> |<执行次数> |<操作> }}
变量名:字符串。目标变量的名字,如i
。
初始值:数字。你要为这个变量设定的初始值,如0
。
执行次数:数字。它的绝对值是操作将要执行的次数,如-3
将执行3次,5
将执行5次。
操作:将执行的操作。如果<执行次数>
是正值,则执行后变量将+1,否则变量将-1。
定义一个名为<变量名>
的变量,赋予其<初始值>
,然后持续执行<操作>
,次数为<执行次数>
的绝对值。
<变量名>
可以随意选择。如果该变量不存在的话,函数会定义之;如果该变量存在,<初始值>
将覆盖原值。
#loop是最不吃资源的循环函数,因为它不需要频繁地检测某个条件。如果可以的话,尽量使用它。
#forargs(实验性)
#fornumargs(实验性)
#for
#foreach
杂项
各种括号
两个左括号"{{"
用于调用模板、发起#命令等,如{{将军须佐能乎}};
三个左括号"{{{"
用于调用变量,如{{{系列}}}
{{{1}}}返回传入该模板的第一个参数
{{{名字|}}} 若竖线左边不存在则返回竖线右边 该例返回空
引用链接
站内链接
输入 | 输出 |
[[标题]] | 链接至标题为“标题”的页面。 |
[[标题|显示文本]] | 显示为“显示文本”,点击后将链接至标题为“标题”的页面。 |
站外链接
输入 | 输出 |
[[超链接]] | 直接链接至“超链接”的内容。 |
[超链接] | 显示为[1](按顺序,下一个是[2],以此类推),点击后直接打开超链接。 |
[[超链接 文本]] | 显示为“文本”,点击后直接打开超链接。 |
全局变量
变量名 | 输入 | 输出 |
当前页名 | {{FULLPAGENAME}} | 解析器函数 |
当前年 | {{LOCALYEAR}} | 2024 |
当前月 | {{LOCALMONTH}} | 11 |
当前日 | {{LOCALDAY}} | 21 |
当前时 | {{LOCALHOUR}} | 16 |