維基百科: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可以轉換數值的進位制:
{{#invoke:BaseConvert|convert|n=9|base=2}}
→ 1001{{#invoke:BaseConvert|convert|n=30|base=16}}
→ 1E
執行模組時的參數會自動以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
中,例如(假設):
- 模組:Example的內容為:
local p={} function p.x(frame) return frame:getParent().args["a"] end return p
- Template:Example中的內容為:
{{#invoke:Example|x}}
- 那麼直接呼叫
{{#invoke:Example|x|a=Hello world}}
是得不到任何內容的。 - 但是使用
{{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|模組名稱}}
:
此模板使用Lua語言: |
之後這些模板會歸入Category:Lua模板及其子分類中,你可以在這個分類中找到這些模板。請勿將模組歸入此分類。
資源
文件
- Scribunto Lua 參考手冊
- Lua編程
- Lua樣式介紹
- About regex 基於Regex的Lua樣式
指南
- 維基百科:Lua代碼風格 – 通過連貫性改進可讀性的標準
- "What do converted templates look like?" (slideshow)
- en:Help:Lua debugging – 除錯Lua模組的指南
- en:Help:Lua for beginners
- en:Wikipedia:Lua string functions
- en:Wikipedia:Guide to Scribbling – 怎樣用Scribunto/Lua編寫模板
- en:Wikiversity:Lua – Lua指引
Lua相關文章
- en:Wikipedia:Lua speed – 比較模板和模組速度
- en:Wikipedia:Lua articles
- en:User:Dragons flight/Lua performance
- en:Wikipedia:Lua unit testing
- mw:User:Sumanah/Lua vs Javascript
- Roberto Ierusalimschy. Lua Performance Tips (PDF). lua.org.
模組連結列表
- ^ 也可以有多個輸出值,但這類函數一般不用於#invoke中。