維基百科: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中。