維基百科:Lua

命名空間
基本命名空間 討論命名空間
0 主/條目 幫助 討論 1
2 用戶 幫助 用戶討論 3
4 維基百科 維基百科討論 5
6 檔案 幫助 檔案討論 7
8 MediaWiki MediaWiki討論 9
10 模板 幫助 模板討論 11
12 幫助 幫助討論 13
14 分類 幫助 分類討論 15
100 主題 主題討論 101
102 維基專題 維基專題討論 103
118 草稿 草稿討論 119
126 格式手冊捷徑 PNS 格式手冊捷徑討論 127
710 字幕 字幕討論 711
828 模組 模組討論 829
1728 活動 活動討論 1729
2600 話題 幫助
虛擬命名空間
-1 特殊
-2 媒體

Lua程式語言目前通過MediaWiki上的解析器函數外掛程式引入到中文維基百科當中使用。要在模板中嵌入Lua指令碼,可加入解析器函數中的{{#invoke:}}功能。Lua原始碼存放在「模組」頁面中(如模組:Example),再以{{#invoke:}}來調用。模組頁面本身不支持切換中文語言變體。

用法

執行模組

普通維基頁面通過#invoke剖析器函數來調用模組。#invoke的句法與一般模板相似,但有些許不同。最重要的是必須指定函數名稱。函數會拿一組輸入值,通過一系列指令,輸出一個值。[1]這和模板很像:輸入參數,模板運作後,輸出一個值。Lua模組中可以有多個函數,但單個模板則只能有一個。

另外,模組不可以直接運行,而是有指定要運行的單個函數。模組是一組函數綜合起來的裝載體,自身並沒有功能。只有指定要運行哪一個函數,該模組才會知道要運行哪一個函數。

最簡單的模組運行方法如下:

{{#invoke:模块名稱|函數名稱}}

例如,Module:Example就可以如此運行,其含有一個叫做「hello」的函數。

運用參數

參數進入模組指令碼的方式與進入模板一樣。不過,在調用模組時第一個豎線之後必須要先指定函數名,第二個豎線之後才是正式參數。

{{#invoke:模組名稱|函數名稱|第一參數|第二參數|帶名稱的參數 = 值}}

例如Module:BaseConvert可以轉換數值的進位制:

執行模組時的參數會自動以table(表)類型的形式寫入對應模組的frame.args中,其中frame為函數的第一個參數。例如{{#invoke:BaseConvert|convert|n=30|base=16}}就會自動給執行時的模組臨時寫入frame.args的值類似於{["n"]="30";["base"]="16"},例如frame.args.n就會輸出為30(字串形式)。(注意:參數名稱如果是數字,其frame.args中的參數名稱也是數字,但參數值一定是一個字串。這個args其實是使用了元表的。它的真正值為getmetatable({},{__index=函數名,__pairs=函數名,__ipairs=函數名}),因此如果需要製作一個純粹的表以使用table.insert等函數,可以利用pairs進行迭代。)

此外,如果是引用呼叫了模組的頁面,其引用時的值會寫入模組的frame:getParent().args中,例如(假設):

  1. 模組:Example的內容為:
    local p={}
    function p.x(frame) return frame:getParent().args["a"] end
    return p
    
  2. Template:Example中的內容為:
    {{#invoke:Example|x}}
  3. 那麼直接呼叫{{#invoke:Example|x|a=Hello world}}是得不到任何內容的。
  4. 但是使用{{Example|a=Hello world}}就可以得到Hello world的字串。

Scribunto對參數的處理有些限制,可參考模組:Arguments以了解如何使用該模組對參數進行進一步處理。

關於Lua

Lua是一種利用多重編程範式的手稿語言,可用於分析資料,計算公式及添加格式等。雖然Lua指令碼可以非常簡單,但其功能強大,能夠支援各種複雜結構,如表格、動態函數等。Lua同時也支持含有自我巢狀函數的遞歸過程。因此在設計Lua程式時,須注意不要加入過度複雜的組件,以免他人無法有效閱讀指令碼。以下指令碼(如在Module:HelloWorld)可以輸出Hello World!訊息:

-- 維基百科上的Lua模組必須在開頭定義一個變數,使參數可從外面存取。
-- 變數的名稱可以含有資料。
local my_object = {};

-- 在該變數上運行函數。在維基百科中可以用#invoke指令調用這些函數。
-- 函數被調用時,維基百科會向函數發送資料。這一資料應包含在frame以內。
my_object.hello = function( frame ) 

    -- 定義局部變數。
    local str = "Hello World!"  

    -- 終止函數,並把str中的資料輸出到維基百科。
    -- 不可使用print函數,所以所有輸出要用return
    return str    

-- 函數結束。
end

-- 模組底部須用return把帶有函數的變數送回維基百科。
return my_object

-- 現在{{#invoke: HelloWorld | hello }}就可以調用以上函數了
-- #invoke指令先指定模組名稱,HelloWorld,再指定某一函數,hello

(注意:以上只是對模組用法的一個範例,如果要輸入Hello World的字串,最簡單的用法如下:)

local p = {}
function p.hello()
     return "Hello World!"
end
return p

Lua指令碼在內文中可以加在<syntaxhighlight lang="lua"></syntaxhighlight>裏面來加上顏色標註。詳見Lua條目。

在MediaWiki中使用Lua的教程,可見mw:Extension:Scribunto/Lua reference manual

單元測試

Module:UnitTests提供Lua指令碼的單元測試。它可用一組指定輸入值來運行特定指令碼,並確認輸出值符合預期。單元測試可以很快地找到改變指令碼後所產生的新問題。

模組(如Module:Example)的單元測試應該放在其附頁Module:Example/testcases裏面,並在Module talk:Example/testcases上用{{#invoke:Example/testcases|run_tests}}運行。測試方法必須以「test」開頭。以下是Module:Example/testcases的例子。

-- [[Module:Example]]的單元測試。進入討論頁可運行測試。
local p = require('Module:UnitTests')
 
function p:test_hello()
    self:preprocess_equals('{{#invoke:Example| hello}}', 'Hello, world!')
end
 
return p

Special:Whatlinkshere/Module:UnitTests頁面列出所有進行單元測試的模組。

MediaWiki特有功能

{{#invoke:}}當中的輸入值在進入Lua指令碼時一定是字串格式。Lua只能輸出非包含及不含{{...}}的維基代碼。所有Lua指令碼的CPU運行時間都限制在10秒。相比一般的Lua,Scribunto的Lua版本少了多個函數(見:mw:Special:MyLanguage/Extension:Scribunto/Lua reference manual#Differences from standard Lua)。Scribunto也提供大量用於和MediaWiki對接的函數(mw:Special:MyLanguage/Extension:Scribunto/Lua reference manual#Scribunto libraries)。

Lua輸入值限制

Lua指令碼只在頁面解析時才會運行。所以要對Lua輸入參數,必須通過「編輯此頁」,而不可在頁面中加入一個輸入框,作實時處理,也不可動態點擊挑選函數功能。Lua可以接受的輸入值包括任何「可包含」的文字頁面。這並不包括圖像檔案(甚至.SVG檔案都不可)和分類中的頁面列表等。

維基代碼

經「包含」的標題經常會有諸如「UNIQ5ae8f2aa414ff233-h-3--QINU」的隱藏文字(稱為strip mark)。這些文字要去除之後才會有效解析。部分擴充標籤也會轉化為strip mark。

類似[[Wikipedia:Help|]]的維基連結在經Lua輸出後是沒有用的,必須完整地寫成[[Wikipedia:Help|Help]]。其他儲存前自動進行的轉換,如~~~~替換為簽名,都會在Lua輸出時無法進行(但在Lua函數被特定條件下還是會執行)。

在Lua代碼中隱藏文字(即進行註釋,例如HTML中的<!--...-->)的方法是在要註釋的文字前輸入--(不能在字串內)。也可使用 --[[開始大段註釋,用]]結束。

Lua不能進行魔術字模板解析器函數的替換,否則會直接保留管道符和花括號(在Special:展開模板頁面除外)。使用模板應該使用frame:expandTemplate{title = "模板名稱(不含命名空間)", args = {"參數1", "參數2"}},其中frame為函數中傳入的框架對象,亦可通過mw.getCurrentFrame()獲得。解析器函數和魔術字在Lua都有內建的函數,例如{{FULLPAGENAME}}應該用tostring(mw.title.getCurrentTitle())或者mw.title.getCurrentTitle().fullText,具體用法參見mw:Special:MyLanguage/Extension:Scribunto/Lua_reference_manual

<ref><nowiki>等標籤也不會在Lua程式當中處理。若要處理<nowiki>,則應該使用mw.text.nowiki("原文字")

使用Lua的模板

基於Lua語言編寫的模板的文件頁面應當加上{{lua|模組名稱}}

之後這些模板會歸入Category:Lua模板及其子分類中,你可以在這個分類中找到這些模板。請勿將模組歸入此分類。

資源

文件

指南

Lua相關文章

模組連結列表

  1. ^ 也可以有多個輸出值,但這類函數一般不用於#invoke中。