Jump to content

Help:替换引用

本頁使用了標題或全文手工轉換
From mediawiki.org
This page is a translated version of the page Help:Substitution and the translation is 100% complete.

替换引用是在维基文本中引用了某个或多个模板变量、或解析器函数的情況下,當页面保存时所进行的维基文本自动转换

在替换模板时,模板的调用将替换为模板的内容,并替换其中的参数。 因此,模板被當作巨集般地使用,且該页面在保存时被巨集展開,而不是像常見的那样,是页面在浏览时才被巨集展開。

在变量的替换或解析器函数的替换這種情况,变量或解析器函数的參考(reference)将會被结果值替换。

替换的方法是将魔法字subst:、或safesubst:放在二個大括號之后、中间不留空格,如示例:{{subst:FULLPAGENAME}}{{safesubst:FULLPAGENAME}}safesubst:指令在多级替换中很有用,请参阅下面

可在保存前(也可不保存)按下“显示更改”键,(与現存的维基文本的差异)结果會顯示出來。 然而,如果文本涉及一个以上的段落,由于页边有加号,这种差異页就不太适合用來复制结果(例如,在不保存每一步的情况下进行逐步替换)。

应用

模板的替换:

  • 使得呈現的页面與模板无关:
    • 在模板被编辑之时,已呈現的页面不会被改变。
    • 可以复制页面到另一个MediaWiki的wiki,而无需連同模板一起复制。
  • 使得页面的呈現更容易,从而服务器的速度也更快。
  • 分析并演示模板的工作情形。 然而,在某些情况下,替換的工作方式是截然不同的。
  • 使得维基文本和被呈現页面之间的对应关系更容易理解(這也許适用,也可能正好相反)。

时间依赖变量的替换:

  • 使得呈現的页面與时间无关。

页面依赖变量的替换:

  • 使得呈現的页面不受页面重命名和复制维基文本到其他页面的影响(如果在页面的非包含部份使用变量PAGENAME来包含页面本身,则情况相反)。

某些MediaWiki的扩展有这样的限制:如果在带参数的模板中使用这些扩展,它们只能在模板被替换后才能運作。

概要

在討論替换的時候,「普通模板」是指,若不是以{{subst:pagename }}(針對模板命名空間中的頁面),就是以{{subst:fullpagename }}(針對其他命名空間中的頁面)的模式來引用的頁面。 「預先定義的模板」是指,以類似方式替换的變數解析器函數

替換是一個獨立的過程,早於任何一個:非替換的模板、變數、解析器函數、或參數,的擴張之前執行。

某個替换调用可以嵌入其它的替换调用到它的裏面。 同樣地,某個替換的被替換模板也可以包含其他替換调用。 會先對這些表達式進行替換:在模板或解析器函數名稱中的表達式、在被替換的模板的參數定義或解析器函數的參數定義中的表達式、以及在被替換的模板的正文中的表達式。

由於擴張是稍後才進行的,因此任何在替換中使用的表達式,如果碰巧包含有成對的雙大括號,則大括號會被視為純文字。 因此,在替換過程中,替換呼叫中帶大括弧的參數名稱 (例如 {{subst:foo|a{{bc}}d=...}}) 可能與模板內的正文的同名參數 (例如 {{{a{{bc}}d}}}) 相吻合。

如果嘗試對不存在之類的模板執行替換,則不會有替換,前綴「subst:」會保留在维基文本中。

在替換過程之後,對模板的擴張之類、以及其他對結果维基文本的那些處理,都會照常運作。 由於替換已經結束,因此無法撤銷在替換過程中發生的參數名稱不匹配(請參閱下面的「部份替換」一節)。

只有在下列內容完全求得值之後,才有可能進行替換:

  • 模板、变量、或解析器函数的名称
  • 在模板的情況下:模板呼叫和模板本身中的參數名稱
  • 在#if, #ifexpr, #ifexist和#iferror的情況下,冒號後的參數
  • 在#ifeq的情況下,冒號後的參數和下一個參數
  • 在#switch的情況下,冒號後的參數和等號左側的表達式

由於如前所述,替換是在其他擴張之前進行的,因此如果表達式涉及非替換的擴張,則上述所需的求值並未進行。

