维基百科:Lua

命名空间
基本命名空间讨论命名空间
0主/條目帮助讨论1
2用戶帮助用户讨论3
4维基百科维基百科讨论5
6文件帮助文件讨论7
8MediaWikiMediaWiki讨论9
10模板帮助模板讨论11
12帮助帮助讨论13
14分类帮助分类讨论15
100主题主题讨论101
102維基專題帮助維基專題討論103
118草稿草稿讨论119
710字幕字幕討論711
828模块模块讨论829
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"] endreturn 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!"endreturn 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相关文章

模块链接列表