Mô đun:Arguments/tài liệu
Đây là trang dành cho tài liệu về Mô đun:Arguments.
Mô đun Lua này được sử dụng ở khoảng 1.860.000 trang, chiếm ≈ 187955% tổng số trang. Để tránh gây lỗi trên quy mô lớn và tải máy chủ không cần thiết, tất cả thay đổi cần được thử nghiệm ở trang con /sandbox, /testcases của mô đun, hoặc ở chỗ thử mô đun. Các thay đổi đã được thử nghiệm có thể thêm vào mô đun bằng một sửa đổi duy nhất. Xin hãy thảo luận các thay đổi tại trang thảo luận trước khi áp dụng sửa đổi. |
Mô đun Lua này được sử dụng trong thông báo hệ thống, và ở khoảng 1.860.000 trang, chiếm ≈ 187955% tổng số trang. Thay đổi đến nó có thể dẫn đến thay đổi ngay lập tức giao diện người dùng Wikipedia. Để tránh gây lỗi trên quy mô lớn và tải máy chủ không cần thiết, tất cả thay đổi cần được thử nghiệm ở trang con /sandbox, /testcases của mô đun, hoặc ở chỗ thử mô đun. Các thay đổi đã được thử nghiệm có thể thêm vào mô đun bằng một sửa đổi duy nhất. Xin hãy thảo luận các thay đổi tại trang thảo luận trước khi áp dụng sửa đổi. |
Mô-đun này là loại cần được khóa. Nó là một mô-đun nhìn thấy rõ được sử dụng bởi một số lượng lớn các trang, hoặc là các thay thế rất thường xuyên. Bởi vì phá hoại hoặc lỗi sai khi sửa sẽ ảnh hưởng đến nhiều trang và thậm chí chỉnh sửa tầm thường có thể gây ra tải đáng kể cho các máy chủ, nó được khóa bảo vệ hạn chế sửa đổi. |
Mô-đun này cung cấp xử lý dễ dàng các đối số được truyền từ #invoke. Đây là một mô-đun meta, được sử dụng cho các mô-đun khác và không được gọi trực tiếp từ #invoke. Các tính năng của nó bao gồm:
- Dễ dàng cắt xén các đối số và loại bỏ các đối số trống.
- Đối số có thể được truyền bởi cả khung hiện tại và khung cha cùng một lúc. (Thêm chi tiết bên dưới.)
- Các đối số có thể được truyền trực tiếp từ một mô-đun Lua khác hoặc từ bảng điều khiển gỡ lỗi.
- Đối số được tìm nạp khi cần, điều này có thể giúp tránh (một số) sự cố với thẻ
<ref>...</ref>
. - Hầu hết các tính năng có thể được tùy chỉnh.
Sử dụng cơ bản
Đầu tiên, bạn cần tải mô-đun. Nó chứa một hàm, được đặt tên getArgs
.
<syntaxhighlight lang="lua"> local getArgs = require('Module:Arguments').getArgs </syntaxhighlight>
Trong kịch bản cơ bản nhất, bạn có thể sử dụng getArgs bên trong chức năng chính của mình. Biến args
là bảng chứa các đối số từ #invoke. (Xem bên dưới để biết chi tiết.)
<syntaxhighlight lang="lua"> local getArgs = require('Module:Arguments').getArgs local p = {}
function p.main(frame) local args = getArgs(frame) -- Main module code goes here. end
return p </syntaxhighlight>
Tuy nhiên, thực tế nên đề xuất là sử dụng một hàm chỉ để xử lý các đối số từ #invoke. Điều này có nghĩa là nếu ai đó gọi mô-đun của bạn từ một mô-đun Lua khác, bạn không phải có sẵn một đối tượng khung, điều này giúp cải thiện hiệu suất.
<syntaxhighlight lang="lua"> local getArgs = require('Module:Arguments').getArgs local p = {}
function p.main(frame) local args = getArgs(frame) return p._main(args) end
function p._main(args) -- Main module code goes here. end
return p </syntaxhighlight>
Nếu bạn muốn nhiều hàm sử dụng các đối số và bạn cũng muốn chúng có thể truy cập được từ #invoke, bạn có thể sử dụng hàm bao bọc.
<syntaxhighlight lang="lua"> local getArgs = require('Module:Arguments').getArgs
local p = {}
local function makeInvokeFunc(funcName) return function (frame) local args = getArgs(frame) return p[funcName](args) end end
p.func1 = makeInvokeFunc('_func1')
function p._func1(args) -- Code for the first function goes here. end
p.func2 = makeInvokeFunc('_func2')
function p._func2(args) -- Code for the second function goes here. end
return p </syntaxhighlight>
Tùy chỉnh
Một só Lựa chọn tùy chỉnh có sẵn khi sử dụng. Chúng được giải thích trong các phần dưới đây.
<syntaxhighlight lang="lua"> local args = getArgs(frame, { trim = false, removeBlanks = false, valueFunc = function (key, value) -- Code for processing one argument end, frameOnly = true, parentOnly = true, parentFirst = true, wrappers = { 'Template:A wrapper template', 'Template:Another wrapper template' }, readOnly = true, noOverwrite = true }) </syntaxhighlight>
Cắt và loại bỏ khoảng trống
Các đối số trống thường gây khó đối với các lập trình viên mới muốn chuyển đổi các bản mẫu MediaWiki sang Lua. Trong cú pháp bản mẫu, chuỗi trống và chuỗi chỉ bao gồm khoảng trắng được coi là sai. Tuy nhiên, trong Lua, chuỗi trống và chuỗi bao gồm khoảng trắng được coi là đúng. Điều này có nghĩa là nếu bạn không chú ý đến những lập luận như vậy khi bạn viết các mô-đun Lua của mình, bạn có thể coi điều gì đó là đúng mà thực sự nên được coi là sai. Để tránh điều này, theo mặc định, mô-đun này sẽ xóa tất cả các đối số trống.
Tương tự, khoảng trắng có thể gây ra vấn đề khi xử lý các đối số vị trí. Mặc dù khoảng trắng được cắt bớt cho các đối số được đặt tên đến từ #invoke, nhưng nó được giữ nguyên cho các đối số vị trí. Hầu hết thời gian khoảng trắng bổ sung này là không mong muốn, vì vậy mô-đun này cắt nó theo mặc định.
Tuy nhiên, đôi khi bạn muốn sử dụng các đối số trống làm đầu vào và đôi khi bạn muốn giữ khoảng trắng bổ sung. Điều này có thể cần thiết để chuyển đổi một số mẫu chính xác như chúng đã được viết. Nếu bạn muốn làm điều này, bạn có thể đặt trim
và removeBlanks
với tham số là false
.
<syntaxhighlight lang="lua"> local args = getArgs(frame, { trim = false, removeBlanks = false }) </syntaxhighlight>
Định dạng tùy chỉnh của các đối số
Đôi khi bạn muốn xóa một số đối số trống nhưng không phải là đối số khác hoặc có lẽ bạn muốn đặt tất cả các đối số vị trí ở dạng chữ thường. Để làm những việc như thế này bạn có thể sử dụng tùy chọn valueFunc
. Đầu vào của tùy chọn này phải là một hàm có hai tham số, key
và value
, và trả về một giá trị duy nhất. Giá trị này là những gì bạn sẽ nhận được khi truy cập vào trường key
trong bảng args
.
Ví dụ 1: hàm này bảo toàn khoảng trắng cho đối số vị trí đầu tiên, nhưng cắt bỏ tất cả các đối số khác và loại bỏ tất cả các đối số trống khác. <syntaxhighlight lang="lua"> local args = getArgs(frame, { valueFunc = function (key, value) if key == 1 then return value elseif value then value = mw.text.trim(value) if value ~= then return value end end return nil end }) </syntaxhighlight>
Ví dụ 2: hàm này loại bỏ các đối số trống và chuyển đổi tất cả các đối số thành chữ thường, nhưng không cắt khoảng trắng khỏi các tham số vị trí. <syntaxhighlight lang="lua"> local args = getArgs(frame, { valueFunc = function (key, value) if not value then return nil end value = mw.ustring.lower(value) if mw.ustring.find(value, '%S') then return value end return nil end }) </syntaxhighlight>
Lưu ý: các chức năng trên sẽ thất bại nếu đầu vào không thuộc loại string
hoặc nil
. Đây có thể là trường hợp nếu bạn sử dụng chức năng getArgs
trong chức năng chính của mô-đun của bạn và chức năng đó được gọi bởi một mô-đun Lua khác. Trong trường hợp này, bạn sẽ cần kiểm tra loại đầu vào của bạn. Đây không phải là vấn đề nếu bạn đang sử dụng một hàm đặc biệt cho các đối số từ #invoke (tức là bạn có chức năng p.main
và p._main
, hoặc một cái gì đó tương tự).
Ví dụ 1 và 2 với kiểm tra loại
|
---|
Ví dụ 1: <syntaxhighlight lang="lua"> local args = getArgs(frame, { valueFunc = function (key, value) if key == 1 then return value elseif type(value) == 'string' then value = mw.text.trim(value) if value ~= then return value else return nil end else return value end end }) </syntaxhighlight> Ví dụ 2: <syntaxhighlight lang="lua"> local args = getArgs(frame, { valueFunc = function (key, value) if type(value) == 'string' then value = mw.ustring.lower(value) if mw.ustring.find(value, '%S') then return value else return nil end else return value end end }) </syntaxhighlight> |
Ngoài ra, xin lưu ý rằng hàm valueFunc
được gọi nhiều hơn hoặc ít hơn mỗi khi một đối số được yêu cầu từ bảng args
, vì vậy nếu bạn quan tâm đến hiệu suất mà bạn nên chắc chắn rằng bạn không làm bất cứ điều gì không hiệu quả với mã của bạn.
Khung và khung cha
Đối số trong bảng args
có thể được truyền từ khung hiện tại hoặc từ khung chính của nó cùng một lúc. Để hiểu điều này có nghĩa là gì, dễ nhất là đưa ra một ví dụ. Hãy nói rằng chúng ta có một mô-đun gọi là Module:ExampleArgs
. Mô-đun này in hai đối số vị trí đầu tiên mà nó được thông qua.
Mã nguồn của Mô đun:ExampleArgs
|
---|
<syntaxhighlight lang="lua"> local getArgs = require('Module:Arguments').getArgs local p = {} function p.main(frame) local args = getArgs(frame) return p._main(args) end function p._main(args) local first = args[1] or local second = args[2] or return first .. ' ' .. second end return p </syntaxhighlight> |
Module:ExampleArgs
sau đó được gọi bởi Bản mẫu:ExampleArgs
, có chứa đoạn mã {{#invoke:ExampleArgs|main|firstInvokeArg}}
. Điều này tạo ra kết quả "firstInvokeArg".
Bây giờ nếu chúng ta gọi Bản mẫu:ExampleArgs
, điều sau đây sẽ xảy ra:
Mã | Kết quả |
---|---|
{{ExampleArgs}}
|
firstInvokeArg |
{{ExampleArgs|firstTemplateArg}}
|
firstInvokeArg |
{{ExampleArgs|firstTemplateArg|secondTemplateArg}}
|
firstInvokeArg secondTemplateArg |
Có ba tùy chọn bạn có thể đặt để thay đổi hành vi này:
frameOnly
, parentOnly
và parentFirst
. Nếu bạn đặt frameOnly
sau đó chỉ các đối số được truyền từ khung hiện tại sẽ được chấp nhận; nếu bạn đặt parentOnly
sau đó chỉ các đối số được truyền từ khung cha sẽ được chấp nhận; và nếu bạn đặt parentFirst
sau đó các đối số sẽ được truyền từ cả khung hiện tại và khung chính, nhưng khung chính sẽ có mức độ ưu tiên so với khung hiện tại. Dưới đây là kết quả với Bản mẫu:ExampleArgs
:
- frameOnly
Mã | Kết quả |
---|---|
{{ExampleArgs}}
|
firstInvokeArg |
{{ExampleArgs|firstTemplateArg}}
|
firstInvokeArg |
{{ExampleArgs|firstTemplateArg|secondTemplateArg}}
|
firstInvokeArg |
- parentOnly
Mã | Kết quả |
---|---|
{{ExampleArgs}}
|
|
{{ExampleArgs|firstTemplateArg}}
|
firstTemplateArg |
{{ExampleArgs|firstTemplateArg|secondTemplateArg}}
|
firstTemplateArg secondTemplateArg |
- parentFirst
Mã | Kết quả |
---|---|
{{ExampleArgs}}
|
firstInvokeArg |
{{ExampleArgs|firstTemplateArg}}
|
firstTemplateArg |
{{ExampleArgs|firstTemplateArg|secondTemplateArg}}
|
firstTemplateArg secondTemplateArg |
Chú ý:
- Nếu bạn đặt cả hai tùy chọn
frameOnly
vàparentOnly
, mô-đun sẽ không tìm nạp bất kỳ đối số nào từ #invoke. Đây có lẽ không phải là những gì bạn muốn. - Trong một số trường hợp, khung cha có thể không khả dụng, ví dụ: nếu getArgs thông qua khung cha chứ không phải khung hiện tại. Trong trường hợp này, chỉ các đối số khung sẽ được sử dụng (trừ khi parentOnly được đặt, trong trường hợp đó sẽ không có đối số nào được sử dụng) và tùy chọn
parentFirst
vàframeOnly
sẽ không có tác dụng.
Wrappers
Tùy chon wrappers được sử dụng để chỉ định một số lượng bản mẫu giới hạn như Bản mẫu wrapper, đó là, các bản mẫu có mục đích duy nhất là gọi một mô-đun. Nếu mô-đun phát hiện ra rằng nó đang được gọi từ một bản mẫu wrappers, nó sẽ chỉ kiểm tra các đối số trong khung cha; nếu không, nó sẽ chỉ kiểm tra các đối số trong khung được truyền cho getArgs. Điều này cho phép các mô-đun được gọi bằng #invoke hoặc thông qua mẫu wrappers mà không làm giảm hiệu suất liên quan đến việc phải kiểm tra cả khung và khung chính cho mỗi lần tra cứu đối số.
Ví dụ: nội dung duy nhất của Template:Side box (trừ nội dung trong cặp <noinclude>...</noinclude>
) là {{#invoke:Side box|main}}
. Không có điểm nào trong việc kiểm tra các đối số được truyền trực tiếp vào câu lệnh #invoke cho bản mẫu này, vì sẽ không có đối số nào được chỉ định ở đó. Chúng ta có thể tránh việc kiểm tra các đối số được truyền cho #invoke bằng cách sử dụng tùy chọn parentOnly, nhưng nếu chúng ta làm điều này thì #invoke cũng sẽ không hoạt động từ các trang khác. Nếu đây là trường hợp, |text=Some text
trong mã {{#invoke:Side box|main|text=Some text}}
sẽ bị bỏ qua hoàn toàn, bất kể nó được sử dụng từ trang nào. Bằng cách sử dụng tùy chọn wrappers
để cụ thể hóa 'Bản mẫu:Side box' là một wrapper, ta có thể tạo {{#invoke:Side box|main|text=Some text}}
hoạt động từ hầu hết các trang, trong khi vẫn không yêu cầu mô-đun kiểm tra các đối số trên chính trang Bản mẫu:Side box.
Wrappers có thể được chỉ định là một chuỗi hoặc là một chuỗi các chuỗi.
<syntaxhighlight lang="lua"> local args = getArgs(frame, { wrappers = 'Template:Wrapper template' }) </syntaxhighlight>
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
wrappers = {
'Template:Wrapper 1',
'Template:Wrapper 2',
-- Bất kì số nào của bản mẫu wrapper cũng có thể thêm vào đây.
}
})
</syntaxhighlight>
Chú ý:
- Mô-đun sẽ tự động phát hiện nếu nó được gọi từ trang con /sandbox của bản mẫu wrapper, do đó không cần chỉ định rõ ràng các trang sandbox.
- Tùy chọn wrappers thay đổi hiệu quả mặc định của tùy chọn frameOnly và parentOnly. Nếu, ví dụ, parentOnly rõ ràng được đặt thành false với set wrappers, các cuộc gọi thông qua các bàn mẫu Wrapper sẽ dẫn đến cả hai đối số khung và đối số được tải, mặc dù các cuộc gọi không qua các mẫu trình bao bọc sẽ chỉ dẫn đến các đối số khung được tải.
- Nếu tùy chọn wrappers được đặt và không có khung cha nào khả dụng, mô-đun sẽ luôn nhận được các đối số từ khung được truyền cho
getArgs
.
Viết vào bảng args
Đôi khi nó có thể hữu ích để viết các giá trị mới vào bảng args. Điều này là có thể với các thiết lập mặc định của mô-đun này. (Tuy nhiên, hãy nhớ rằng thường là phong cách mã hóa tốt hơn để tạo một bảng mới với các giá trị mới của bạn và sao chép các đối số từ bảng args khi cần.)
<syntaxhighlight lang="lua"> args.foo = 'some value' </syntaxhighlight>
Có thể thay đổi hành vi này với tùy chọn readOnly
và noOverwrite
. Nếu readOnly
được đặt thì không thể ghi bất kỳ giá trị nào vào bảng args. Nếu noOverwrite
được đặt, sau đó có thể thêm các giá trị mới vào bảng, nhưng không thể thêm giá trị nếu nó ghi đè lên bất kỳ đối số nào được truyền từ #invoke.
Cập tags Ref
Mô đun này sử dụng metatables để tìm nạp các đối số từ #invoke. Điều này cho phép truy cập vào cả đối số khung và đối số khung cha mà không cần sử dụng hàm chức năng pairs()
. Điều này có thể giúp có ích nếu mô-đun của bạn có thể được thông qua tags <ref>...</ref>
làm đầu vào.
Ngay khi Tags <ref>...</ref>
được truy cập từ Lua, chúng được xử lý bởi phần mềm MediaWiki và tài liệu tham khảo sẽ xuất hiện trong danh sách tham khảo ở cuối bài viết. Nếu mô-đun của bạn tiến hành bỏ qua thẻ tham chiếu từ đầu ra, bạn sẽ kết thúc bằng một tham chiếu ảo - một tham chiếu xuất hiện trong danh sách tham chiếu, nhưng không có số nào liên kết với nó. Đây là một vấn đề với các mô-đun sử dụng pairs()
để phát hiện xem nên sử dụng các đối số từ khung hoặc khung cha, vì các mô-đun đó tự động xử lý mọi đối số có sẵn.
Mô-đun này giải quyết vấn đề này bằng cách cho phép truy cập vào cả đối số khung và khung cha, trong khi vẫn chỉ tìm nạp các đối số đó khi cần thiết. Vấn đề vẫn sẽ xảy ra nếu bạn sử dụng pairs(args)
ở nơi khác trong mô-đun của bạn, tuy nhiên.
Những hạn chế đã biết
Việc sử dụng các metatables cũng có nhược điểm của nó. Hầu hết các công cụ bảng Lua bình thường sẽ không hoạt động chính xác trên bảng args, bao gồm cả mã hoạt động #
, hàm chức năng next()
, và các chức năng trong thư viện bảng. Nếu việc sử dụng này là quan trọng cho mô-đun của bạn, bạn nên sử dụng chức năng xử lý đối số của riêng bạn thay vì mô-đun này.