Help:Substitution
This help page is a how-to guide. It explains concepts or processes used by the Wikipedia community. It is not one of Wikipedia's policies or guidelines, and may reflect varying levels of consensus. |
Substitution is a way of handling templates, magic words, variables, parser functions, and other Wikipedia pages that differs from transclusion.
Definition
[edit]Ordinarily, templates will be transcluded, which means that their content is always retrieved directly from the most recent version of the template. This is advantageous because, if the template's page is changed, every other page that uses that template will display the updated content. In this case, when someone is editing a page that transcludes a template, they only see the {{template call}} and not the underlying code. This procedure is used for most templates, to avoid having to manually keep pages up-to-date individually.
However, some templates should always be substituted. This means that, once an editor places the template on a page and publishes their edit, the entire content of the template in the moment it is substituted will be hard-coded into the page, along with any parameters passed to it, as if the editor had manually copied the code and pasted it. Since the substituted content is now an integral part of the page, it can now be modified without affecting other pages or the parent template itself. However, if the template is changed in the future, the pages that have already substituted it will not be affected, because there is no longer a connection between them and the substituted template.
Usage
[edit]To transclude a template, its name is simply enclosed in double curly braces, as in: {{Cleanup}}. Instead, to substitute a template, the string subst: is added after the opening braces, as in {{subst:Cleanup}}. The contents of {{Cleanup}} will then be inserted ("expanded") in the location where the template call is placed in the page. Parameters can be included as in the case of transclusion, for example {{subst:Cleanup|reason=Incorrect capitalization}}. Before saving, you can check the resulting wikitext, which differs from what you see in the editor, by clicking "Show changes".
Pages not in the template namespace can also be substituted, e.g. {{subst:User:Cleverclogs/My box}}. To substitute the current content of a page in mainspace (i.e. one with no namespace prefix), two colons are required, as in {{subst::Page}}. If a substituted page or template does not exist, the entire expression (with braces and subst:) will remain unchanged in the wikitext and on the page.
Use the same syntax to substitute variables and parser functions, e.g. {{subst:PAGENAME}} or {{subst:#switch:{{NUMBEROFADMINS}}|1=Foo|1000=Bar|#default=Baz}}. There may be white space between the opening braces and the "subst:". However it is recommended not to have any space or newlines immediately after the "subst:", as this will not work in every case.
Benefits and drawbacks
[edit]Documenting substitution
[edit]Usage of a template through subst: does not automatically show up in page histories. Therefore, it is strongly suggested that the template be mentioned in the edit summary so other editors can easily understand your edits. (For instance, include "Substituted [[Template:Cleanup]]" or "{{subst:Cleanup}}".) If you don't, they might think you wrote the entire template code yourself.
HTML comments outside noinclude tags are included in the substituted wikitext, so a comment can be used to mention the template, and then find it again later. See any of the user warning templates, which all use this approach. Template {{uw-coi}}, for example, places the comment onto the page where it is substituted, thus enabling searching for that comment as a proxy for searching for substitutions of the template. The § Notes section of the template's documentation provides a search link based on this technique.
If you are creating or editing templates that are commonly substituted, you can add a hidden comment to the template so that other editors know which templates was substituted (e.g. <!-- Template:Cleanup -->). Use {{subst:HTML comment}} if you want to write HTML comments that contain wikitext expansions.
Substitution of parameters does not work inside comments, but a workaround for this is to begin an intended comment with <!<noinclude />-- so that it turns into a comment once transcluded.
Technical implementation
[edit]The template code on a page calls a separate page every time it needs to be displayed. Although most page views are served from the cache, pages need to be rendered for previews and rendered again when the page changes.
Variables and parser functions can also be substituted, meaning that their current value will be recorded permanently on the page – they will not be re-evaluated whenever someone views the page. Time-dependent variables are substituted to make the rendered page independent of the time at which it is viewed. Substituting page-dependent variables makes the resulting wikitext independent of renaming of the page and of copying to another page. Some things may appear to be templates but are actually magic words, such as {{!}} and {{noexternallanglinks}}. Substituting them either will output nothing, or will substitute a template that shadows them, such as the deprecated {{!}} template.
Substitution is part of the process performed on saving a page, and causes the wikitext saved as a result of the edit to differ from the text which the user actually entered in the edit window. Similar replacements performed during this process include expansion of links using the pipe trick and replacement of multiple tildes with signatures and timestamps.
This means that substitution necessarily occurs before any actions performed at the time of page rendering (conversion of the stored wikitext to HTML). In particular, substitutions are done before transclusions. So typing {{subst:Help:L{{in(tut)}}k}} will not do substitution, even though {{in(tut)}} returns the text "in" and Help:Link exists. The transclusion of {{in(tut)}} has not yet taken place when the substitution is attempted. However, replace {{in(tut)}} with {{subst:in(tut)}}, and both substitutions will be performed in the expected order.
Similarly:
- Typing
{{subst:#if:{{x0}}|yes|no}}gives the wikitext "yes", even though {{x0}} is an empty template, since the conditional parameter evaluates to the non-empty string "{{x0}}". However{{subst:#if:{{subst:x0}}|yes|no}}produces "no", since the inner substitution is performed first. - Typing
{{subst:#expr:2*{{{p|3}}}}}returns Expression error: unrecognised punctuation character "{", as the undefined parameter {{{p}}} has not been replaced by its default value (3) when the substitution occurs. - If {{t6}} contains the text "t2|a", then
{{ {{subst:t6}} }}will produce the wikitext "{{ t2|a }}", rendered as "[[w:List of people by name: a{{{2}}}|a{{{2}}}]]" Contrast this with the behaviour of{{ {{t6}} }}, which is rendered as "{{ t2|a }}", because the parser does not reinterpret the pipe as a separator during the non-substituted expansion stage. (Similarly,{{subst:{{subst:t6}} }}gives the wikitext{{subst:t2|a }}, which only on the next edit will be substituted with [[w:List of people by name: a{{{2}}}|a{{{2}}}]].)
Clicking the "Show changes" button during editing shows the wikitext that will result after substitution and other immediate replacements are carried out. Clicking "Show preview" shows what the rendered page will look like after these replacements.
Note also that if instances of the subst: syntax appear in a template that is being transcluded, then they will be rendered unchanged (as "{{subst:...}}"), since no substitution in wikitext is possible at the rendering stage. This feature can be exploited to control template behaviour (see § Making templates behave differently when transcluded or substituted). However, it may be inconvenient when a template is designed to be possible to transclude as well as substitute – in this case safesubst: can be used instead of subst:.
The safesubst: modifier
[edit]The subst: modifier can be replaced by the alternative modifier safesubst:. The two have the same behaviour, except when they are encountered during non-substituted expansion (transclusion or direct viewing) of a template. In such a situation, the code {{subst:...}} remains unparsed, whereas the {{safesubst:...}} is treated as if no modifier were present – and so the subtemplate is transcluded or the variable or parser function evaluated.
Hence the safesubst: modifier is used in the code of templates which are designed to produce recursive substitution when substituted; but that are also intended to work when transcluded or simply to be viewed directly. Contrasted with using the subst: modifier, such templates would break in such cases of transclusion (and possibly on direct viewing).
Limitation
[edit]Substitution is not available inside <ref>...</ref> and <gallery>...</gallery> tags. If you write {{subst:foo}}, it is not substituted nor transcluded, but remains as-is (it's a known bug, see T4700 and gerrit:272916 for current status).
However it is possible to bypass this limitation by using the magic word #tag. If you write, for instance, {{safesubst:#tag:ref|content of the reference}}, the content of the reference will be substituted and the {{#tag:ref|...}} will be replaced with <ref>...</ref>. A more concrete example: If you write for instance {{safesubst:#tag:ref|...Title=ExampleTitle|archivedate={{subst:TODAY}}|Edition=Hardcover...}} then the software will perform substitutions on the text within the last field and the {{#tag:ref|...}} will be replaced with <ref>...</ref>around the altered text, and the reference will be saved with the substitution; it'll be saved as "{{|...Title=ExampleTitle|archivedate=29 January 2016|Edition=Hardcover|...}}" with <ref>...</ref> around it. In other words, first the software will expand the templates and then place that expanded text within reference tags.
Recursive substitution
[edit]If a page substitutes itself (e.g. in the noinclude part of a template page) it substitutes the old version, as it was before the current edit. If the expansion of a substituted template itself contains instances of the subst: syntax, then the substitutions are performed recursively. However, substitution is not automatically recursive – if a substituted template contains ordinary transclusions or variables and parser functions which are not explicitly substituted, then these will not be substituted.
To make substitution work recursively, you must include the subst: syntax in the code of the calling template. However, you cannot do this by simply typing "subst:" within the template, as the substitution would then be performed as soon as the template is saved. There are two ways to work around this problem:
- Use
subst:<noinclude />in place of plainsubst:. The noinclude tag breaks up the substitution syntax when the template is saved, but will be stripped away when it is later substituted, allowing the inner substitution to take effect. Alternatively, a larger part of the template code can be wrapped in<onlyinclude>...</onlyinclude>. Then the wrapped code is ignored on the template page itself but not when it is transcluded. - Make "subst:" the possible value of an expression containing a parameter, such as
{{{subst-foo|subst:}}}, which will evaluate to "subst:" provided the parameter subst-foo is not set. This is a more flexible solution, as it allows the behaviour to be controlled via the parameter. For example, such a template might be called using{{subst:Templatename|subst-foo=|...}}, assigning the parameter an empty value and thus turning off the second level of substitution. If it is not planned to use the parameter, the parameter name is often chosen to be the empty string, giving{{{|subst:}}}, but this can have unexpected results if a value is assigned to the empty string parameter (e.g.{{Templatename|=foo}}).
To ensure that the template will still work as intended if it is transcluded instead of substituted, use safesubst: instead of subst:. This also applies if the template is also to be viewed directly, on its own page (although in this case, if the first of the above methods is used, plain subst: will still work, as the includeonly tags will cause the parser to ignore the subst: on direct viewing).
To see what a template will produce when fully expanded, without the need to explicitly substitute all subtemplates etc., the Special:ExpandTemplates tool can be used.
For more information, see the Recursive conversion of wikitext help page at Meta. See also Help:Calculation § Substitution, m:Template:Example table with computations, with optional substitution (backlinks edit), and the feature request at substall.
Recursive substitution in guided tours
[edit]Guided tours can make posts on behalf of users, such as automatically posting the contents of a wiki page onto a talk page. Unlike normal substitution or transclusion, however, this function of guided tours does not respect <includeonly>...</includeonly> and similar markup. To make recursive substitution work via guided tour posting, you can use the method for delaying substitution with Template:subst.
Example of recursive substitution
[edit]This is an example using the actual Template:Like, and a hypothetical Template:Foo. You are attempting to include the Template:Foo, and indirectly the Template:Like, on a third page through transclusion and substitution. Template:Like displays this symbol:
Like
For example, let's say the Template:Foo contained the wikitext {{Like}}. If you then transclude it, using the wikitext {{Foo}}, this will transclude the Template:Like as you would expect. But if you use the wikitext {{subst:Foo}}, when you save it, you find the wikitext {{Like}} substituted rather than the wikitext of the page Template:Like. The substitution has not been recursive.
An example of recursion would be if the Template:Foo contained the wikitext {{{{{|safesubst:}}}Like}}. Now if you transclude it, using the wikitext {{Foo}}, this will transclude the Template:Like just as before. And if you save {{subst:Foo}} it will substitute the full actual wikitext of the Template:Like. You have therefore achieved recursive substitution.
| Wikitext of Template:Foo | When you view Template:Foo, it looks like: |
The result of {{Foo}} if included on this page |
The result of {{subst:Foo}} if included on this page | ||
|---|---|---|---|---|---|
| saves as: | renders as: | saves as: | renders as: | ||
{{!}}
{{PAGENAME}}
{{#if: 1 | yes | no}}
|
|
Foo yes |
{{Foo}}
|
|
Substitution yes |
{{!}}
{{PAGENAME}}
{{#if: 1 | yes | no}}
|
|
Substitution yes |
{{{{{|subst:}}}!}}
{{{{{|subst:}}}PAGENAME}}
{{{{{|subst:}}}#if: 1 | yes | no}}
|
{{subst:!}}
{{subst:PAGENAME}} {{subst:#if: 1 | yes | no}} |
{{Foo}}
|
{{subst:!}}
{{subst:PAGENAME}} {{subst:#if: 1 | yes | no}} |
| Substitution yes |
|
Substitution yes |
{{{{{|safesubst:}}}!}}
{{{{{|safesubst:}}}PAGENAME}}
{{{{{|safesubst:}}}#if: 1 | yes | no}}
|
|
Foo yes |
{{Foo}}
|
|
Substitution yes |
| Substitution yes |
|
Substitution yes |
Making templates behave differently when transcluded or substituted
[edit]Sometimes it is desirable to make a template behave differently when substituted rather than when transcluded. A common trick for doing this is to use an expression like {{{{{subst|subst:}}}ns:0}}. This evaluates to the empty string if the template is being substituted (since the inner substitution takes effect, giving the prefix of namespace 0, which is empty), but to "{{subst:ns:0}}" if the template is being transcluded (since substitution cannot take place after transclusion).
A common application is in templates which are designed only to be substituted, to make them produce a warning if they are mistakenly transcluded instead. This is done in templates like {{prod}}, which are designed to produce a timestamp (e.g. for adding pages to dated categories), and will not be able to do this if transcluded.
A template, {{issubst}}, has been created to simplify this. It returns "yes" if substitution is being performed, or the empty string otherwise. This can then be used as the parameter of a conditional parser function to make the template display a warning method if it is being transcluded, or to otherwise change the behaviour of a template depending on whether it is being transcluded or substituted.
Substitution trick
[edit]Templates can be coded so that they return a cleaned-up copy of themselves upon substitution. This is known as the substitution trick and is especially useful for removing unsupported parameters (which may cause a page to land in a maintenance category) or updating a template to use the current names for parameters instead of their aliases. Module:Unsubst offers a straightforward tool to carry out the subst trick.
A prominent example of a template that can perform the substitution trick is {{Infobox album}} and some of its associated templates like {{Singles}} and {{Extra album cover}}. Other examples include most maintenance templates like {{Citation needed}} and {{Unreferenced}}, which when substituted will generally add the |date= parameter with the month and the year.
See also
[edit]- Help:Transclusion
- Help:Metatemplating § Substitution
- Special:ExpandTemplates, put the template with the
{{curly brackets}}in the "input text" box. - Category:Wikipedia substituted templates, templates that should always be substituted.
- User:AnomieBOT, a bot approved to substitute certain templates.
Sister-projects
[edit]- mw:Help:Substitution, a longer and more technical help page at Mediawiki
- mw:Help:ExpandTemplates
- mw:Help:TemplateData
- phab:T4003: – feature request to allow marking a template as being substituted without "subst:"
- Check Wikipedia § Template programming element on ToolForge helps to find articles substituted rather than transcluded
- Templates containing a call to itself with "subst:" and producing a similar call with updated info, either replacing or adding to the previous info:
- m:Template:last edit (backlinks edit) – example: last edit
- m:Template:page history (backlinks edit)
Templates for substitution
[edit]- {{require subst}} can wrap templates which require subst:
- {{issubst}} - Returns "yes" when substituted.
- {{ifsubst}} - Similar to #if: magic word, judging from substituted or not.