Module:Template link renders a template's name as a clickable, brace-wrapped, formatted example — the engine behind {{Tlg}} and the family of "template link" templates.
Overview
When documentation needs to show a template by name — like displaying as a link reading {{Navbox}}
— this module builds that text. It takes a template name plus optional sample parameters and produces a link to the template wrapped in literal {{ }} braces (using nowiki so they don't actually transclude). Many display options control bolding, italics, styling, whether to show braces, and so on.
This implements {{Tlg}} ("template link general"); the many short aliases ({{tl}}, {{tlx}}, etc.) are thin wrappers around it. The wiki page for this module is just a redirect to Wikipedia's documentation for Module:Template link general, since this is essentially that well-known module.
Editors use the template-link templates ({{tl}}, {{Tlg}}, …), not the module directly.
Functions / entry points
Function (#invoke)
What it does
Called by
p.main
Collects arguments (via {{ArgsUtil}}m's merge) and hands them to p._main. The normal entry point.
{{Tlg}} / {{tl}} and related template-link templates
p._main
Does the actual work: builds the link to the named template, appends any sample parameters (separated by escaped pipes), and applies the requested formatting flags (bold, italic, code, braces, nowrap, etc.). Returns the finished wikitext. Can also show the expanded result or a link to Special:ExpandTemplates.
p.main (and Lua callers that already have an args table)
How it's used
Editors write one of the template-link templates, e.g.:
{{tl|Navbox}} → {{Navbox}}
{{tl|Sound|MyFile.ogg}} → {{Sound|MyFile.ogg}}
Those templates are built on {{...}}. The first positional argument is the template name; positional arguments 2+ are shown as sample parameters; named options control the look.
Common options (all optional, presence-only flags unless noted):
bold / italic — bold the link / italicise the sample params.
code or tt — wrap in ; plaincode for borderless code; kbd for .
nolink — show the name as plain text, not a link.
brace / braceinside — show extra literal braces.
nowiki — treat sample params as literal text.
subst — prefix the shown name with subst:.
alttext — override the displayed link text.
nowrap / nowrapname — prevent line wrapping.
_show_result — also expand the template and show its output after a "→".
_expand — append a link to Special:ExpandTemplates for the call.
debug — dump the parsed args.
Ordinary editors should use {{tl}} / {{Tlg}} and the other wrappers; they rarely need raw #invoke.
Notes
- Namespace handling. A bare name is treated as a
Template: page. A name containing a colon is checked against known namespaces: a real namespace prefix is kept as-is, otherwise it's still treated as a template title. A leading colon / other-namespace title is handled via mw.title.new(name, 'Template').
- Braces are literal. The surrounding
{{ }} and the pipes between sample parameters are produced with mw.text.nowiki so the displayed example does not actually transclude or break the page.
- Depends on
{{ArgsUtil}}m for argument collection (require('Module:ArgsUtil').merge).
- Origin. This is the Wikipedia "Template link general" module; the on-wiki doc is a
{{From Wikipedia}} redirect to that module's documentation, so the full option reference there applies.
- Related:
{{Tlg}}, {{tl}} and the other template-link wrappers, {{ArgsUtil}}m.
-- This implements Template:Tlg
local getArgs = require('Module:ArgsUtil').merge
local p = {}
-- Is a string non-empty?
local function _ne(s)
return s ~= nil and s ~= ""
end
local nw = mw.text.nowiki
local function addTemplate(s)
local i, _ = s:find(':', 1, true)
if i == nil then
return 'Template:' .. s
end
local ns = s:sub(1, i - 1)
if ns == '' or mw.site.namespaces[ns] then
return s
else
return 'Template:' .. s
end
end
local function trimTemplate(s)
local needle = 'template:'
if s:sub(1, needle:len()):lower() == needle then
return s:sub(needle:len() + 1)
else
return s
end
end
local function linkTitle(args)
if _ne(args.nolink) then
return args[1]
end
local titleObj
local titlePart = '[['
if args[1] then
-- This handles :Page and other NS
titleObj = mw.title.new(args[1], 'Template')
else
titleObj = mw.title.getCurrentTitle()
end
titlePart = titlePart .. (titleObj ~= nil and titleObj.fullText or
addTemplate(args[1]))
local textPart = args.alttext
if not _ne(textPart) then
if titleObj ~= nil then
textPart = titleObj:inNamespace("Template") and args[1] or titleObj.fullText
else
-- redlink
textPart = args[1]
end
end
if _ne(args.subst) then
-- HACK: the ns thing above is probably broken
textPart = 'subst:' .. textPart
end
if _ne(args.brace) then
textPart = nw('{{') .. textPart .. nw('}}')
elseif _ne(args.braceinside) then
textPart = nw('{') .. textPart .. nw('}')
end
titlePart = titlePart .. '|' .. textPart .. ']]'
if _ne(args.braceinside) then
titlePart = nw('{') .. titlePart .. nw('}')
end
return titlePart
end
function p.main(frame)
local args = getArgs()
return p._main(args)
end
function p._main(args)
local bold = _ne(args.bold) or _ne(args.boldlink) or _ne(args.boldname)
local italic = _ne(args.italic) or _ne(args.italics)
local dontBrace = _ne(args.brace) or _ne(args.braceinside)
local code = _ne(args.code) or _ne(args.tt)
local show_result = _ne(args._show_result)
local expand = _ne(args._expand)
-- Build the link part
local titlePart = linkTitle(args)
if bold then titlePart = "'''" .. titlePart .. "'''" end
if _ne(args.nowrapname) then titlePart = '<span class="nowrap">' .. titlePart .. '</span>' end
-- Build the arguments
local textPart = ""
local textPartBuffer = "|"
local codeArguments = {}
local codeArgumentsString = ""
local i = 2
local j = 1
while args[i] do
local val = args[i]
if val ~= "" then
if _ne(args.nowiki) then
-- Unstrip nowiki tags first because calling nw on something that already contains nowiki tags will
-- mangle the nowiki strip marker and result in literal UNIQ...QINU showing up
val = nw(mw.text.unstripNoWiki(val))
end
local k, v = string.match(val, "(.*)=(.*)")
if not k then
codeArguments[j] = val
j = j + 1
else
codeArguments[k] = v
end
codeArgumentsString = codeArgumentsString .. textPartBuffer .. val
if italic then
val = '<span style="font-style:italic;">' .. val .. '</span>'
end
textPart = textPart .. textPartBuffer .. val
end
i = i + 1
end
-- final wrap
local ret = titlePart .. textPart
if not dontBrace then ret = nw('{{') .. ret .. nw('}}') end
if _ne(args.a) then ret = nw('*') .. ' ' .. ret end
if _ne(args.kbd) then ret = '<kbd>' .. ret .. '</kbd>' end
if code then
ret = '<code>' .. ret .. '</code>'
elseif _ne(args.plaincode) then
ret = '<code style="border:none;background:transparent;">' .. ret .. '</code>'
end
if _ne(args.nowrap) then ret = '<span class="nowrap">' .. ret .. '</span>' end
--[[ Wrap as html??
local span = mw.html.create('span')
span:wikitext(ret)
--]]
if _ne(args.debug) then ret = ret .. '\n<pre>' .. mw.text.encode(mw.dumpObject(args)) .. '</pre>' end
if show_result then
local result = mw.getCurrentFrame():expandTemplate{title = addTemplate(args[1]), args = codeArguments}
ret = ret .. " → " .. result
end
if expand then
local query = mw.text.encode('{{' .. addTemplate(args[1]) .. string.gsub(codeArgumentsString, textPartBuffer, "|") .. '}}')
local url = mw.uri.fullUrl('special:ExpandTemplates', 'wpInput=' .. query)
mw.log()
ret = ret .. " [" .. tostring(url) .. "]"
end
return ret
end
return p