Modul:Template wrapper
| Modul Lua ini digunakan pada sekitar 15.000 halaman dan perubahannya kemungkinan memicu perubahan massal pada semua halaman yang menggunakannya. Uji cobalah di subhalaman /bak pasir atau /kasus uji Modul:Template wrapper, atau bak pasir modul Anda. Pertimbangkan untuk mendiskusikan perubahan di halaman pembicaraan sebelum mengimplementasikannya. |
Modul ini digunakan dalam templat pembungkus untuk memungkinkan templat tersebut menyediakan nilai parameter bawaan serta mengizinkan penyunting untuk meneruskan parameter tambahan ke templat kerja dasar.
Saat menulis templat pembungkus, berikan modul ini semua parameter bawaan wajib yang biasanya diperlukan untuk menggunakan templat pembungkus dalam bentuk dasarnya. Penyunting kemudian dapat menggunakan templat pembungkus sebagaimana adanya atau dapat memberikan parameter pembungkus dan parameter kanonis tambahan. Parameter kanonis apa pun yang didukung oleh templat kerja dapat ditambahkan ke templat pembungkus atau disediakan oleh penyunting di ruang nama artikel. Ketika penyunting menyediakan parameter yang memiliki nilai bawaan dalam templat pembungkus, nilai yang disediakan oleh penyunting akan menimpa nilai bawaan tersebut. Jika perlu menghapus parameter bawaan, penyunting dapat mengatur nilai parameter ke kata kunci khusus unset yang akan menyebabkan modul pembungkus ini menghapus nilai bawaan templat pembungkus untuk parameter tersebut. Modul ini mengabaikan parameter bernama yang kosong.
Parameter posisional biasanya tidak diteruskan ke templat kerja. Mengatur |_include-positional=yes akan meneruskan semua parameter posisional ke templat kerja. Parameter posisional tidak dapat dikecualikan; parameter posisional dapat diatur menjadi unset.
Parameter yang hanya digunakan oleh pembungkus harus berupa posisional ({{{n}}}) atau tercantum dalam |_exclude= (daftar parameter bernama yang dipisahkan dengan koma). Modul ini tidak akan meneruskan parameter dalam _exclude ke templat kerja.
Penggunaan
{{#invoke:Template wrapper|wrap|_template=templat kerja|_exclude=parameter bernama, parameter bernama, ...|_reuse=parameter bernama, parameter bernama, ...|_alias-map=parameter alias:parameter kanonis|_include-positional=yes|<parameter bawaan>>|<parameter bawaan>>|...}}
- Parameter kendali
|_template=– (wajib) nama templat kerja (templat yang dibungkus), tanpa ruang nama; lihat §_template di bawah|_exclude=– daftar nama parameter yang dipisahkan koma yang digunakan oleh templat pembungkus dan tidak boleh diteruskan ke templat kerja; lihat §_exclude di bawah|_reuse=– daftar nama kanonis yang dipisahkan koma yang memiliki arti baik bagi templat pembungkus maupun templat kerja; lihat §_reuse di bawah|_alias-map=– daftar nama parameter templat pembungkus yang dipisahkan koma yang akan diperlakukan sebagai alias dari parameter kanonis templat kerja tertentu; lihat §_alias-map di bawah|_include-positional=– teruskan semua parameter posisional ke templat kerja; lihat §_include-positional di bawah
- Definisi
- parameter kanonis – parameter yang didukung dan digunakan oleh templat kerja
- parameter pembungkus – parameter yang digunakan oleh templat pembungkus; dapat menyediakan data untuk parameter kanonis atau mengendalikan aspek lain dari templat pembungkus
- parameter alias – parameter pembungkus yang bermakna secara kontekstual bagi templat pembungkus tetapi harus diubah namanya menjadi parameter kanonis untuk digunakan oleh templat kerja
- parameter guna ulang (reused) – parameter yang digunakan bersama oleh templat pembungkus dan templat kerja serta telah diubah oleh templat pembungkus
- parameter bawaan – parameter kanonis yang diberi nilai bawaan dalam templat pembungkus
| templat pembungkus |
Module:Template wrapper | templat kerja | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|parameter kanonis= |
→ | –––––––→ | → | –––––––→ | → | –––––––→ | → | –––––––→ | → | –––––––→ | → | filter parameter yang dikecualikan |
templat kerja | |
|parameter pembungkus= |
→ | –––––––→ | → | –––––––→ | → | –––––––→ | → | –––––––→ | → | –––––––→ | → | |||
|_exclude= |
→ | –––––––→ | → | –––––––→ | → | –––––––→ | → | –––––––→ | → | → | ||||
|_include-positional= |
→ | –––––––→ | → | –––––––→ | → | –––––––→ | → | –––––––→ | → | |||||
|_alias-map= |
→ | konversi parameter alias ke parameter kanonis |
→ | |parameter kanonis= |
→ | –––––––→ | → | –––––––→ | → | → | ||||
| → | → | ubah parameter kanonis yang digunakan ulang | ||||||||||||
|parameter alias= |
→ | –––––––→ | → | → | |parameter guna ulang= |
→ | –––→ | → | ||||||
|_reuse= |
→ | –––––––→ | → | –––––––→ | → | |||||||||
|parameter kanonis= |
→ | –––––––→ | → | –––––––→ | → | –––––––→ | → | |||||||
|parameter bawaan= |
→ | –––––––→ | → | –––––––→ | → | –––––––→ | → | –––––––→ | → | –––→ | → |
Rincian parameter
_template
Satu-satunya parameter yang wajib diisi, |_template= menyediakan nama templat kerja (templat yang dibungkus), tanpa ruang nama. Jika parameter ini diabaikan, Module:Template wrapper akan menampilkan pesan kesalahan:
|_template=hilang atau kosong
_alias-map
|_alias-map= menerima daftar parameter templat pembungkus yang dipisahkan koma yang akan diperlakukan sebagai alias dari parameter kanonis templat kerja yang ditentukan. Setiap elemen pemetaan dalam daftar memiliki format:
<dari>:<ke>– di mana:<dari>adalah nama parameter pembungkus dan<ke>adalah nama parameter kanonis
Dalam contoh ini, mungkin lebih disukai bagi templat pembungkus untuk menggunakan |assessor= yang mungkin tidak dikenal oleh templat kerja, tetapi templat kerja memiliki parameter setara yaitu |author=, sehingga dalam {{#invoke:}} kita menulis:
|_alias-map=assessor:author
Parameter posisional juga dapat dipetakan ke parameter kanonis:
|_alias-map=1:author, 2:title, 3:language
Parameter pembungkus bernomor (enumerasi) dapat dipetakan ke parameter kanonis bernomor menggunakan penentu enumerator #:
|_alias-map=assessor#:author#
Berdasarkan contoh di atas, |assessor2= akan dipetakan ke |author2=; selain itu, |assessor= dan |assessor1= akan dipetakan ke |author1=
Beberapa parameter pembungkus dapat dipetakan ke satu parameter kanonis:
|_alias-map=1:author, assessor:author
Parameter pembungkus yang terdaftar dalam |alias-map= tidak akan diteruskan ke templat kerja. Memetakan parameter posisional saat |_include-positional=yes dapat memberikan hasil yang tidak diinginkan. |_alias-map=1:author dan |_include-positional=yes akan menyebabkan semua parameter posisional lainnya diteruskan ke templat kerja apa adanya: {{{2}}} pada templat pembungkus menjadi {{{2}}} pada templat kerja, dan seterusnya; templat kerja tidak akan menerima {{{1}}} meskipun akan menerima |author=.
_reuse
|_reuse= menerima daftar parameter kanonis yang dipisahkan koma yang memiliki arti baik bagi templat pembungkus maupun templat kerja; tidak didukung untuk parameter posisional.
Dalam kasus paling sederhana, parameter kanonis yang diteruskan ke templat pembungkus menimpa parameter bawaan yang disediakan dalam templat pembungkus. Kadang-kadang parameter pembungkus sama dengan parameter kanonis dan templat pembungkus perlu mengubah nilai parameter tersebut sebelum diteruskan ke templat kerja. Dalam contoh ini, |title= adalah parameter pembungkus sekaligus parameter kanonis yang perlu diubah oleh templat pembungkus sebelum diteruskan ke templat kerja. Untuk melakukan ini, pertama-tama kita menulis:
|_reuse=title
kemudian, dalam templat pembungkus {{#invoke:Template wrapper|wrap|_template=...|...}} kita menulis:
|title=Diubah {{{title}}}
Parameter dalam _reuse tidak dapat ditimpa.
_exclude
|_exclude= menerima daftar parameter yang dipisahkan koma yang digunakan oleh templat pembungkus dan tidak boleh diteruskan ke templat kerja. Daftar ini berlaku untuk semua parameter pembungkus dan kanonis (termasuk parameter kanonis yang merupakan hasil perubahan nama dari parameter alias) yang diterima dari templat pembungkus.
Sebagai contoh, templat pembungkus mungkin menggunakan |id= untuk menyediakan sebagian nilai yang ditetapkan pada parameter bawaan |url=, sehingga kita menulis:
|_exclude=id
kemudian, dalam templat pembungkus {{#invoke:Template wrapper|wrap|_template=...|...}} kita menulis:
|url=https://example.com/{{{id}}}
Nilai |url= yang diubah akan diteruskan ke templat kerja, tetapi |id= beserta nilainya tidak akan diteruskan.
Parameter dalam _reuse dan parameter bawaan tidak dapat dikecualikan.
_include-positional
|_include-positional= adalah parameter boolean yang hanya menerima satu nilai: yes; nilai bawaannya (kosong, tidak ada) adalah no (parameter posisional biasanya dikecualikan). Ketika diatur ke yes, Module:Template wrapper akan meneruskan semua parameter posisional ke templat kerja.
Lihat juga §_alias-map.
Menimpa parameter bawaan
Penyunting dapat menimpa parameter bawaan dengan cara menetapkan parameter bawaan tersebut ke nilai yang diinginkan dalam templat pembungkus. Modul ini mengabaikan parameter kosong (parameter yang diberi nama tetapi tidak memiliki nilai yang ditetapkan). Jika ingin menimpa parameter bawaan menjadi tanpa nilai, gunakan kata kunci khusus unset. Parameter bawaan dengan nilai ini akan diteruskan ke templat kerja sebagai parameter kosong (tanpa nilai yang ditetapkan).
Parameter dalam _reuse tidak dapat diatur menjadi unset atau ditimpa.
Mode pembenahan/dokumentasi
Modul ini memiliki dua titik masuk. Sebuah templat pembungkus mungkin menggunakan panggilan modul {{#invoke:}} yang ditulis seperti ini:
{{#invoke:Template wrapper|{{#if:{{{_debug|}}}|list|wrap}}|_template=<templat kerja>|_exclude=_debug, ...|...}}
di mana parameter pembungkus |_debug=, yang diisi dengan nilai apa pun, akan menyebabkan modul menampilkan pemanggilan ke templat kerja tanpa benar-benar memanggil templat kerja tersebut.
Sebagai contoh, {{cite wikisource}} adalah templat pembungkus yang menggunakan {{citation}} sebagai templat kerjanya. {{cite wikisource}} menerima parameter posisional tetapi {{citation}} tidak, sehingga templat pembungkus harus mengonversi parameter posisional menjadi parameter bernama yang dilakukan menggunakan parameter |_alias-map=:
{{#invoke:template wrapper|{{#if:{{{_debug|}}}|list|wrap}}|_template=citation |_exclude=..., _debug <!-- rincian yang tidak perlu diabaikan --> |_alias-map=1:title, 2:author, 3:language
Contoh ini menggunakan parameter posisional dan mengatur |_debug=yes untuk menunjukkan bahwa templat {{citation}} telah dibentuk dengan benar:
{{cite wikisource|Sentido y sensibilidad|Jane Austen|es|_debug=yes}}- Jane Austen (dalam bahasa bahasa Spanyol).
Sentido y sensibilidad. Wikisource.
- Jane Austen (dalam bahasa bahasa Spanyol).
dan, dengan |_debug= yang dikosongkan:
{{cite wikisource|Sentido y sensibilidad|Jane Austen|es|_debug=}}- Jane Austen (dalam bahasa bahasa Spanyol).
Sentido y sensibilidad. Wikisource.
- Jane Austen (dalam bahasa bahasa Spanyol).
Nama |_debug= dipilih di sini demi kemudahan, tetapi dapat berupa apa saja selama cocok dengan {{#if:}} dalam {{#invoke:}}.
Anda juga dapat memanggil fungsi link untuk mendapatkan tampilan seperti sisi kiri Template:yy. Ini pada dasarnya adalah fungsi list dengan nama templat yang diubah menjadi pranala.
{{Pengguna di Selandia Baru
|
Galat Lua: expandTemplate: template "Pengguna di Selandia Baru" does not exist. | linked pages
|
require('strict');
local error_msg = '<span style=\"font-size:100%\" class=\"error\"><code style=\"color:inherit; border:inherit; padding:inherit;\">|_template=</code> missing or empty</span>';
--[[--------------------------< I S _ I N _ T A B L E >--------------------------------------------------------
scan through tbl looking for value; return true if found, false else
]]
local function is_in_table (tbl, value)
for k, v in pairs (tbl) do
if v == value then return true end
end
return false;
end
--[[--------------------------< A D D _ P A R A M E T E R >----------------------------------------------------
adds parameter name and its value to args table according to the state of boolean list argument; kv pair for
template execution; k=v string for template listing.
]]
local function add_parameter (k, v, args, list)
if list then
table.insert( args, table.concat ({k, '=', v})); -- write parameter names and values to args table as string
else
args[k] = v; -- copy parameters to args table
end
end
--[[--------------------------< A L I A S _ M A P _ G E T >----------------------------------------------------
returns a table of local template (parent frame) parameter names and the target template names that match where
in [key]=<value> pairs where:
[key] is local template parameter name (an alias)
<value> is target template parameter name (the canonical parameter name used in the working template)
The parameter |_alias-map= has the form:
|_alias-map=<list>
where <list> is a comma-separated list of alias / canonical parameter name pairs in the form
<from> : <to>
where:
<from> is the local template's parameter name (alias)
<to> is the target template's parameter name (canonical)
for enumerated parameters place an octothorp (#) where the enumerator digits are placed in the parameter names:
<from#> : <to#>
]]
local function alias_map_get (_alias_map)
local T = mw.text.split (_alias_map, '%s*,%s*'); -- convert the comma-separated list into a table of alias pairs
local mapped_aliases = {}; -- mapped aliases will go here
local l_name, t_name; -- parameter names
for _, alias_pair in ipairs (T) do -- loop through the table of alias pairs
l_name, t_name = alias_pair:match ('(.-)%s*:%s*(.+)'); -- from each pair, get local and target parameter names
if l_name and t_name then -- if both are set
if tonumber (l_name) then
l_name = tonumber (l_name); -- convert number-as-text to a number
end
mapped_aliases[l_name] = t_name; -- add them to the map table
end
end
return mapped_aliases;
end
--[[--------------------------< F R A M E _ A R G S _ G E T >--------------------------------------------------
Fetch the wrapper template's 'default' and control parameters; adds default parameters to args
returns content of |_template= parameter (name of the working template); nil else
]]
local function frame_args_get (frame_args, args, list)
local template;
for k, v in pairs (frame_args) do -- here we get the wrapper template's 'default' parameters
if 'string' == type (k) and (v and ('' ~= v)) then -- do not pass along positional or empty parameters
if '_template' == k then
template = v; -- save the name of template that we are wrapping
elseif '_exclude' ~= k and '_reuse' ~= k and '_include-positional' ~= k and '_alias-map' ~= k then -- these already handled so ignore here;
add_parameter (k, v, args, list); -- add all other parameters to args in the style dictated by list
end
end
end
return template; -- return contents of |_template= parameter
end
--[=[--------------------------< P F R A M E _ A R G S _ G E T >------------------------------------------------
Fetches the wrapper template's 'live' parameters; adds live parameters that aren't members of the exclude table to
args table; positional parameters may not be excluded
no return value
]=]
local function pframe_args_get (pframe_args, args, exclude, _include_positional, list)
for k, v in pairs (pframe_args) do
if 'string' == type (k) and not is_in_table (exclude, k) then -- do not pass along excluded parameters
if v and ('' ~= v) then -- pass along only those parameters that have assigned values
if 'unset' == v:lower() then -- special keyword to unset 'default' parameters set in the wrapper template
v = ''; -- unset the value in the args table
end
add_parameter (k, v, args, list) -- add all other parameters to args in the style dictated by list; alias map only supported for local-template parameters
end
end
end
if _include_positional then
for i, v in ipairs (pframe_args) do -- pass along positional parameters
if 'unset' == v:lower() then -- special keyword to unset 'default' parameters set in the wrapper template
v = ''; -- unset the value in the args table
end
add_parameter (i, v, args, list);
end
end
end
--[[--------------------------< _ M A I N >--------------------------------------------------------------------
Collect the various default and live parameters into args styled according to boolean list.
returns name of the working or listed template or nil for an error message
]]
local function _main (frame, args, list)
local template;
local exclude = {}; -- table of parameter names for parameters that are not passed to the working template
local reuse_list = {}; -- table of pframe parameter names whose values are modified before they are passed to the working template as the same name
local alias_map = {}; -- table that maps parameter aliases to working template canonical parameter names
local _include_positional;
if frame.args._exclude and ('' ~= frame.args._exclude) then -- if there is |_exclude= and it's not empty
exclude = mw.text.split (frame.args._exclude, "%s*,%s*"); -- make a table from its contents
end
-- TODO: |_reuse= needs a better name (|_reuse=)
if frame.args._reuse and ('' ~= frame.args._reuse) then -- if there is |_reuse= and it's not empty
reuse_list = mw.text.split (frame.args._reuse, "%s*,%s*"); -- make a table from its contents
end
if frame.args['_alias-map'] and ('' ~= frame.args['_alias-map']) then -- if there is |_alias-map= and it's not empty
alias_map = alias_map_get (frame.args['_alias-map']); -- make a table from its contents
end
template = frame_args_get (frame.args, args, list); -- get parameters provided in the {{#invoke:template wrapper|...|...}}
if nil == template or '' == template then -- this is the one parameter that is required by this module
return nil; -- not present, tell calling function to emit an error message
end
_include_positional = 'yes' == frame.args['_include-positional']; -- when true pass all positional parameters along with non-excluded named parameters to ...
-- ... the working template; positional parameters are not excludable
local _pframe_args = frame:getParent().args; -- here we get the wrapper template's 'live' parameters from pframe.args
local pframe_args = {}; -- a local table that we can modify
for k, v in pairs (_pframe_args) do -- make a copy that we can modify
pframe_args[k] = v;
end
-- here we look for pframe parameters that are aliases of canonical parameter names; when found
-- we replace the alias with the canonical. We do this here because the reuse_list works on
-- canonical parameter names so first we convert alias parameter names to canonical names and then
-- we remove those canonical names from the pframe table that are reused (provided to the working
-- template through the frame args table)
for k, v in pairs (alias_map) do -- k is alias name, v is canonical name
if pframe_args[k] then -- if pframe_args has parameter with alias name
pframe_args[v] = _pframe_args[k]; -- create new canonical name with alias' value
pframe_args[k] = nil; -- unset the alias
end
end
for k, v in pairs (pframe_args) do -- do enumerated parameter alias -> canonical translation
if 'string' == type (k) then -- only named parameters can be enumerated
if alias_map[k..'#'] then -- non-enumerated alias matches enumerated parameter pattern? enumerator at end only
pframe_args[alias_map[k..'#']:gsub('#', '')] = v; -- remove '#' and copy parameter to pframe_args table
pframe_args[k] = nil; -- unset the alias
elseif k:match ('%d+') then -- if this parameter name contains digits
local temp = k:gsub ('%d+', '#'); -- make a copy; digits replaced with single '#'
local enum = k:match ('%d+'); -- get the enumerator
if alias_map[temp] then -- if this parameter is a recognized enumerated alias
pframe_args[alias_map[temp]:gsub('#', enum)] = v; -- use canonical name and replace '#' with enumerator and add to pframe_args
pframe_args[k] = nil; -- unset the alias
end
end
end
end
-- pframe parameters that are _reused are 'reused' have the form something like this:
-- |chapter=[[wikisource:{{{chapter}}}|{{{chapter}}}]]
-- where a parameter in the wrapping template is modified and then passed to the working template
-- using the same parameter name (in this example |chapter=)
-- remove parameters that will be reused
for k, v in ipairs (reuse_list) do -- k is numerical index, v is canonical parameter name to ignore
if pframe_args[v] then -- if pframe_args has parameter that should be ignored
pframe_args[v] = nil; -- unset the ignored parameter
end
end
pframe_args_get (pframe_args, args, exclude, _include_positional, list); -- add parameters and values to args that are not listed in the exclude table
return template; -- args now has all default and live parameters, return working template name
end
--[[--------------------------< W R A P >----------------------------------------------------------------------
Template entry point. Call this function to 'execute' the working template
]]
local function wrap (frame)
local args = {}; -- table of default and live parameters and their values to be passed to the wrapped template
local template; -- the name of the working template
template = _main (frame, args, false); -- get default and live parameters and the name of the working template
if not template then -- template name is required
return error_msg; -- emit error message and abandon if template name not present
end
return frame:expandTemplate {title=template, args=args}; -- render the working template
end
--[[--------------------------< L I S T >----------------------------------------------------------------------
Template entry point. Call this function to 'display' the source for the working template. This function added
as a result of a TfD here: Wikipedia:Templates_for_discussion/Log/2018_April_28#Module:PassArguments
This function replaces a similarly named function which was used in {{cite compare}} and {{cite compare2}}
Values in the args table are numerically indexed strings in the form 'name=value'
]]
local function list(frame, do_link)
local args = {}; -- table of default and live parameters and their values to be passed to the listed template
local template; -- the name of the listed template
template = _main (frame, args, true); -- get default and live parameters and the name of the listed template
if not template then -- template name is required
return error_msg; -- emit error message and abandon if template name not present
end
if do_link then
template = ('[[%s|%s]]'):format(frame:expandTemplate{ title='Transclude', args = {template} }, template)
end
table.sort(args)
for i = 1, #args do
local stripped = args[i]:match('^' .. i .. '=([^=]*)$')
if stripped then args[i] = stripped else break end
end
return frame:preprocess(table.concat({
'<code style="color:inherit; background:inherit; border:none;">{{',
template,
('<wbr><nowiki>|%s</nowiki>'):rep(#args):format(unpack(args)), '}}</code>'})); -- render the template
end
local function link (frame)
return list(frame, true)
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
link = link,
list = list,
wrap = wrap,
};