本页使用了标题或全文手工转换

维基百科:Lua

维基百科,自由的百科全书
跳到导航 跳到搜索
维基百科名字空间
基本名字空间 讨论名字空间
0 主/條目 帮助 讨论 1
2 用戶 帮助 用户讨论 3
4 计划 计划讨论 5
6 文件 帮助 文件讨论 7
8 MediaWiki MediaWiki讨论 9
10 模板 帮助 模板讨论 11
12 帮助 帮助讨论 13
14 分类 帮助 分类讨论 15
100 主题 帮助 主题讨论 101
118 草稿 草稿讨论 119
828 模块 模块讨论 829
2300 Gadget
2302 Gadget definition
2600 话题 帮助
虚拟名字空间
-1 特殊
-2 媒体

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

用法[编辑]

运行模块[编辑]

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

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

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

{{#invoke:''模塊名稱''|''函數名稱''}}

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

  • {{#invoke:Example|hello}} → Hello, world!

運用參數[编辑]

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

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

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

  • {{#invoke:BaseConvert|convert|n=9|base=2}} → 1001
  • {{#invoke:BaseConvert|convert|n=30|base=16}} → 1E

运行模块时的参数会自动以table(表)类型的形式写入对应模块的mw.getCurrentFrame().args中。例如{{#invoke:BaseConvert|convert|n=30|base=16}}就会自动给运行时的模块临时写入mw.getCurrentFrame().args的值类似于{["n"]="30";["base"]="16",例如mw.getCurrentFrame().args.n就会输出为30(字符串形式)。(注意:参数名称如果是数字,其mw.getCurrentCrame().args中的参数名称也是数字,但参数值一定是一个字符串。这个args其实是使用了元表的。它的真正值为getmetatable({},{__index=某函数,__pairs=某函数,__ipairs=某函数}),因此如果需要制作一个纯粹的表以使用table.insert等函数,可以利用pairs进行迭代。)

此外,如果是引用调用了模块的页面,其引用时的值会写入模块的mw.getCurrentFrame():getParent().args中,例如(假设):

  1. 模块:Example的内容为:
    local p={}
    function p.x() return mw.getCurrentFrame():getParent().args["a"] end
    return p
    
  2. Template:Example中的内容为:
    {{#invoke:lua|x}}
  3. 那么直接调用{{#invoke:lua|x|a=Hello world}}是得不到任何内容的。
  4. 但是使用{{example|a=Hello world}}就可以得到Hello world的字符串。

關於Lua[编辑]

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

-- 維基百科上的Lua模塊必須在開頭定義一個變量,使參數可從外面存取。
-- 變量的名稱可以含有數據。
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腳本在內文中可以加在"<source lang="lua">...</source>"裡面來加上顏色標註。詳見Lua條目。

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

單元測試[编辑]

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

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

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

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

維基百科特有功能[编辑]

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

Lua輸入值限制[编辑]

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

維基代碼[编辑]

經「包含」的標題經常會有諸如「UNIQ5ae8f2aa414ff233-h-3--QINU」的隱藏文字。這些文字要去除之後才會有效解析。

類似[[Wikipedia:Help|]]的維基鏈接在經Lua輸出後是沒有用的,必須完整地寫成[[Wikipedia:Help|Help]]。其他保存前自動進行的轉換,如~~~~替換為簽名,都會在Lua輸出時無法進行。

在Lua代码中隐藏文本(即进行注释,例如HTML中的<!--...-->)的方法是在要注释的文本前输入--(不能在字符串内)。也可使用 --[[开始大段注释,用]]结束。

Lua不能进行魔术字模板解析器函数的替换,否则会直接保留管道符和花括号(在Special:展开模板页面除外)。使用模板应该使用mw.getCurrentFrame():expand{title = "模板名稱(不含命名空間)", args = {"參數1", "參數2"}}。解析器函数和魔术字在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|模組名稱}}

之后这些模板会归入Category:基于Lua编程语言的模板及其子分类中,你可以在这个分类中找到这些模板。

腳註[编辑]

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

资源[编辑]

文档[编辑]

指南[编辑]

Lua相关文章[编辑]

模块链接列表[编辑]