Модуль:Transclude
Внимание! Это один из самых используемых модулей. |
Этот модуль относится к критическим. У него очень много включений или он используется с подстановкой. Из-за опасности вандализма или ошибочного редактирования он был защищён. |
Этот модуль содержит функции, позволяющие вызывать внутренний шаблон из объемлющего шаблона после некоторой обработки параметров. Под объемлющим шаблоном имеется в виду шаблон, в котором написано {{#invoke:Transclude|...
, например, {{Пиктограммы СГС}}. В вызове модуля указывается название функции и внутренний шаблон, вроде {{Пиктограммы СГС/основа}}, который собственно и обрабатывает аргументы, полученные от объемлющего шаблона.
Функция | Код объемлющего шаблона | Код его вызова | Результат |
---|---|---|---|
call | {{#invoke:Transclude|call|внутренний шаблон}}<br>дополнение
|
{{объемлющий шаблон|1|2|3}}
|
{{внутренний шаблон|1|2|3}}<br>дополнение
|
forall | {{#invoke:Transclude|forall|внутренний шаблон}}
|
{{объемлющий шаблон|1|2|3}}
|
{{внутренний шаблон|1}}
|
join | {{#invoke:Transclude|join|<nowiki>, </nowiki>|<nowiki> и </nowiki>}}
|
{{объемлющий шаблон|1|2|3}}
|
1, 2 и 3
|
npc | {{#invoke:Transclude|npc|внутренний шаблон|вверху=|внизу=}}
|
{{объемлющий шаблон |вверху1 = 11 |внизу1 = 12 |вверху2 = 21 |внизу2 = 22 }} |
{{внутренний шаблон |вверху = 11 |внизу = 12 }}{{внутренний шаблон |вверху = 21 |внизу = 22 }} |
cycle | TODO | TODO | TODO |
Методы
call
{{#invoke:Transclude|call|внутренний шаблон}}
Вызывает внутренний шаблон с аргументами объемлющего шаблона (того, в коде которого указан #invoke). Нужно для того, чтобы дописать к выводу внутреннего шаблона что-то новое. Передаются как нумерованные, так и именованные аргументы.
Например, объемлющий шаблон с кодом
{{#invoke:Transclude|call|внутренний шаблон}}<br>дополнение
,
вызванный таким образом:
{{объемлющий шаблон|1|2|3}}
,
вернёт
{{внутренний шаблон|1|2|3}}<br>дополнение
.
Пример использования: Шаблон:TRef.
forall
{{#invoke:Transclude|forall|внутренний шаблон}}
{{#invoke:Transclude|forall|внутренний шаблон|separator=разделитель|conjunction=последний разделитель}}
Вызывает внутренний шаблон, по одному передавая ему нумерованные параметры объемлющего шаблона (того, в коде которого указан #invoke). Параметры могут быть набраны в произвольном порядке и с пропусками, они будут отсортированы. Пустые параметры не пробрасываются.
Например, объемлющий шаблон с кодом
{{#invoke:Transclude|forall|внутренний шаблон}}
,
вызванный таким образом:
{{объемлющий шаблон|1|2|3}}
,
вернёт
{{внутренний шаблон|1}}{{внутренний шаблон|2}}{{внутренний шаблон|3}}
.
Можно передать разделитель и последний разделитель через параметры separator и conjunction, по умолчанию они пусты. Если указан только separator, то conjunction заполняется из него. Например, объемлющий шаблон с кодом
{{#invoke:Transclude|forall|внутренний шаблон|separator=<nowiki>, </nowiki>|conjunction=<nowiki> и </nowiki>}}
,
вызванный таким образом:
{{объемлющий шаблон|1|2|3}}
,
вернёт
{{внутренний шаблон|1}}, {{внутренний шаблон|2}} и {{внутренний шаблон|3}}
,
а объемлющий шаблон с кодом
{{#invoke:Transclude|forall|внутренний шаблон|separator=<nowiki>, </nowiki>}}
,
вызванный таким образом:
{{объемлющий шаблон|1|2|3}}
,
вернёт
{{внутренний шаблон|1}}, {{внутренний шаблон|2}}, {{внутренний шаблон|3}}
.
Если требуется, чтобы разделитель содержал пробел в начале или в конце, нужно заключить его в <nowiki></nowiki>
.
Примеры использования:
- Простой: Шаблон:Пиктограммы СГС вызывает Шаблон:Пиктограммы СГС/основа, см. Шаблон:Пиктограммы СГС/тесты.
- Более продвинутый: Шаблон:Falseredirect вызывает Шаблон:Falseredirect/основа, см. Шаблон:Falseredirect/тесты.
join
{{#invoke:Transclude|join|разделитель|последний разделитель}}
Берёт нумерованные аргументы объемлющего шаблона (того, в коде которого указан #invoke) и склеивает их в единую строку. Пустые аргументы пропускаются. Используются разделитель и последний разделитель, указанные первым и вторым параметрами в вызове модуля. Если указан только первый параметр, второй заполняется из него.
Например, объемлющий шаблон с кодом
{{#invoke:Transclude|join|<nowiki>, </nowiki>|<nowiki> и </nowiki>}}
,
вызванный таким образом:
{{объемлющий шаблон|1|2|3}}
,
вернёт
1, 2 и 3
,
а объемлющий шаблон с кодом
{{#invoke:Transclude|join|<nowiki>, </nowiki>}}
,
вызванный таким образом:
{{объемлющий шаблон|1|2|3}}
,
вернёт
1, 2, 3
.
Если требуется, чтобы разделитель содержал пробел в начале или в конце, нужно заключить его в <nowiki></nowiki>
.
Фактически аналогичен использованию #forall с внутренним шаблоном с кодом 1
и другим способом указания разделителей.
Пример использования: Шаблон:Luaman и Шаблон:Luaman/тесты (TODO: заменить на более внятный пример).
См. также: Модуль:Separated entries.
npc
{{#invoke:Transclude|npc|внутренний шаблон|параметр=|другой параметр=|…}}
{{#invoke:Transclude|npc|внутренний шаблон|общий параметр=значение|другой общий параметр=значение|…|параметр=|другой параметр=|…}}
Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона (того, в коде которого указан #invoke). Параметр название12 передаётся как название в 12-й вызов шаблона. Для этого нужно указать в вызове модуля |название=
.
Например, объемлющий шаблон с кодом
{{#invoke:Transclude|npc|внутренний шаблон|вверху=|внизу=}}
,
вызванный таким образом:
{{объемлющий шаблон |вверху1 = 11 |внизу1 = 12 |вверху2 = 21 |внизу2 = 22 |вверху3 = 31 |внизу3 = 32 }}
возращает
{{внутренний шаблон |вверху = 11 |внизу = 12 }}{{внутренний шаблон |вверху = 21 |внизу = 22 }}{{внутренний шаблон |вверху = 31 |внизу = 32 }}
Можно также указать в вызове модуля общие аргументы, который будут передаваться в каждый вызов внутреннего шаблона. Например, объемлющий шаблон с кодом
{{#invoke:Transclude|npc|внутренний шаблон|общий={{{общий|}}}|вверху=|внизу=}}
,
вызванный таким образом:
{{объемлющий шаблон |общий = 0 |вверху1 = 11 |внизу1 = 12 |вверху2 = 21 |внизу2 = 22 |вверху3 = 31 |внизу3 = 32 }}
возращает
{{внутренний шаблон |общий = 0 |вверху = 11 |внизу = 12 }}{{внутренний шаблон |общий = 0 |вверху = 21 |внизу = 22 }}{{внутренний шаблон |общий = 0 |вверху = 31 |внизу = 32 }}
Обратите внимание, что необходимо ставить вертикальную черту сразу после значения общего параметра, потому что вызовы модулей, в отличие от вызовов шаблонов, не обрезают пробелы:
{{#invoke:Transclude|npc|внутренний шаблон|общий={{{общий|}}}|вверху=|внизу=}}
или
{{#invoke:Transclude|npc|внутренний шаблон| общий={{{общий|}}}| вверху=| внизу=}}
но не
{{#invoke:Transclude|npc|внутренний шаблон |общий={{{общий|}}} |вверху= |внизу=}}
Замечания:
- Общие параметры также учитываются вместе с остальными при выборе того, что передавать во внутренний шаблон: если в объемлющем шаблоне указан параметр общий12, он передастся в 12-й вызов внутреннего шаблона под названием общий и может заменить общий параметр.
- Происходят вызовы внутреннего шаблона не для всех нумерованных блоков параметров, а только для непустых, так что могут быть пропуски. А именно, вызывается блок 12, если в объемлющем шаблоне есть параметр параметр12 и в вызове модуля есть параметр параметр. Рекомендуется, чтобы внутренний шаблон при вызове без параметров возвращал пустую строку.
Пример использования: Шаблон:Карточка вызывает Шаблон:Карточка/внизу.
cycle
{{#invoke:Transclude|cycle|имя шаблоан|n|список параметров…}}
Этот раздел не завершён. |
Действует аналогично #forall по числовой переменной, изменяющейся от 1 до n. Другое начало можно задать в виде «-10..10» вместо n, или в обратном порядке «10..-10». Также можно задать предел цикла в виде имени шаблона (если второго параметра нет или он имеет вид «1..», шаблон раскрывается, пока не пуст). Не увлекайтесь!
Замечание: номера нумерованных параметров шаблона при записи увеличить на 1.
Параметром output
можно задать как выводить шаблоны.
- newline — каждый шаблон на новой строке.
- inline — все шаблоны в одну строку (по-умолчанию).
Тесты шаблона
См. Модуль:Transclude/tests и Шаблон:Test transclude.
См. также
local M={}
---------------------------------------------------------
-- Функции для работы с параметрами вызвавшего шаблона --
---------------------------------------------------------
function M.uni(f)-- Унификация имён параметров; псевдонимы.
local tf, cs=f:getParent(), {};
local findcs=function(a) cs[a]=f.args[a] end;
(f.args['|фиксрег'] or f.args['|fixreg'] or ''):gmatch(' *([^%n]+) *', findcs);
-- {{!}}фиксрег = список разделённых новыми строками аргументов, регистр которых не менять
local args,am={};
for a,v in pairs(tf.args) do
am = a:lower():gsub('[_ ]+',' ');
args[ cs[a] and a or ( f.args[am] or am ) ] = v
end
return tf:expandTemplate{title=f.args[1]; args=args}
end
function M.forall(frame)-- Итератор по нумерованным аргументам вызывающего шаблона.
local template = frame.args[1]
local separator = frame.args.separator or ''
local conjunction = frame.args.conjunction or separator
local results = {}
for param, value in pairs(frame:getParent().args) do
if type(param) == 'number' then
results[param] = frame:expandTemplate{ title = template, args = {value} }
end
end
return mw.text.listToText( results, separator, conjunction )
end
function M.escapeparams(f)-- Нормализация
-- (обезопасивание) значений параметров.
local i,ac,acn=0,{},{};
local function repl(s)
return s:gsub('{{','{{Х'):gsub('}}',"{{ЪЪ}}"):gsub('{{Х','{{ХХ}}')--: --замена фигурных скобок
:gsub('=','{{=}}'):gsub('|','{{!}}')
end
for k,v in pairs(f:getParent().args) do
if type(k)=='number' then ac[k]=repl(v); i=i+1
else acn[repl(k)]=repl(v)end
end
if i ~= #ac-1 then --нумерованные параметры не сплошные
for k,v in pairs(ac) do
if k>i then acn[tostring(k)] = v; ac[k]=nil end-- удалять в pairs можно
end
end
for k,v in pairs(acn) do
table.insert(ac, table.concat(f.args[2] or "\n ", k, f.args[3] or ' = ', v, f.args[4] or '') )
end
return table.concat(ac,'|')
end
function M.npc(f)-- Итератор по именованно-нумерованным параметрам.
local tf, ac, ns = f:getParent(), {}, {};
for k,v in pairs(tf.args) do
local b,n = string.match(k,"^(.-)%s*(%d*)$");
n = tonumber(n);
if n then
if f.args[b] then
if not ac[n] then
ac[n] = mw.clone(f.args)
setmetatable( ac[n], nil ) -- metatable ломает expandTemplate
table.insert(ns,n)
end
ac[n][b] = v
end--if f.args[b]
end--if n
end--for
table.sort(ns);
local tmod = #f.args-1
for n,i in ipairs(ns) do
ns[n]=tf:expandTemplate{ title=f.args[n % tmod+1]; args=ac[i] }
end
return table.concat(ns)
end
function M.call(f)-- Просто вызывает шаблон с аргументами вызывающего.
return f:getParent():expandTemplate{ title=f.args[1]; args=f:getParent().args }
end
function M.join(f)-- Версия forall с разделителем вместо шаблона.
-- f.args[1] — разделитель.
local t, tf, i = {}, f:getParent(), tonumber(f.args.from) or 1
local k,j,m = tonumber(f.args.to),i,f.args[3]
while k and i<=k or tf.args[i] do
if (
({
['_']=function(s)return s~=''end;
['s']=function(s)return not tostring(s):match("^%s*$")end
})[m] or function() return true end
)(tf.args[i]) then
t[j]=tf.args[i];
j=j+1
end;
i=i+1
end
return mw.text.listToText(t,f.args[1],f.args[2] or f.args[1])
end
-------------------------------------------------------
-- Функции для работы с параметрами шаблона в invoke --
-------------------------------------------------------
--[[
function M.split(f)-- Разрезает строку f.args[3]
-- указанным в f.args[2](?) разделителем
-- и передаёт куски шаблону f.args[1].
local tf, ac, oldi, i, e =f:getParent(), {}, 1, f.args[3]:find(f.args[1],1,true)
-- «f.args[1]» в строке выше — точно не ошибка? --Incnis Mrsi
while i do
table.insert( ac, f.args[3]:sub(oldi, i-1) ); oldi=e+1
end
table.insert( ac, f.args[3]:sub(oldi, #f.args[3]-1) )
return f:getParent():expandTemplate{ title=f.args[1]; args=ac }
end
]]
function M.cycle(f)-- Действует аналогично forall по числовой переменной,
-- изменяющейся (по умолчанию, от 1) до f.args[2].
local tf,ac=f:getParent(),{};
for p,k in pairs(f.args) do
if type(p)=='number' then
if p>2 then ac[p-1]=k end
else ac[p]=k
end
end
local s,fh = f.args[2]:match('^%s*(%-?%d+)%s*%.%.') or 1,
f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or '';
fh=tonumber(fh) or fh:match('^%s*(.-)%s*$');
local acr={};
if not tonumber(s) then error('Начало цикла «'..s..'» — не число') end
local function dc()
local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} }
s=s+1;
if r~='' then table.insert(acr,r); return r end
end
if type(fh)=='number' then
while s<fh do dc() end
elseif fh~='' then
while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc() end
else
while dc() do end
end
return table.concat(acr)
end
--[[Функция не пашет как можно ждать — пробелы отсекаются после передачи параметров в expandTemplate
function M.pass(f)-- Передаёт шаблону параметры без подрезки.
local ac,i={},1;
while f.args[2*i] do ac[ tonumber(f.args[2*i]) or f.args[2*i] ] = f.args[2*i+1]; i=i+1 end;
return f:getParent():expandTemplate{ title=f.args[1]; args=ac }
end
]]
return M