首页
最近更改
MediaWiki帮助
中文社区
模组
人物
团体
群聊
历史
外网社区
模组
发帖交流
论坛
聊天
博客
快捷访问
分类
文件列表
上传文件
用户列表
用户通知
礼物列表
随机页面
聊天中的在线用户
模块
讨论
查看源代码
查看历史
刷新
创建账号
登录
查看“︁模块:Arguments/doc”︁的源代码
来自Age Of History 2 Chinese Wiki
←
Arguments/doc
跳转至:
导航
、
搜索
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
该模块来自于英语维基百科的[[enwp:Module:Arguments|同名模块]],英文原文详见历史版本[https://zh.moegirl.org.cn/index.php?title=%E6%A8%A1%E5%9D%97:Arguments/doc&oldid=3709348]。 这个模块提供了从#invoke传递的参数的简单处理。它是一个元模块,用于其他模块,不应该直接从#Invoke调用。它的特点包括: *简单地修剪参数和删除空白参数。 *参数可以同时由当前框架和父框架传递。 *参数可以直接从另一个Lua模块或调试控制台传入。 *参数是根据需要获取的,这有助于避免<nowiki><ref>...</ref></nowiki>标签带来的(一些)问题。 *大多数功能都可以定制。 == 基础使用 == 首先,你需要加载(load)本模块(module),它包含一个叫 <code>getArgs</code> 的函数。 <pre lang=lua> local getArgs = require('Module:Arguments').getArgs </pre> 最基本的情况下,您可以在主函数使用getArgs函数。变量args的类型是一个表(table),其中包含从#invoke传过来的参数(argument)。 <pre lang=lua> local getArgs = require('Module:Arguments').getArgs local p = {} function p.main(frame) local args = getArgs(frame) -- 主函数的代码会在这里运行。 end return p </pre> 然而,我们更推荐使用一个函数单独用来处理来自于#invoke的参数。这意味着,如果别人用另一个Lua模块调用你的模块,你不必再次通过frame(框架)对象获取args变量。这会提高性能。 <pre 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) -- 主函数的代码。 end return p </pre> 如果你想要从#invoke中访问多个函数,同时这些函数也可以使用#invoke的参数,你可以使用包装函数(wrapper function),就像下面的例子一样。 <pre lang=lua> local getArgs = require('Module:Arguments').getArgs local function makeInvokeFunc(funcName) return function (frame) local args = getArgs(frame) return p[funcName](args) end end local p = {} p.func1 = makeInvokeFunc('_func1') function p._func1(args) -- 第一个函数的代码。 end p.func2 = makeInvokeFunc('_func2') function p._func2(args) -- 第二个函数的代码。 end return p </pre> === 参数选项 === 以下参数选项(option)是可用的,下文会对其进行解释。 <pre 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 }) </pre> === 空白参数和空格的处理 === 空白参数(blank argument)经常会让MediaWiki的编辑者产生困惑。因为在模板的语法,空白字符串和仅包括空格的字符串会被当做false处理。但是在Lua,空白字符串和仅包括空格的字符串会被处理为true。如果你在写Lua模块的时候没有对参数产生足够重视,你可能会把本应是false的变量当做true。为了避免这种情况,空白变量会被默认去除。 在处理位置参数的时候,空格可能会导致棘手的问题。对于已命名的参数,空格会被修剪(trim)掉。对于位置参数,虽然空格通常会保留,但是大多数时候空格是不需要的,所以模块也会默认修剪掉这些空格。 然而,你有时候可能需要空白参数作为输入内容,有时候也想要保留多出来的空格,比如想将模板的内容按照所写的那样精确转化时。这时,你可以把<code>trim</code>变量和<code>removeBlanks</code>(清除空白参数)变量设置为<code>false</code>。 <pre lang=lua> local args = getArgs(frame, { trim = false, removeBlanks = false }) </pre> === 自定义参数格式 === 有时你可能需要去除特定的某些空白参数,或者你想要把所有的位置参数都变成小写字母。你可以使用<code>valueFunc</code>参数选项。这个参数选项必须是一个函数,且需要两个形参(parameters),分别是<code>key</code>和<code>value</code>,并且只返回一个值。这个返回值,就是<code>args</code>表(table)在指定键<code>key</code>下获取到的元素。 示例1:这个函数保留第一个参数的空格,但会修剪其它参数的空格,以及清除所有空白的参数。 <pre 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 }) </pre> 示例2:这个函数会清除所有的空白参数,并且把所有的参数都变成小写字母,但是不会修剪位置参数的空格。 <pre 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 }) </pre> 注意:如果传过来的输入既不是<code>string</code>类型,也不是<code>nil</code>,这个函数会失效。如果你的模块在main函数调用了<code>getArgs</code>函数,并且这个函数被其他Lua类调用的时候,很可能会出现这种情况。这时候,你应该检查输入的类型。但是,如果你有一个函数用来特别处理来自于#invoke的参数,不会出现这种问题(例如你使用了<code>p.main</code>和<code>p._main</code>函数,或者之类的)。 {{Hide|标题=增加类型检查示例1/示例2|内容= 示例1: <pre 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 }) </pre> 示例2: <pre 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 }) </pre> }} 需要注意的是,每次从<code>args</code>表获取参数的时候,<code>valueFunc</code>都会大约被调用一次。为了确保性能,你需要保证你的代码的高效性。 === 框架和父框架 === <code>args</code>中的参数既可以从当前框架传递,也可以从其父框架传递。我们来通过示例来理解上面这段话。我们有一个叫做<code>Module:ExampleArgs</code>的模块,它可以输出传入的前两个位置参数中。 {{Hide|标题=Module:ExampleArgs|内容= <pre 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 </pre> }} 然后,模块<code>Module:ExampleArgs</code>被模板<code>Template:ExampleArgs</code>调用。这个模板包括以下代码<code><nowiki>{{#invoke:ExampleArgs|main|firstInvokeArg}}</nowiki></code>。 接下来,如果我们通过以下方式调用模板<code>Template:ExampleArgs</code>,会出现以下情况。 {| class="wikitable" style="width: 50em; max-width: 100%;" |- ! style="width: 60%;" | 代码 ! style="width: 40%;" | 结果 |- | <code><nowiki>{{ExampleArgs}}</nowiki></code> | firstInvokeArg |- | <code><nowiki>{{ExampleArgs|firstTemplateArg}}</nowiki></code> | firstInvokeArg |- | <code><nowiki>{{ExampleArgs|firstTemplateArg|secondTemplateArg}}</nowiki></code> | firstInvokeArg secondTemplateArg |} 以下三种参数选项可以改变参数传递情况:<code>frameOnly</code>,<code>parentOnly</code>,和<code>parentFirst</code>。如果你设置<code>frameOnly</code>参数选项,那么只有从当前框架传递来的参数会被接受。如果你设置<code>parentOnly</code>参数选项,那么只有从父框架传递来的参数会被接受。如果你设置<code>parentFirst</code>参数选项,当前框架和父框架传递来的参数都会被接受,但是父框架的参数会被优先接受。下面是部分示例。 ; frameOnly {| class="wikitable" style="width: 50em; max-width: 100%;" |- ! style="width: 60%;" | 代码 ! style="width: 40%;" | 结果 |- | <code><nowiki>{{ExampleArgs}}</nowiki></code> | firstInvokeArg |- | <code><nowiki>{{ExampleArgs|firstTemplateArg}}</nowiki></code> | firstInvokeArg |- | <code><nowiki>{{ExampleArgs|firstTemplateArg|secondTemplateArg}}</nowiki></code> | firstInvokeArg |} ; parentOnly {| class="wikitable" style="width: 50em; max-width: 100%;" |- ! style="width: 60%;" | 代码 ! style="width: 40%;" | 结果 |- | <code><nowiki>{{ExampleArgs}}</nowiki></code> | |- | <code><nowiki>{{ExampleArgs|firstTemplateArg}}</nowiki></code> | firstTemplateArg |- | <code><nowiki>{{ExampleArgs|firstTemplateArg|secondTemplateArg}}</nowiki></code> | firstTemplateArg secondTemplateArg |} ; parentFirst {| class="wikitable" style="width: 50em; max-width: 100%;" |- ! style="width: 60%;" | 代码 ! style="width: 40%;" | 结果 |- | <code><nowiki>{{ExampleArgs}}</nowiki></code> | firstInvokeArg |- | <code><nowiki>{{ExampleArgs|firstTemplateArg}}</nowiki></code> | firstTemplateArg |- | <code><nowiki>{{ExampleArgs|firstTemplateArg|secondTemplateArg}}</nowiki></code> | firstTemplateArg secondTemplateArg |} 注意: # 如果你同时设置了<code>frameOnly</code>和<code>parentOnly</code>参数选项,那么模块不会从#invoke接收到任何参数。 # 在一些情况下,父框架传递过来的参数可能无法获得,比如getArgs被传递给了基框架而不是父框架。这时候,只有框架参数会被使用,(除非设置了parentOnly,在这种情况下不会使用参数)并且<code>parentFirst</code>和<code>frameOnly</code>参数不会起作用。 <ref>这一段可能需要看完后面的部分才能够理解,翻译者注。</ref> === 包装器 === ''包装器''参数选项可以规定少数模板作为''包装模板''(wrapper template)。也就是说,这些模板唯一的作用就是去调用一个模块。如果这个模块发现是自己被包装模板调用的,它会只检查父框架的参数,否则,它会只检查传递给getArgs的参数。这允许模块既可以被#invoke调用,也可以被包装模板调用。在模块被包装模板调用的时候,并不会因为既需要检查当前框架,也需要检查父框架,而带来性能损失。 <!--例如,如果不算<nowiki><noinclude>...</noinclude></nowiki>中的内容的情况下,模板[[Template:Side box]] 的内容仅有<code><nowiki>{{#invoke:Side box|main}}</nowiki></code>。对于这个模板,对传给#invoke的参数无需进行检查,因为这里并没有参数被具体规定。我们可以通过使用''parentOnly''参数选项,来避免参数检查,但是如果这样的话,其他页面的#invoke可能会失效,比如,<code><nowiki>{{#invoke:Side box|main|text=Some text}}</nowiki></code>中的{{para|text|Some text}} 会被完全忽略。 --> 我们以[[Template:Side box]]模板举例,这个模板的有效内容<ref>指的是除了<nowiki><noinclude>...</noinclude></nowiki>的内容</ref>仅有<code><nowiki>{{#invoke:Side box|main}}</nowiki></code>这一小段。如果仅对于这个模板,我们可以使用''parentOnly''参数选项来优化(因为这样可以避免参数检查),但是这样会造成很大的问题,可能会影响其它的页面。比如,其他页面出现的<code><nowiki>{{#invoke:Side box|main|text=Some text}}</nowiki></code>中的{{para|text|Some text}}会被完全忽略。而使用<code>wrappers</code>参数选项,把模板'Template:Side box'包装为包装模板,就可以避免这个问题。 wrappers参数选项既可以被指定为一个字符串,也可以被指定为字符串数组。 <pre lang=lua> local args = getArgs(frame, { wrappers = 'Template:Wrapper template' }) </pre> <pre lang=lua> local args = getArgs(frame, { wrappers = { 'Template:Wrapper 1', 'Template:Wrapper 2', -- Any number of wrapper templates can be added here. } }) </pre> 注意: # 模块会自动地检测自己是被包装模板调用还是被沙盒子页面调用。所以无需显式指定沙盒页面。 # ''wrappers''参数选项会在特定时候有效地改变''frameOnly''和''parentOnly''。例如,如果将''parentOnly''显式设置为false,并设置了''wrappers'',通过包装模板的调用,当前框架和父框架都会被加载,而没有通过包装模板的调用仅仅会调用当前框架。 # 如果''wrappers''被设定,但并没有可用的父框架,模块一直从当前框架获取参数传递给<code>getArgs</code>。 === 对args表的写入 === 有时你可能需要在args表中写入新的值。模块的默认设定允许你这样做。(通常,创建一个新表,从args表复制需要的参数,是更好的编程习惯) <pre lang=lua> args.foo = 'some value' </pre> 你可以通过<code>readOnly</code>和<code>noOverwrite</code>参数选项来监测对args的写入。如果设定了<code>readOnly</code>,那么args表无法被写入。如果设定了<code>noOverwrite</code>,那么args表可以被写入,但是从#invoke传入的参数无法被修改。 === ref标签 === 这个模块使用[[mw:Extension:Scribunto/Lua reference manual#Metatables|元表]]来从#invoke中获取参数。这样可以无需<code>pairs()</code>函数,同时获取当前框架和父框架的参数。这样你的模块可以接受<nowiki><ref>...</ref></nowiki>标签(tag)作为输入。 只要Lua可以访问到<nowiki><ref>...</ref></nowiki>标签(reference),它们就会被MediaWiki软件处理,然后会有引用内容在页面的底部(注释与外部链接)出现。如果模块的输出省略了<nowiki><ref>...</ref></nowiki>标签,会触发一个bug:在引用列表会出现这个引用内容,但是没有数字连接到这个引用。这对于使用<code>pairs()</code>来检测是使用当前框架还是父框架的参数的模块来说是一个问题,因为这些模块会自动处理每个可用的参数。 然而本模块解决了这个问题,通过同时访问当前框架和父框架,仅在必要的时候获取参数。但是如果你的模块使用<code>pairs(args)</code>了,这个问题还是会出现。 === 本模块已知的缺陷 === 元表(metatable)的使用带来的副作用。Lua中大多数的table tools并不会正常运行在args表上。包括<code>#</code>运算符,<code>next()</code>函数,还有table library中的函数。如果你需要在你的模块用到这些,你应该用自己的函数来处理参数而不是这个模块。<includeonly>{{#ifeq:{{SUBPAGENAME}}|sandbox|}}</includeonly>
该页面使用的模板:
Hide
(
查看源代码
)
Para
(
查看源代码
)
返回
Arguments/doc
。
工具
链入页面
相关更改
特殊页面
页面信息
Cargo数据