Purpose +/-

This module protects templates and modules from being wrongly substituted.

Usage +/-

First, put the following at the beginning of the entry_point function in the module:

if mw.isSubsting() then
	return require('Module:unsubst').unsubst_template("entry_point")
end

Where "entry_point" should be replaced with the function name. Next, edit the template:

{{safesubst:<noinclude/>#invoke:...|entry_point|...}}

The <noinclude/> is optional. The template will substitute into its transcluded form.

To protect the module itself instead of the template, add this at the start of the function instead:

if mw.isSubsting() then
	return require('Module:unsubst').unsubst_module("entry_point")
end

Directly in templates +/-

You can wrap the template code in

{{safesubst:#invoke:unsubst|me|=
...
}}

It will work just like unsubst_template above, apart from also generating a transclusion to Module:unsubst. Additionally, it protects templates from being copied and pasted to non-template pages.


local export = {}

local function serialise_frame(title, args)
	local result = { "{{", title }
	
	for i, value in ipairs(args) do
		if value:find("=") then
			value = i .. "=" .. value
		end
		table.insert(result, "|" .. value)
	end
	
	for key, value in pairs(args) do
		if type(key) == "string" then
			table.insert(result, "|" .. key .. "=" .. value)
		end
	end
	
	table.insert(result, "}}")
	return table.concat(result)
end

function export.unsubst_module(entry_point)
	local frame = mw.getCurrentFrame()
	return serialise_frame(
		((parent:getTitle() == mw.title.getCurrentTitle().fullText) and 'safesubst:' or '') ..
		'#invoke:' .. frame:getTitle():gsub('^Module:', '') .. '|' .. entry_point, frame.args	
	)
end

function export.unsubst_template(entry_point)
	local frame = mw.getCurrentFrame()
	local parent = frame:getParent()
	if parent:getTitle() == mw.title.getCurrentTitle().fullText then
		return serialise_frame('safesubst:#invoke:' .. frame:getTitle():gsub('^Module:', '') .. '|' .. entry_point, frame.args)
	end
	return serialise_frame(parent:getTitle():gsub('^Template:', ''), parent.args)
end

-- invokables

function export.me(frame)
	local parent = frame:getParent()

	if mw.isSubsting() then
		return export.unsubst_template('me')
	end

	-- "manual substitution"?
	if not frame.args.nocheck then
		if (frame ~= parent) and not parent:getTitle():find("^Template:") then
			return '<strong class="error">It appears that you have copied template code from a template page. ' ..
				'You should transclude the template instead, by putting its name in curly brackets, like so: ' ..
				'<code>{{template-name}}</code>.</strong>' -- XXX: maintenance category?
		end
	end

	return frame.args['']
end

return export

-- {{documentatio}} --