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 {{Navbox}} displaying as a link reading

— 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 = "&#124;"
	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('*') .. '&nbsp;' .. 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