模板擴展語法
幫助導航 |
---|
關於萌娘百科 • 常見問題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分41秒(北京時間2024年10月30日(星期三)20時01分41秒)為例說明各格式參數的作用。
格式參數 | 說明 | 顯示結果 |
---|---|---|
A | 顯示AM或PM | PM |
a | 顯示am或pm | pm |
c | 顯示長日期 | 2024-10-30T12:01:41+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:41 +0000 |
s | 秒數 | 41 |
t | 該月天數 | 31 |
U | 1730289701 | |
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語法。