此外,在其他解析器函數的情況下,冒號之後的參數若未完全求值,會導致解析器函數套用於帶大括弧的维基文本,而非擴張後的维基文本,進而影響了結果。

例如:

  • {{subst:Help:L{{tc}}k}}有使用Template:tc,不進行替代,因為Help:L{{tc}}k不是現有頁面,儘管Help:L{{tc}}k呈現為Help:Link。 因此,生成的維基文本格式與原始維基文本格式相同,並呈現為{{subst:Help:Link}}。
  • {{#if:{{void|abc}}|yes|no}}(有使用Template:void)呈現為"no",所以{{subst:#if:{{subst:void|abc}}|yes|no}}也會同樣呈現為維基文本"no"。 另一方面,{{subst:#if:{{void|abc}}|yes|no}}會呈現維基文本"yes",因為Template:void是在替換之後才解析的。

原則上,完全替換產生的維基文本與普通包含的維基文本的呈現效果完全相同。

但請注意,在替換解析器函數時,參數值中使用的具有預設值的未定義參數不會被(在英文維基百科中)預設值所取代,例如,在替換#expr時,數值表達式中不允許使用該參數:

  • {{#expr:2*{{{p|3}}}}}會給出6, 而{{subst:#expr:2*{{{p|3}}}}}卻給出: Expression error: unrecognised punctuation character "{"

在替換那個包含此內容的模板時,{{{p|3}}}若不是被{{{p}}}的值所替換、就是被3所替換,因此不會出現複雜的情況。

{{ {{t6}} }}使用了內含有"t2demo|a<noinclude>[[Category:Demo templates]]</noinclude>"的Template:t6,會被呈現為{{ t2demo|a }}。 {{subst:{{subst:t6}} }}會給出维基文本{{subst:t2demo|a }}呈現相同的维基文本,並在下一次編輯/儲存時變更為start-a -middle{{2}}end。 {{ {{subst:t6}} }}會給出維基文本{{ t2demo|a }}呈現為start-a -middle{{2}}end。 這是因為,在無替代和完全替代這二者的情況下,在模板呼叫中的管道符號(不包括內層模板呼叫、模板參數、連結、和圖像標籤內的管道符號)決定了參數定義之間的分隔、以及與模板名稱之間的分隔。 此分隔並不取決於在模板名稱和參數定義的擴充格式中可能會多出的管道字元。 然而,如果在取代內層模板之後,外層模板呼叫中出現了管道符號,它就會像其他模板一樣,在決定分隔時發揮作用。 換句話說,解析會先進行一次置換、然後進行一次渲染,但在這兩種情況裏,中間不會有多出一次。 在只取代內層模板的情況下,隨後的兩次解析都會起作用。

當取代包含{{{p|q}}} (有預設值的參數標籤) 的模板時,如果已定義值為p,則會產生p的值,否則會產生q的值。 例如,(在英文維基百科中)使用{{timc|t pd}},{{subst:t pd}}會給出維基文本2。 如果頁面會取代自己 (例如在模板頁面的noinclude部份),它會取代舊版本。

注意事项

如前所述,普通模板在替代後的變更不會影響已被替代的頁面,而取決於時間的替代變量也不再取決於時間等。 然而,例如{{#expr:2*3}}的替換完全不會影響渲染。

頁面的維基文本與其渲染之間的關係在替換之後會變得更容易理解,因為有某個人把所有的維基文本都放在了一起、且參數已經替換了。

它也可以變得更複雜。 各別專注在理解模板呼叫和理解模板內容會比較容易。 替換之後的維基文本往往比直接撰寫需要的維基文本來得更複雜。

與模板呼叫不同(如果某人了解模板的話),替換後的維基文本不會顯示某人是如何產生類似的結果的。 維基文本可以又長又複雜,因此直接「寫」很麻煩;也可以很簡單,例如是某個計算所得出的數字,但要直接「找」就很麻煩。 當某人在研究某個頁面的維基文本時,可能會認為這個維基文本就是應該寫的、然後直接查找就可以得到結果,即使是在非常不切實際的這個情況下。

在這種情況下,模板呼叫的文檔就很用。 就像在電腦程式設計中,我們會修改原始碼和/或資料以產生新的結果,而不會直接去修改目標檔案一樣,在這裡我們會修改模板的呼叫和/或模板,而不是直接修改替換後所產生的維基文本。

普通模板

在替換普通模板的情況,模板標籤會被模板的維基文本所取代、參數會被參數值所替換。

範例: m:Template:t2,其包含有:
start-{{{1}}}-middle-{{{2}}}-end
並以 {{subst:t2|[[a]]|{{tc}}}} 形式(請參閱{{Tc }})呼叫時,會產生以下维基文本:
start-[[a]]-middle-{{tc}}-end,會呈現為
start-a-middle-in-end.

替換功能會移除noinclude的那一部份以及includeonly的標籤。

参数:

  • 以p=r進行替換時,{{{p}}}和{{{p|q}}}會被r所取代。 此情況包含r的值為{{{s}}}或{{{s|t}}}的形式。
  • 替換的p未定義時,將保留{{{p}}},並且(在英語維基百科中){{{p|q}}}會被預設q所取代。

subst: 的情形中,模板標籤由维基文本取代的功能不具備遞迴作用。 欲執行完整的遞迴替換,請使用 Special:ExpandTemplates。 另請參閱substall、以及下文的多级替换

逐步替換包含有其他模板(它包含有更多的模板等等)的模板的方法,對於分析和記錄複雜模板的行為會有所助益。

然而,頁面在進行替換後可能會呈現不同的樣貌。例如:若模板產生花括号、垂直線、及/或等號,這些符號在替換後會觸發其他模板的展開,但在未經替換時這些符號會被視為純文字處理。

在不具有參數的情況下,模版替換可比擬為複製維基文本的效果、或是某個已預覽的/已儲存的{{ msgnw:頁面名稱 }}嵌入後的呈現效果。 然而,模板替換會排除‎<noinclude>的部份、移除‎<includeonly>的標籤,並以其預設值替換掉那些未定義的參數。

预先定义模板

在替換預先定義的模板的情況時,若該模板並沒有依賴其他模板的參數,則標籤將被結果所替換。

subst:必須直接加在預定義模板的名稱之前,且中間不得有任何空格

將subst套用至變數的方式,如同是將它套用至模板的方式一樣。 例如,這是一個時間戳記:

{{subst:CURRENTYEAR}}-{{subst:CURRENTMONTH}}-{{subst:CURRENTDAY}} T {{subst:CURRENTTIME}} [[w:UTC|]]

可能會解釋出這樣的维基文本:

2010-04-10 T 06:30 [[w:UTC|UTC]]

而呈現為:

2010-04-10 T 06:30 UTC

在需以參數取代預先定義的模板、而該參數又依賴於另一個模板的情況時,則該模板同樣亦須透過單獨的修飾符subst:進行替換,否則結果就是未定義。

  • {{subst:UC:{{subst:tc}}}} – 給出"IN"這個字,與{{UC:{{tc}}}}展開後得到相同的维基文本;UC:被套用在Tc的輸出"in"。
  • {{subst:ns:{{subst:#expr:2*3}}}} – 給出"File"。
  • {{ns:{{subst:#expr:2*3}}}} – 給出維基文本{{ns:6}},其呈現為File。
  • {{subst:t1|{{subst:NAMESPACE}}}} – 給出維基文本startHelpend(請參閱{{T1 }})
  • {{subst:t1|{{subst:#expr:3*4}}}} – 給出維基文本start12end
  • {{subst:t1|{{subst:uc:AbCdEf}}}} – 給出維基文本startABCDEFend
  • {{subst:#expr:{{subst:3X|11*}}1}} – 給出維基文本1331
  • {{subst:UC:{{subst:3X|abc}}}} – 給出維基文本ABCABCABC
  • {{subst:LC:{{subst:#expr:1/100000}}}} – 給出維基文本1e-05
  • {{subst:#expr:2*{{subst:CURRENTDAY}}}} – (在寫的那個當時)給出維基文本30
  • {{subst:UC:{{subst:CURRENTDAYNAME}}}} – (在寫的那個當時)給出維基文本THURSDAY

然而:

  1. {{subst:UC:{{tc}}}} – 給出維基文本{{TC}},其呈現為the current page's transclusion count
  2. {{subst:ns:{{#expr:2*3}}}} – 維持{{subst:ns:{{#expr:2*3}}}}不變,其呈現為{{subst:ns:6}}。

如前所述,在替換過程中,所有未經模板、變數、及解析器函數替換的呼叫皆會被視為純文字處理。 因此,在巢狀的{{ x:...{{ y:...}} }}中替換外層的x:,通常僅在所有內層y:也被替換時才適用。

在替換預先定義模板的情況時,若其中某個參數的表達式包含有{{{p|3}}},其帶有未定義的p,此程式碼將簡化為 3。 然而,在頁面本身中,{{{p|3}}}會被視為是{{{p|3}}},而非 3。

範例:

  • {{#expr:2*{{{p}}}}}Expression error: Unrecognized punctuation character "{".
  • {{#expr:2*{{{p|3}}}}}6
  • {{subst:#expr:2*{{{p|3}}}}}Expression error: Unrecognized punctuation character "{".
  • p未被賦予值,則替換包含有{{<includeonly>subst:</includeonly>#expr:2*{{{p|3}}}}}的模板會給出 6;若p「有」被賦予值,則結果為p的兩倍。
  • 若替換呼叫有一個參數「subst=subst:」,則可從包含有「{{{{{subst}}}#expr:2*{{{p|3}}}}}」的模板中獲得相同結果。

對比:

  • {{uc:2*{{{p}}}}}2*{{{P}}}
  • {{uc:2*{{{p|q}}}}}2*Q
  • {{subst:uc:2*{{{p|q}}}}} → 維基文本2*{{{P|Q}}},其呈現為2*Q。

(從上所述)還有:

  • {{subst:UC:{{subst:tc}}}} – 給出"IN"這個字,如同是{{UC:{{tc}}}}所呈現的;UC 被套用在Tc的輸出"in"。
  • {{subst:UC:{{tc}}}} – 給出維基文本{{TC}},其呈現為the current page's transclusion count

在替換UC時,標籤{{tc}}的包含會被視為是字串,就像{{{p|q}}}一樣。

部份替換

在普通模板的內部,可對包含一個參數的普通模板呼叫進行替換,將其取代為直接包含有該參數的维基文本。 這相當於自動合併兩個模板(創造出一個「複合模板」,其類似於複合函數)。 若內層和/或外層模板是預先定義模板,則無法實現。 (然而,手動合併(例如一個#expr的呼叫是位於另一個#expr的呼叫之中)有助於避免中間將結果四捨五入至 12 位數,從而提高結果的精確度。)

如此一來,便可省去下文所述的選擇性替換技術,然後單純使用subst:來替換最終的外層模板(除非存在更多的巢狀層級)。

示例:

  • {{subst:t}} – 給出維基文本start-{{{1|pqr}}}-end,就像是m:Template:t一樣,沒有noinclude的部份和includeonly的標籤
  • {{subst:t|a{{{p|q}}}b}} – 給出維基文本start-a{{{p|q}}}b-end

雙重替換的範例:

  • {{subst:3X|{{subst:t}}}} – 給出維基文本start-{{{1|pqr}}}-endstart-{{{1|pqr}}}-endstart-{{{1|pqr}}}-endstart-{{{1|q}}}-end
  • {{subst:3X|{{subst:t|{{{1|q}}}}}}} – 給出維基文本start-{{{1|q}}}-endstart-{{{1|q}}}-endstart-{{{1|q}}}-end

多層次替换

在進行模板替換時,不妨也在該模板內部執行一次替換。 這可以在模板中使用 safesubst: 來實現。

為防止過早進行替換(亦即在儲存模板之時),可在替換指令後附加‎<noinclude />指令——即safesubst:<noinclude />。 另一種解決方案是使用未使用的參數的預設值。 通常空字串(即 {{{|safesubst:}}})是有效的,但有時模組會將其用於呼叫模板或插入註解。 The cleanest way to prevent premature substitution in templates is to wrap the template code in ‎<includeonly>...‎</includeonly>, while using standard {{safesubst: calls inside; template presentation on the template page can then be managed from its documentation subpage.

subst:<noinclude />的差異在於,safesubst:<noinclude />在對safesubst:求值時,不僅允許多層次替換,同時也允許多層次嵌入,因為在嵌入過程中它會被忽略。 要使模板能夠在兩種選項之間進行選擇、同時也支援單層次替換(若涉及更多模板、變數、及/或解析器函數,則可提供更多選擇),則需有一個或多個參數,詳見下文說明。

可獨立控制每個替換操作的多層次替换

一個參數subst(也可有多個、各具專屬名稱)可用於 safesubst: 及空字串作為其可能值。 因此,我們可以,例如,當外層模板被替換時,控制內層模板是否也隨之被替換。 這二者的任一選項皆可設為預設值。

帶有參數的內層模板可採用相同方式控制更深層的內部替換;這些參數可能依賴於控制內層模板替換的替換參數,因為若該參數未被替換,則該模板內的內部替換將無法進行。

同樣地,若在內層模板中存在多個模板、變數、及/或解析器函數,我們可透過二種方式控制全部的替換,二擇一:採用不同參數進行獨立控制,或,部份或全部元素共用同一參數進行控制。

例如,假設模板T有使用參數subst1

  • T是以空字串為預設值時,T會呼叫那些內部模板與前綴有{{{subst1|}}}名稱的解析函式;若要呼叫T,可使用:
    • {{t|..}} – 無替換
    • {{subst:t|..}} – 單層次替換
    • {{subst:t|subst1=subst:|..}} – 雙層次替換
    • {{subst:t|subst1=safesubst:|..}} – 同上
  • T是以"safesubst:"為預設值時,T會呼叫那些內部模板與前綴有{{{subst1|safesubst:}}}名稱的解析函式;若要呼叫T,可使用:
    • {{t|..}} – 無替換
    • {{subst:t|subst1=|..}} – 單層次替換
    • {{subst:t|..}} – 雙層次替換

想要將替換與否的選擇權移交給在T內部模板中所呼叫的模板與解析器函數,我們可在這些內層模板的呼叫分別中添加類似subst2={{{subst1|}}}或subst2={{{subst1|safesubst:}}}的形式的東西(變數 解析器函數 不會獲得額外參數)。

部份替換

使用預先準備的可選 subst=subst: 模板進行普通替換(無需指定參數值),可將其代碼像複製貼上般嵌入其他模板,但所有的‎<noinclude>部份與關鍵字‎<includeonly>將自動被移除。 執行插入的程式碼而非呼叫它,對伺服器而言可能更有效率。

此技術的典型範例是在另一個模板中展開某個用作#switch:中的測試表達式的模板,例如m:Template:len

  1. 產出的程式碼:
    {{#switch: {{len|parameter tag}}|0=case 0 etc.}}
  2. 標準的程式碼:
    {{{{{subst|}}}#switch: {{{{{subst|}}}len|parameter tag|subst={{{subst|}}}}}|0=case 0 etc.}}
  3. 更佳的解決方案:透過套用此維基文本進行置換來建立模板程式碼:
    {{{{{subst|}}}#switch: {{subst:len|parameter tag}}|0=case 0 etc.}}

m:Template:len已準備好進行可選替換,因此兩種解決方案皆可行,但後者直接替換其程式碼的方案更為簡潔且高效。

請參閱m:Template:csnm:Template:lz12,以了解Template:len是如何以此方式替代的情況。

若某個模板使用了一個參數,其名稱是一個包含另一個模板或解析函數之表達式,且該模板以對應參數定義(以參數最終名稱為準)進行呼叫時,僅當在模板展開時,該參數名稱的表達式已完成評估,方能正確展開。 因此,若在替換模板時未將參數名稱的表達式進行替換,參數定義便會「遺失」,導致該參數成為未定義狀態。 因此在此情況下,任何替代都無法產生與完全替代相同的結果,而部份替代則會產生不同的結果。 請参见示例m:Template:ts1

複合運算

透過{{A|{{B|p}}}}呼叫模板A時,會將模板B的參數p作為其參數傳入。 我們可將此類模板的呼叫整合為單一呼叫{{C|p}},即帶有參數為p的「複合模板C

模板C的維基文本應該是{{A|{{B|{{{1}}}}}}},或可運用選擇性的替代,如下列的結構: :
{{ {{{subst|}}} A|{{ {{{subst|}}} B|{{{1}}} |subst={{{subst|}}} }} |subst={{{subst|}}} }}
如前所述,subst={{{subst|}}}僅用於遞迴替換時需要。

請注意,指定{{subst|subst:}}並無助益,因為在替換階段中,此標籤不會簡化為預設的subst:

A和(或)B已預先定義,則該結構類似,但模板中未包含subst={{{subst|}}}

includeonly

防止過早替換的另一種方法稱為「includeonly subst magic」,需使用一對includeonly標籤。 透過在這些標籤內呼叫模板,即可防止內容被替換。 替換機制亦會因以下情況而受阻:當一個或兩個標籤出現在模板呼叫的任何位置(在參數定義的內部除外)。 因此標籤可置於safesubst:subst:的之前、內部、或之後,亦可置於模板名稱的內部或之後。 兩個標籤的位置僅影響模板頁面本身的呈現效果。

{{<includeonly>safesubst:</includeonly>something}}形式暗示了替換被阻止是因為頁面本身捨棄了safesubst:,但實際上替換被阻止是因為標籤擾亂了safesubst的語法。

它並非是相關的模板在建立之時取代「something」,而是在模板被替換時產生預期的效果。

例如,請參見擴充功能:輸入框 中的「預載」及 說明:魔法字 中的「替換」。

建立一個在下次儲存時執行替換的頁面

請参见Manual:Recursive conversion of wikitext

強制替換

某些模板會刻意拒絕未經替換的引用。 这个机制对于那些会渲染出自身(第一次)被调用的时间的模板,比如会直接显示时间(比如英文维基的Proposed deletionCURRENTISOTIME模板)和按照时间将使用模板页面加入特定分类中的模板。

在以下任一個T模板的代碼中,都會輸出警告訊息,除非正在執行subst=subst:的遞迴替換:
{{{{{subst|}}}ifdef|{{{{{subst|subst:}}}ns:0}}|'''Warning'''}}.
  1. {{T}}{{subst:T}}的輸出 – Warning
  2. {{T|subst=subst:}}的輸出 – Warning
  3. {{subst:T|subst=subst:}}的輸出 – 無(沒有殘留的維基文本)
這是一個罕見的情形,#if:替換掉ifdef無法直接奏效。

部份參數的替換

比如模板Feelings使用参数1和参数2。 考慮建立一個名為Emotions的模板,其包含一個參數1(對應於Feelings)、並為參數2指定值love。 然后让我们对比一下{{Feelings|2=love}}{{Feelings|1={{{1}}}|2=love}}。 这两个用法在模板页面看起来是一样的(例见m:Template:t ps),但是第一个写法并不会正常工作,因为{{{1}}}会被解释为文本,而不是参数。

然而,使用替换(比如subst:Special:Expandtemplates)生成的wikitext结果是一样的,因为无论是文本{{{1}}}还是1={{{1}}},它们都是参数,所以不需要写作1={{{1}}}

如果Feelings包含使用多个参数的表达式(比如#expr)也是一样的,但需要注意的是只能替换掉最顶层的表达式(Feelings),而无法替换掉内部的解析器函数,所以不能使用Special:Expandtemplates

一般来讲,先填充参数、再应用模板和解析器函数 有时和 先应用模板和解析器函数(保留三个大括号的写法)、再填充参数 的结果是相同的。

没有提供参数的默认值时(一步替换(一次提供所有参数并进行替换)与不替换的渲染结果相同):

结果相等的例子:

  • 比如Feelings模板,其内容为With {{{1}}} one can {{{2}}}
    • 当带着参数1=love2=help替换的时候,就会变成With love one can help
    • 如果只带着2=help进行替换,会变成With {{{1}}} one can help。 如果之后再带着1=compassion进行替换,就会变成With compassion one can help
  • 两层替换:一个含有{{#if:{{{4}}}|{{{3}}}p}}的模板。
    • 当带着参数3=u4=v替换的时候,就会变成up
    • 如果只带着4=v进行替换,会变成{{{3}}}p。 如果之后再带着3=u进行替换,就会变成up

结果不相等的例子:

  • 两层替换:一个含有{{#if:{{{3}}}|{{{4}}}p}}的模板。
    • 如果使用3=4=v替换,返回就是空的。
    • 如果带着4=v进行替换,会变成vp。 如果再使用3=u替换,它还是vp不变。
  • 两层替换:一个含有{{#if:{{{2}}}|{{{1}}}p}}的模板。
    • 当带着参数1=u2=v替换的时候,就会变成up
    • 如果只带着2=v进行替换,会变成{{{1}}}pp(由于bug会多一个p)。 如果之后再带着3=u进行替换,就会变成upp
  • 两层替换:一个含有{{#expr:{{{1}}}*{{{2}}}}}的模板。
    • 当带着参数1=72=8替换的时候,就会变成56
    • 如果只带着2=8进行替换,会变成Expression error: Unrecognised punctuation character "{"。 如果再使用1=7替换,它将保持不变。

因此,在不相等的情况下,我们可能会得到错误的结果,也可能直接收到报错消息。

其中一个例子表明,单个参数的代换可能会受到上述Bug的影响。 不过,我们可以通过将{{{1}}}替换为{{{1{{{{{substvoid|}}}void}}}}}来进行完全代换,因为substvoid未定义,所以可以防止这个bug发生。 结果在转储(transclusion,即正常调用模板)时就能正确工作。 随后,可以通过substvoid=subst:来进行替换,从而得到正常(plain)的{{{1}}}

如果给定了参数的默认值:

渲染结果与不进行替换时相同的情况:

  • 两层代换:模板内容为With {{{1|love}}} one can {{{2}}},当仅提供2=help进行代换时会返回With {{{1|love}}} one can help
  • 两层代换:模板内容为{{#if:{{{4}}}|{{{3|d}}}p}},当仅提供4=v进行代换时会返回dp

渲染结果与不进行替换时不相同的情况(出现差异或错误):

  • 两层代换:模板内容为{{#if:{{{3|}}}|{{{4}}}p}},当仅提供4=v进行代换时会返回vp
  • 两层代换:模板内容为{{#if:{{{2}}}|{{{1|d}}}p}},当仅提供2=v进行代换时会返回dpp(bug导致多一个p)。
  • 两层代换:模板内容为{{#expr:{{{1|6}}}*{{{2}}}}},当仅提供2=8进行代换时,会变成: Expression error: Unrecognised punctuation character "{"

在使用参数定义进行替换后:

  • {{subst:#if:{{{3|}}}|vp}}vp
  • {{subst:#if:v|{{{1|d}}}p}}dpp (bug导致的)
  • {{subst:#expr:{{{1|6}}}*8}}Expression error: Unrecognised punctuation character "{"

解决方案(避开上述问题):

  • {{subst:#if:{{subst:#ifeq:{{{3|+}}}|{{{3|-}}}|vp}}}} → 返回空字符串
  • {{subst:#if:v|{{subst:#ifeq:{{{1|+}}}|{{{1|-}}}|{{{1}}}|d}}p}}dp
  • {{subst:#expr:{{subst:#ifeq:{{{1|+}}}|{{{1|-}}}|{{{1}}}|6}}*8}}48

限制

引用替换在‎<ref>...‎</ref>‎<gallery>...‎</gallery>等解析器标签中不可用。 如果你输入{{subst:foo}},它将不会被替换也不会被嵌入,而是解析为普通文本。

文档替换

通过subst:使用模板不会自动显示在页面的历史记录中。 因此在编辑摘要中提供包含“subst:”的维基文本特别有用。

此外,有被替换的模板的页面不会显示在链入页面中,该模板也不会显示在编辑页面上的嵌入模板列表中。 该模板可以将页面添加到某个分类以追踪替换项,但将此分类列在页面上可能会使页面所属的内容类分类列表显得杂乱。 此外,noinclude标签之外的注释也会包含在wikitext中。 因此注释可用于提示模板。 它甚至可以包含参数的值,因为参数的替换即使在注释中也有效。

参阅