Модуль:Arguments/doc: различия между версиями
Перейти к навигации
Перейти к поиску
Содержимое удалено Содержимое добавлено
Oreolek (обсуждение | вклад) мНет описания правки Метка: редактор вики-текста 2017 |
Oreolek (обсуждение | вклад) Содержимое страницы заменено на «Данный модуль служит для облегчения обработки аргументов, передаваемых в {{code|#invoke}}. Это мета-модуль, предназначенный для использования в других модулях, а не вики-страницах напрямую. Его функционал включает: * Облегчение обрезки аргуме...» Метки: замена редактор вики-текста 2017 |
||
| Строка 5: | Строка 5: | ||
* Большинство возможностей поддаются настройке. |
* Большинство возможностей поддаются настройке. |
||
См. [[ruwiki:Module:Arguments/doc|документацию на русской Википедии]]<includeonly>{{#ifeq:{{SUBPAGENAME}}|sandbox|| |
|||
== Базовое использование == |
|||
Первым делом, необходимо загрузить модуль. Он содержит всего одну функцию — {{code|getArgs}}. |
|||
{{luacode|1= |
|||
local getArgs = require('Module:Arguments').getArgs |
|||
}} |
|||
В наиболее простом сценарии вы можете использовать {{code|getArgs}} в главной функции вашего модуля. Переменная {{code|args}} содержит таблицу аргументов, переданных в {{code|#invoke}}. |
|||
{{luacode|1= |
|||
local getArgs = require('Module:Arguments').getArgs |
|||
local p = {} |
|||
function p.main(frame) |
|||
local args = getArgs(frame) |
|||
-- Основной код модуля. |
|||
end |
|||
return p |
|||
}} |
|||
Тем не менее, принятая практика заключается в использовании функции отдельной функции для получения аргуметов из {{code|#invoke}} и отдельной функции для их обработки — чтобы было проще вызывать ваши функции из другого модуля без передачи аргумента {{code|frame}}, что положительно влияет на производительность. |
|||
{{luacode|1= |
|||
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 |
|||
}} |
|||
Если вам нужно несколько разных функций, использующих аргументы вызова, вы можете использовать функцию-обёртку. |
|||
{{luacode|1= |
|||
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) |
|||
-- Код первой функции. |
|||
end |
|||
p.func2 = makeInvokeFunc('_func2') |
|||
function p._func2(args) |
|||
-- Код второй функции. |
|||
end |
|||
return p |
|||
}} |
|||
=== Опции === |
|||
Доступные опции приведены ниже. |
|||
{{luacode|1= |
|||
local args = getArgs(frame, { |
|||
trim = false, |
|||
removeBlanks = false, |
|||
valueFunc = function (key, value) |
|||
-- код, обрабатывающий единственный аргумент |
|||
end, |
|||
frameOnly = true, |
|||
parentOnly = true, |
|||
parentFirst = true, |
|||
wrappers = { |
|||
'Шаблон:Обёртка', |
|||
'Шаблон:Другая обёртка' |
|||
}, |
|||
readOnly = true, |
|||
noOverwrite = true |
|||
}) |
|||
}} |
|||
=== Обрезка и удаление пробелов === |
|||
Пустые аргументы могут представлять сложность при портировании кода шаблонов на Lua. В синтаксисе шаблонов пустые строки или строки из пробелов приравниваются к {{luafalse}}. В Lua же такие строки соответствуют {{luatrue}}. Поэтому, если вы уделите недостаточно внимания обработке таких аргументов, может нарушиться задуманная логика шаблона. Чтобы избежать такого развития событий, по умолчанию модуль удаляет все пустые аргументы. |
|||
Кроме того, пробелы могут вызывать проблемы при обработке позиционных аргументов. При вызове {{code|#invoke}} из именованных параметров пробелы по краям удаляются сами, но сохраняются для позиционных параметров. Большинство таких пробелов на самом деле не нужно, поэтому модуль по умолчанию их обрезает. |
|||
Однако же, если требуется сохранить эти пробелы, можно задать опциям {{code|trim}} и {{code|removeBlanks}} значение {{luafalse}}. |
|||
{{luacode|1= |
|||
local args = getArgs(frame, { |
|||
trim = false, |
|||
removeBlanks = false |
|||
}) |
|||
}} |
|||
=== Произвольное форматирование аргументов === |
|||
В некоторых случаях может потребоваться удалить только часть пустых аргументов или, например, привести все позиционные аргументы к нижнему регистру. Для этого можно использовать опцию {{code|valueFunc}}. На вход этой опции должна подавиться функция от двух параметров, {{var|key}} и {{var|value}}, возвращающая единственное значение. Это значение будет записано в поле {{code|key}} таблицы {{code|args}}. |
|||
Пример 1: оставлять нетронутыми пробелы в первом позиционном аргументе и применять стандартную обрезку для прочих. |
|||
{{luacode|1= |
|||
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 |
|||
}) |
|||
}} |
|||
Пример 2: удалить пробельные и пустые аргументы и привести все аргументы к нижнему регистру, но не обрезать пробелы из позиционных аргументов. |
|||
{{luacode|1= |
|||
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 |
|||
}) |
|||
}} |
|||
Замечание: функции выше выдадут ошибку, если входные аргументы не будут принадлежать к типу {{code|string}} или {{luanil}}. Это может произойти при вызове функции {{code|getArgs}} из другого модуля. В этом случае требуется проверка типов. В обычном случае при вызове из {{code|#invoke}} такая проблема не стоит. |
|||
{{Начало скрытого блока|Примеры 1 и 2 с проверкой типов}} |
|||
Пример 1: |
|||
{{luacode|1= |
|||
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 |
|||
}) |
|||
}} |
|||
Пример 2 2: |
|||
{{luacode|1= |
|||
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 |
|||
}) |
|||
}} |
|||
{{конец скрытого блока}} |
|||
Также следует обращать внимание, что функция {{code|valueFunc}} вызывается приблизительно при каждом запросе к таблице {{code|args}}, так что если стоит вопрос производительности, эта функция не должна быть дорогой. |
|||
=== Фреймы и родительские фреймы === |
|||
Аргументы в таблице {{code|args}} могут одновременно передаваться из текущего фрейма и его родительского фрейма. Это можно понять на примере. Например, есть модуль {{code|Module:ExampleArgs}}, работа которого заключается в выводе двух первых переданных позиционных аргументов. |
|||
{{Начало скрытого блока|Код модуля ExampleArgs}} |
|||
{{luacode|1= |
|||
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 |
|||
}} |
|||
{{конец скрытого блока}} |
|||
{{code|Модуль:ExampleArgs}} вызывается шаблоном {{tc|ExampleArgs}}, код которого — {{tc|#invoke:ExampleArgs|main|первый_аргумент_вызова}}. По умолчанию он возвращает текст «первый_аргумент_вызова». |
|||
Далее возможны следующие варианты: |
|||
{| class="wikitable" style="width: 70em; max-width: 100%;" |
|||
|- |
|||
! style="width: 60%;" | Код |
|||
! style="width: 40%;" | Результат |
|||
|- |
|||
| {{tc|ExampleArgs}} |
|||
| первый_аргумент_вызова |
|||
|- |
|||
| {{tc|ExampleArgs|первый_аргумент_вызова}} |
|||
| первый_аргумент_вызова |
|||
|- |
|||
| {{tc|ExampleArgs|первый_аргумент_вызова|второй_аргумент_вызова}} |
|||
| первый_аргумент_вызова второй_аргумент_вызова |
|||
|} |
|||
Это поведение можно изменить тремя опциями: {{code|frameOnly}}, {{code|parentOnly}} и {{code|parentFirst}}. При установке {{code|frameOnly}} будут обрабатываться только аргументы фрейма, где происходит непосредственно вызов {{code|#invoke}}; при установке {{code|parentOnly}} будут обрабатываться только аргументы родительского фрейма; при установке {{code|parentFirst}} будут обрабатываться аргументы из обоих фреймов, но в первую очередь родительского. В случае рассматриваемого {{tc|ExampleArgs}} это будет выглядеть так: |
|||
; frameOnly |
|||
{| class="wikitable" style="width: 70em; max-width: 100%;" |
|||
|- |
|||
! style="width: 60%;" | Код |
|||
! style="width: 40%;" | Результат |
|||
|- |
|||
| {{tc|ExampleArgs}} |
|||
| первый_аргумент_вызова |
|||
|- |
|||
| {{tc|ExampleArgs|первый_аргумент_шаблона}} |
|||
| первый_аргумент_вызова |
|||
|- |
|||
| {{tc|ExampleArgs|первый_аргумент_шаблона|второй_аргумент_шаблона}} |
|||
| первый_аргумент_вызова |
|||
|} |
|||
; parentOnly |
|||
{| class="wikitable" style="width: 70em; max-width: 100%;" |
|||
|- |
|||
! style="width: 60%;" | Код |
|||
! style="width: 40%;" | Результат |
|||
|- |
|||
| {{tc|ExampleArgs}} |
|||
| |
|||
|- |
|||
| {{tc|ExampleArgs|первый_аргумент_шаблона}} |
|||
| первый_аргумент_шаблона |
|||
|- |
|||
| {{tc|ExampleArgs|первый_аргумент_шаблона|второй_аргумент_шаблона}} |
|||
| первый_аргумент_шаблона второй_аргумент_шаблона |
|||
|} |
|||
; parentFirst |
|||
{| class="wikitable" style="width: 70em; max-width: 100%;" |
|||
|- |
|||
! style="width: 60%;" | Код |
|||
! style="width: 40%;" | Результат |
|||
|- |
|||
| {{tc|ExampleArgs}} |
|||
| первый_аргумент_вызова |
|||
|- |
|||
| {{tc|ExampleArgs|первый_аргумент_шаблона}} |
|||
| первый_аргумент_шаблона |
|||
|- |
|||
| {{tc|ExampleArgs|первый_аргумент_шаблона|второй_аргумент_шаблона}} |
|||
| первый_аргумент_шаблона второй_аргумент_шаблона |
|||
|} |
|||
Замечания: |
|||
# При установке одновременно опций {{code|frameOnly}} и {{code|parentOnly}} модуль не получит никаких аргументов из {{code|#invoke}}. Так делать не стоит. |
|||
# В некоторых ситуациях родительский фрейм может быть недоступен, например, если он был сразу подан на вход функции {{code|getArgs}}. Тогда могут использоваться лишь аргументы этого фрейма (если установлена опция {{code|parentOnly}}, то никакие аргументы получить не удастся), а {{code|parentFirst}} и {{code|frameOnly}} не будут иметь эффекта. |
|||
=== Обёртки === |
|||
Опция {{var|wrappers}} используется для указания ограниченного числа шаблонов как ''шаблонов-обёрток'', то есть шаблонов, чьей единственной целью является вызов модуля. Если модуль обнаружит, что вызывается из шаблона-обёртки, то будут проверяться только аргументы родительского фрейма, иначе будут проверяться только аргументы непосредственного вызывающего фрейма. Это позволяет вызвать модули через {{code|#invoke}} и через шаблон-обёртку без потери производительности из-за поиска аргументов в двух фреймах. |
|||
Например, единственное содержимое шаблона {{tl|optp}} вне тэгов {{tag|noinclude}} это вызов <nowiki>{{#invoke:Template call code|onlyParams}}</nowiki>. Нет смысла проверять аргументы, передаваемые {{code|#invoke}} на странице шаблона, поскольку там их никогда не будет. Этого можно избежать с помощью опции {{var|parentOnly}}, но тогда {{code|#invoke}} не будет работать и на других страницах. В таком случае параметр {{para|text|Некий текст}} в коде <code><nowiki>{{#invoke:Template call code|onlyParams|text=Некий текст}}</nowiki></code> игнорировался бы на всех страницах. Но если мы укажем в опции {{var|wrappers}} 'Шаблон:Optp', код <code><nowiki>{{#invoke:Template call code|onlyParams|text=Некий текст}}</nowiki></code> будет работать на всех страницах, не проверяя аргументы на странице шаблона. |
|||
Обёртки могут задаваться строкой или массивом строк. |
|||
{{luacode|1= |
|||
local args = getArgs(frame, { |
|||
wrappers = 'Шаблон:Обёртка' |
|||
}) |
|||
}} |
|||
{{luacode|1= |
|||
local args = getArgs(frame, { |
|||
wrappers = { |
|||
'Шаблон:Обёртка 1', |
|||
'Шаблон:Обёртка 2', |
|||
-- Тут может быть задано любое количество шаблонов. |
|||
} |
|||
}) |
|||
}} |
|||
Замечания: |
|||
# Модуль автоматически определяет, если вызывается с подстраницы /песочница шаблона-обёртки, такие страницы не надо задавать явным образом. |
|||
# Опция{{var|wrappers}} изменяет поведение по умолчанию опций {{var|frameOnly}} и {{var|parentOnly}}. Например, если {{var|parentOnly}} явным образом установлена в {{luafalse}} при установленных {{var|wrappers}}, вызов через обёртку будет приводить к проверке аргументов текущего и родительского фрейма, тогда как другие вызовы будут проверять только текущие аргументы. |
|||
# Если опция {{var|wrappers}} установлена и родительский фрейм недоступен, модуль всегда будет получать аргументы, переданные функции {{code|getArgs}}. |
|||
=== Запись в таблицу args === |
|||
Иногда может быть полезно записать новые значения в таблицу {{code|args}}. При настройках данного модуля по умолчанию это возможно. (Тем не менее, в большинстве случаев лучшим подходом будет создать новую таблицу с новыми значениями и копировать туда нужные значения {{code|args}}.) |
|||
{{luacode|1= |
|||
args.foo = 'some value' |
|||
}} |
|||
С помощью установки опций {{var|readOnly}} и {{var|noOverwrite}} это поведение можно переопределить. Если установлена опция {{var|readOnly}}, в таблицу {{code|args}} нельзя вносить изменения вообще. При установке же опции {{var|noOverwrite}} можно добавлять новые значения, но нельзя менять уже имеющиеся в таблице значения, полученные из {{code|#invoke}}. |
|||
=== Тэги ref === |
|||
Данный модуль использует [[mw:Extension:Scribunto/Lua reference manual/ru#Metatables|метатаблицы]], чтобы получить аргументы {{code|#invoke}}. Это даёт доступ одновременно к аргументом фрейма и родительского фрейма без использования функции {{luacode|pairs()|inline=1}}. Это может быть полезно при передаче на вход тэгов {{xtag|ref|p}}. |
|||
Поскольку из Lua происходит доступ к тэгам {{tag|ref}}, они обрабатываются движком MediaWiki и примечание появляется в списке примечаний ({{tag|referenes|s}}). Если модуль не выводит содержимое тэгов, то может появиться сноска-призрак, отображающаяся только в списке примечаний, но не в основном тексте. Это может являться проблемой для модулей, использующих {{luacode|pairs()|inline=1}} для доступа к аргументам, поскольку эта функция осуществляет доступ ко всем доступным аргументам. |
|||
Эта проблема не стоит при использовании данного модуля, поскольку хотя доступ к аргументам производится только по необходимости. Однако же при явном вызове {{luacode|pairs(args)|inline=1}} в коде функций, ошибочное поведение может воспроизводиться. |
|||
=== Известные ограничения === |
|||
У использования метатаблиц есть свои недостатки. Большинство инструментов для работы с обычными таблицами Lua не будут корректно работать с таблицей {{code|args}}, включая оператор {{code|#}}, функцию {{luacode|next()|inline=1}} и функции из стандартной библиотеки {{code|table}}. Если данные функции необходимы для работы модуля, может понадобиться своя реализация обработки аргументов. Также возможно использование функций из модуля [[Module:TableTools|TableTools]]. |
|||
<includeonly>{{#ifeq:{{SUBPAGENAME}}|sandbox|| |
|||
[[Категория:Модули:Базовые]] |
[[Категория:Модули:Базовые]] |
||
}}</includeonly> |
}}</includeonly> |
||
Версия от 03:57, 30 сентября 2025
Данный модуль служит для облегчения обработки аргументов, передаваемых в #invoke. Это мета-модуль, предназначенный для использования в других модулях, а не вики-страницах напрямую. Его функционал включает:
- Облегчение обрезки аргументов и удаления пустых аргументов.
- Аргументы, передаваемые не только текущим фреймов, но и родительским фреймом. (См. ниже)
- Аргументы, передаваемые из другого модуля или отладочной консоли.
- Большинство возможностей поддаются настройке.