Module:unsubst
- The following documentation is located at Module:unsubst/documentation. [edit]
- Useful links: subpage list • links • transclusions • testcases • sandbox
This module protects templates and modules from being wrongly substituted.
Usage
There are two ways to use this module:
- Protecting all templates in a module
First, put the following at the top of a module which contains functions designed to be called by {{#invoke:}}
:
-- Prevent substitution.
if mw.isSubsting() then
return require("Module:unsubst")
end
Second, edit each template which calls that module from:
to:
{{safesubst:
<noinclude/>
#invoke:...|function|...}}
Note: this should only be used with modules that only return functions which are designed to be called by templates (not by other modules). If your module also returns functions (or other data) designed to be called by other modules, then the safest solution is to separate out the template functions into a separate module, usually in the format Module:.../templates
(e.g. Module:links/templates). This is because unsubst prevents any functions or data in a module from being accessed during substitution, which will disrupt other modules which need to access your module while they are being substituted.
- In templates
{{safesubst:<noinclude/>
#invoke:unsubst|me|=
...
}}
local m_template_parser = require("Module:template parser")
local build_template = m_template_parser.buildTemplate
local concat = table.concat
local get_template_invocation_name = m_template_parser.getTemplateInvocationName
local is_valid_title = require("Module:pages").is_valid_title
local new_title = mw.title.new
local is_substing = mw.isSubsting()
local function unsubst_me(frame)
return frame.args[""]
end
local function get_title(frame)
local title = new_title(frame:getTitle())
return is_valid_title(title) and title or
-- This shouldn't happen.
error("frame returned an invalid title")
end
local function serialize(title, args)
return "{{" .. concat(build_template(title, args), "|") .. "}}"
end
local mt = {}
function mt:__index(entry_point)
-- Cannot unsubst if not currently being substed.
if not is_substing then
local frame_title = mw.getCurrentFrame():getTitle()
if frame_title ~= "Module:unsubst" then
error(("[[%s]] should not call [[Module:unsubst]] unless mw.isSubsting() returns true"):format(frame_title))
end
-- Allow {{#invoke:unsubst|me|=...}}, but otherwise return nothing.
return entry_point == "me" and unsubst_me or nil
end
return function(frame)
local parent = frame:getParent()
if parent:getTitle() ~= mw.title.getCurrentTitle().fullText then
return serialize(get_template_invocation_name(get_title(parent)), parent.args)
end
local title = get_title(frame)
return title.namespace == 828 and
(serialize(("safesubst:<noinclude/>#invoke:%s|%s"):format(title.text, entry_point), frame.args)) or
-- This shouldn't happen.
error(("[[Module:unsubst]] cannot work if the current frame is not in the %s namespace, because the #invoke magic word requires it"):format(mw.site.namespaces[828].canonicalName))
end
end
return setmetatable({}, mt)