跳轉到內容

Scribunto:入門/何時轉換模板

來自華夏公益教科書

在上一章中,我們瞭解到Scribunto是為了解決MediaWiki模板的效能問題而開發的。在Scribunto中,模板使用的大多數功能都是原生可用的,其他模板功能可以透過在Scribunto模組內部預處理原始模板程式碼來訪問。換句話說,Scribunto可以做模板能做的一切。此外,Scribunto中的單個操作比模板程式碼中的操作更快。那麼,是否應該將所有模板都轉換為使用Scribunto而不是模板程式碼呢?

嗯,不完全是。

是否轉換模板涉及多個因素,包括模板的複雜程度、它是否處理大量資料以及它包含哪些維基文字功能。評估轉換模板的影響也是一個好主意,以確保您明智地花費程式設計時間。在本頁中,我們將學習如何找到合適的模板進行轉換,以及哪些模板應該保持原樣。

不要轉換簡單的模板

[編輯 | 編輯原始碼]

首先,非常簡單的模板不應該轉換為Lua。主要由文字組成且不包含或幾乎不包含解析器函式的模板應該保持原樣。有兩個原因。

第一個原因是執行Scribunto時存在輕微的開銷。MediaWiki是用PHP程式語言編寫的,Scribunto模組是用Lua程式語言編寫的。從一種程式語言切換到另一種程式語言需要一些相當複雜的邏輯,這會佔用處理時間。準備執行Lua模組的成本在2到4毫秒之間,具體取決於使用的Scribunto版本。一旦Lua初始化,Lua程式碼的執行速度會比等效的模板程式碼快得多,但初始開銷意味著非常簡單的模板執行速度會比等效的Lua模組快。

第二個原因是,簡單的模板通常比等效的Lua模組更容易被編輯器閱讀。雖然模板可能充滿了條件邏輯和解析器函式,但它們最初的功能是在多個頁面上顯示相同或類似的內容。模板由於多年來積累的複雜性而獲得了難以閱讀的名聲;但是,包含大量文字的簡單模板很容易理解。另一方面,Lua模組具有專門的語法,適合表達複雜的邏輯。由於能夠縮排程式碼和添加註釋等,在Lua程式碼中而不是模板程式碼中表達複雜的邏輯通常更容易理解。但是,對於簡單內容,使用模板是更易讀的選擇。

您可以看到所有引數

[編輯 | 編輯原始碼]

Scribunto模組比模板有一個很大的優勢:您可以訪問模板的所有引數。要使模板能夠使用引數,必須在模板程式碼中顯式指定該引數。例如,假設我們正在使用一個名為“模板:Hello”的模板,它向某人問好。它有以下程式碼

Hello, {{{name}}}!

如果我們使用程式碼{{hello|name=Anna}}使用此模板,它將顯示“Hello, Anna!”。這對於任何使用過MediaWiki模板的人來說可能都很熟悉。但如果我們使用程式碼{{hello|name=Anna|abc=def}}呼叫它呢?

額外的引數不會對模板有任何影響;它只是顯示“Hello, Anna!”。但是,在Lua模組中,我們可以檢測到存在額外引數的事實,並根據它更改顯示值。例如,我們可以顯示一條錯誤訊息,提示“檢測到意外引數'abc'”。

任意引數

[編輯 | 編輯原始碼]

這種能夠看到傳遞給模板的所有引數的能力會產生一些有趣的影響。首先,這意味著Lua模組可以接受任意數量的引數。例如,考慮一個列印姓名列表的模板。它使用引數{{{1}}}{{{2}}}{{{3}}}等作為姓名值。在模板程式碼中,您必須指定每個編號引數,如果您想要輸出可變數量的引數,則必須測試每個引數是否存在。

List of names: {{{1}}}{{#if: {{{2|}}} | , {{{2}}} }}{{#if: {{{3|}}} | , {{{3}}} }} ...

這意味著模板可以輸出的姓名數量始終有一個上限。如果您想輸出20個姓名,模板程式碼中必須列出20個引數。但是,Lua沒有這樣的限制。您所要做的就是編寫一些程式碼來為一個姓名構建一個列表項,然後將該程式碼用於傳遞給模板的每個姓名。如果傳遞了20個姓名給模板,您將使用該程式碼20次。如果只傳遞了三個姓名給模板,您將只使用該程式碼三次。如果傳遞了1000個姓名給模板,仍然不會有任何問題來顯示它們。

能夠獲取傳遞給模板的所有引數是Lua比模板程式碼更快的最大原因之一。假設我們上面的示例模板被編寫為最多輸出10個姓名。

List of names: {{{1}}}{{#if: {{{2|}}} | , {{{2}}} }}{{#if: {{{3|}}} | , {{{3}}} }}{{#if: {{{4|}}} | , {{{4}}} }}{{#if: {{{5|}}} | , {{{5}}} }}{{#if: {{{6|}}} | , {{{6}}} }}{{#if: {{{7|}}} | , {{{7}}} }}{{#if: {{{8|}}} | , {{{8}}} }}{{#if: {{{9|}}} | , {{{9}}} }}{{#if: {{{10|}}} | , {{{10}}} }}

即使我們只需要一個包含三個姓名的列表,模板仍然檢查所有10個引數以檢視它們是否包含姓名。另一方面,Lua版本只會檢查我們傳遞給它的三個姓名。檢查引數需要相對較長的時間,因此Lua在類似此類應用中比模板程式碼具有很大的效能優勢。

因此,具有{{{1}}}{{{2}}}{{{3}}}等或{{{value1}}}{{{value2}}}{{{value3}}}等引數的模板幾乎總是應該轉換為Lua。

模板操作模板

[編輯 | 編輯原始碼]

某些模板旨在操作來自其他模板的引數。例如,英文維基百科上的模板:Unsubst與其他模板一起使用,以檢查它們是否被錯誤地替換。如果被替換,模板:Unsubst將輸出模板的未替換版本。模板:Unsubst要求模板作者手動輸入其模板使用的所有引數;但是,在模組:Unsubst中轉換為Lua之後,傳遞給模板的引數會自動檢測。如果您想編寫一個旨在處理傳遞給它的所有引數的模板,那麼Lua是使用的工具。

複雜模板

[編輯 | 編輯原始碼]

另一個主要考慮轉換為Lua的候選物件是複雜的模板。有時您會發現非常複雜的模板,它們包含許多解析器函式,並且呼叫也包含許多解析器函式的子模板,這些子模板又呼叫更多子模板……由於它們的層次結構很多,在Wikia上,這些模板被稱為inceplates,源於電影《盜夢空間》。這些模板是受益於轉換為Lua最多的模板。

華夏公益教科書