User:Mindrones/Manual:Substitution

Substitution is a function whereby, when an editor saves a page, every expandable item in the wiki code is permanently replaced with its expanded wikitext.

During the next edit, the wikitext won't show the expandable item call anymore, but the rather the expanded wikitext that was contained in the expandable item when you saved the page. The substitute text won't change anymore, even if the expandable wikitext will be edited in the future.

In particular:


 * templates can be substituted, as an alternative to be transcluded. Ordinarily, a template will be expanded "on the fly", so that the template code on a page calls a separate page every time it is rendered. Also, when someone is editing a page with a normal template call, they see the template call itself in the page. When a template is substituted on a page, its substitute text won't be affected by later changes made to the template itself, and the wikitext of the page doesn't contain the template call anymore.
 * parser functions and variables can also be substituted. Their current value will be recorded permanently on the page and they will not be re-evaluated whenever someone views the page.

Terminology on this page

 * expandable
 * a template, a variable, a core parser function/modifier, or a extension parser function ;


 * tplarg
 * a template parameter, possibly specifying a default value

Applications
Substitution may be needed to:


 * Make a page independent:
 * from a template
 * The rendered page does not change when the template is edited.
 * The page can be copied to another MediaWiki installation without copying the template.
 * from time
 * Substituting time-dependent variables makes a rendered page independent of the time
 * from page names
 * Substituting page-dependent variables makes a rendered page independent of renaming of the page and of copying the wikitext to another page.
 * Make a page rendering easier and therefore faster for the server.
 * Although most page views are served from the cache, pages need to be rendered for previews, and rendered again when the page changes.
 * Analyze and demonstrate the working of templates.
 * The relationship between wikitext of a page and its render can become easier to understand after substitution, because one has all wikitext together, and parameter substitutions have been performed.
 * Note that wikitext after substitution is often more complex than when the required wikitext would have been written directly, and in some cases substitution works differently than transclusion)

subst:
Normal substitution is done by adding the modifier  after the double opening braces, without intervening spaces.

safesubst:
The modifier  is explained below, see multilevel substitution.

How to inspect the result of the substitution before saving
To check the resulting wikitext before saving click on "Show changes". If the text covers more than one paragraph the diff page is not very suitable for copying the result because of plus signs in the margin.

Check how the page will look like by clicking "Show preview".

Substitution when parameters don't dependend on other expandable items
Here we explain the basics substitution, that is when the eventual parameters are independent from other expandable items.

Parameters
In the absence of parameters, the template is replaced by its result.

If there are parameters to be sustituted:
 * undefined parameters with default are replaced by their defaults,
 * undefined parameters without default are left as they are in the template wikitext.

and parts
Moreover, template substitution:
 * excludes  parts,
 * removes  parts,

Recursive substitution
Using "subst:" the replacement of a template title by its wikitext does not work recursively.

For full recursive substitution see multilevel substitution below.

Variables
The variable tag is replaced by its result.

Modifiers and parser functions
The tag is replaced by its result.

Substitution when parameters depend on other expandable items
When parameters depend on other expandable items, they have to be substituted too, with a separate  modifier, otherwise the result is undefined.

Templates

 * gives the wikitext startHelpend (see t1)
 * gives the wikitext start12end
 * gives the wikitext startABCDEFend


 * substituting a template containing or  gives 6 if p is not assigned a value, and twice the number p if it is assigned a value.

Variables
In the case of substitution of a predefined template, if the expression for one of its parameters contains with undefined p, this code reduces to 3. However, on the page itself, is treated as such, not as 3.

Modifiers

 * gives IN, the same wikitext as is expanded to; UC: is applied to the output "in" of Tc.
 * gives File.
 * gives the wikitext ABCABCABC
 * gives the wikitext 1e-05 (see LC:)
 * gives (at the time of writing) the wikitext THURSDAY
 * gives wikitext     rendered as.

However:
 * 1)  gives the wikitext   rendered as.
 * 2)  stays , rendered as  (see ns:).

As mentioned before, on substitution, all calls without substitution of templates, variables, and parser functions are treated as plain text. As a result substitution of the outer  in a nested often is only suitable if all inner  are also substituted.

Compare:
 * 2* gives 2*
 * 2* gives 2*
 * gives the wikitext 2* rendered as 2*

and also (from above):
 * gives IN, just like does; UC is applied to the output "in" of Tc.
 * gives the wikitext  rendered as.

In the substitution of UC, the inclusion tag is treated as string just like.

Page substituting itself
If a page substitutes itself (e.g. in the noinclude-part of a template page) it substitutes the old version.

(TODO to be formatted)

Rules for substitution
A save command potentially starts a substitution process which modifies the wikitext before saving. For any substitution to occur, there has to be at least one explicit occurrence of  or   on the page, immediately after the opening braces of a expandable item.

The new wikitext is equal to what the expanded wikitext in transclusion would be, with these rules:


 * an expandable without  or   is not expanded,
 * there are no occurrences of  or   in the expanded wikitext,
 * a tplarg is not expanded to its default on the page itself,
 * a tplarg is expanded to its default in substituted templates,
 * a tplarg is substituted if and only if the page in which it occurs is substituted. This is not the case if a tplarg is on the page itself, because this page is neither substituted nor transcluded.
 * In directly and indirectly substituted templates, again only  s with  or   are expanded.
 * If the substituted title is inside another title it may construct a text  or   causing that other title to be substituted too.
 * A text  or   in a substituted template can also be constructed with a tplarg (be it a parameter value or a default value).
 * A code  or   before a name that is not a valid variable or parser function name, and not the name of an existing template, does not result in substitution, and the prefix is kept in the wikitext.
 * After the substitution process, the new wikitext is expanded as usual for rendering the page.

Partial substitution
Inside an ordinary template one can apply substitution to an ordinary template call containing a parameter, to replace it by the direct wikitext containing the parameter. It amounts to automatically merging the two templates (creating a "composite template" like a composite function). It is not possible if the inner and/or outer template is predefined. (However, manually merging e.g. a call of #expr inside another one is useful for increasing the accuracy of the result by avoiding intermediate rounding to 12 digits.)

This way one can dispense with the optional substitution technique described below, and apply substitution of the resulting outer template by simply using "subst:" (unless there are more nesting levels).

Example:
 * gives the wikitext start--end, just that of , without noinclude parts and includeonly tags
 * ab gives the wikitext start-ab-end

Examples with double substitution:
 * gives the wikitext start--endstart--endstart--endstart--end
 * gives the wikitext start--endstart--endstart--end

Multilevel substitution
When substituting a template it may be desirable to carry out a substitution inside the template too. This can be done with "safesubst:" in the template. To prevent premature substitution (i.e., when the template is saved), and to control whether single- or multilevel substitution is applied, this code is provided as default value of an otherwise unused parameter. Since the empty string is a possible but for other purposes uncommon parameter name, it is usually a suitable choice for the name of this parameter, so we can use the code.

The difference with  is that , evaluating to   if the parameter with the empty string as name is undefined, not only allows multilevel substitution but also multilevel transclusion, because on transclusion it is ignored. With  it is still possible to perform one-level substitution by assigning to the parameter with the empty string as name, the empty string as value, e.g..

Sometimes a template call defines a value of the parameter with the empty string as name, just for inserting this value as comment inside the template tag, or for lay-out of the template tag, see template tag lay-out. When enabling multilevel substitution for such a template, one of the two parameters needs to be given another name.

If the name of the inner template, parser function or variable depends on a parameter without default, then we can simply put, because premature substitution is not possible anyway. However, this does not allow us to control whether single- or multilevel substitution is applied,

Multilevel substitution with independent control of each substitution separately
Parameters subst1, subst2 (or whatever names one chooses) can be used with "safesubst:" and the empty string as possible values. Thus we can control for each template, parser function and variable separately (or group them, and control per group) whether it is substituted too when the outer template is substituted. Either possibilty can be made the default.

Inner templates with parameters may control further inner substitutions in the same way; these parameters may depend on the substitution parameter controlling the substitution of the inner template, since if that is not substituted, inner substitutions within that template are not possible.

For example, if template T uses parameter subst1:
 * with the empty string as default, T calls inner templates and parser functions prefixing their names with ; for calling T we can use:
 * .. (no substitution)
 * .. (one-level substitution)
 * .. (two-level substitution)
 * .. (ditto)
 * with default "safesubst:", T calls inner templates and parser functions prefixing their names with ; for calling T we can use
 * .. (no substitution)
 * .. (one-level substitution)
 * .. (two-level substitution)

To transfer the choice of substituting or not to templates and parser functions called inside the inner templates of T, we can add to the call of these inner templates something of the form subst2= or subst2= , respectively (parser functions and variables don't get the additional parameter).

See also Help:Calculation and.

Partial substitution
Using a template prepared for optional subst=subst: only with ordinary substitution, without specifying parameter values, allows to insert its code into another template, like copy and paste, but all &lt;noinclude&gt; parts and &lt;includeonly&gt; keywords automatically stripped. Executing inserted code instead of calling it may be more efficient for the server.

A typical example for this technique is expanding, within another template, a template used as test expression in a #switch: like : parameter tag case 0 etc. parameter tag  case 0 etc. parameter tag  case 0 etc. something&#125;} suggests that substitution is prevented by discarding "safesubst:" on the page itself, but actually substitution is prevented because the safesubst-syntax is disturbed by the tags.
 * 1) Development code:

It doesn't substitute "something" at the time of the creation of the relevant template, but has the desired effect when the template is substituted.

For examples see "preload" in Extension:InputBox and "substitution" in Help:Variable.

Creating a page which applies substitution on the next save
See Help:Recursive conversion of wikitext.

Forced substitution
Some templates deliberately refuse to work without substitution, for an example see Conv-dist. This technique is essential for templates like prod producing some kind of timestamp, e.g. adding pages to dated categories.


 * The following code in any template T outputs a warning unless recursive substitution with subst=subst: is in effect&#58;
 *  .
 * Output for {&#123;T&#125;} or {&#123;subst:T&#125;}&#58; Warning,
 * output for {&#123;T|subst=subst:&#125;}&#58; ,
 * output for {&#123;subst:T|subst=subst:&#125;}&#58; nothing (no remaining wikitext).


 * This is a rare case where replacing ifdef by #if: doesn't work directly.

Substitution of part of the parameters
Let template A use parameters 1 and 2. Consider creating a template B with one parameter 1, corresponding to A, with a given value q of parameter 2. Pages containing and  are rendered the same, but the second has a parameter  while the first does not. See e.g..

However, with substitution (using "subst:" or Special:Expandtemplates) the resulting wikitext is the same, without distinction between a text and a parameter, it is a parameter anyway, so "1=" is not needed.

If A contains e.g. #expr with an expression containing both parameters the same applies, except that we can only substitute the highest level (A), not the parser function, so we cannot use Special:Expandtemplates.

In general, substituting a parameter and applying a template or parser function sometimes gives the same result as substituting the template or parser function with the triple-braced parameter code and then substituting the parameter.

Without defaults (all rendered the same in one-step substitution as without substitution):

Examples with equality:
 * A template containing pqr substituted with 1=u, 2=v gives puqvr; substituted with 2=v it gives pqvr, which itself, substituted with 1=u gives also puqvr.
 * Two-level substitution of a template containing with 3=u, 4=v gives up; substituted with 4=v it gives p, which itself, substituted with 3=u gives up.

Examples without equality:
 * Two-level substitution of a template containing with 3=, 4=v gives the empty string; substituted with 4=v it gives vp, which itself, substituted with 3=u remains vp.
 * Two-level substitution of a template containing with 1=u, 2=v gives up; substituted with 2=v it gives pp (the bug), which itself, substituted with 3=u, gives upp.
 * Two-level substitution of a template containing with 1=7, 2=8 gives 56; substituted with 2=8 it gives &lt;strong class="error">Expression error: Unrecognised punctuation character "{"&lt;/strong>, which itself, substituted with 1=7, remains the same.

Thus without equality we may or may not get an error message.

One example shows that substitution of one parameter can be affected by the bug mentioned above. However, we can then replace e.g. by  and do full substitution, except that substvoid is undefined, preventing the bug. The result works already correctly with transclusion. Subsequently it can be substituted with substvoid=subst: so that we get the plain.

With defaults:

Rendered the same as without substitution:
 * Two-level substitution of a template containing pqr with 2=v gives pqvr.
 * Two-level substitution of a template containing with 4=v gives p.

Not rendered the same as without substitution:
 * Two-level substitution of a template containing with 4=v gives vp.
 * Two-level substitution of a template containing with 2=v gives pp (the bug).
 * Two-level substitution of a template containing with 2=8 gives &lt;strong class="error">Expression error: Unrecognised punctuation character "{"&lt;/strong>.

After substitution with the parameter definition:
 * vp gives vp.
 * p gives pp (the bug).
 * gives &lt;strong class="error">Expression error: Unrecognised punctuation character "{"&lt;/strong>.

Rewritten:
 * gives the empty string.
 * p gives dp.
 * gives 48.

Documenting substitution; preservation of comments
Usage of a template through  does not automatically show up in page histories. Therefore providing the line of wikitext containing "subst:" in the edit summary is especially useful.

Also pages with a substituted template do not show up in backlinks, and the template does not appear in the list of transcluded templates on the edit page. The template could add pages to a category to track substitutions, but listing this category on a page may clutter the list of content-based categories the page is in. Also, comments outside noinclude tags are included in the wikitext. Thus a comment can be used to mention the template. Substitution of parameters inside comment tags does not work.

See also Help:Comment tags.

Usage considerations
Wikitext after substitution does not show how one can produce a similar result. The wikitext can be long and complicated, and therefore cumbersome to write directly, or it can be simple, e.g. a number resulting from a computation, but cumbersome to find directly. When studying the wikitext of a page one may think that this wikitext is what one is supposed to write and find directly to get the result, even in cases where that would be very impractical.

In such cases documentation of the template call is useful. Just like in computer programming we change the source code and/or the data to produce new results, and we do not directly change the object file, here we would change the template calls and/or the templates, instead of changing the wikitext resulting from substitution directly.

= See also =


 * Extension:ExpandTemplates
 * w:Help:Substitution
 * w:Wikipedia:Template substitution - partly technical, partly policy
 * 2003 - feature request to allow marking a template as being substituted without "subst:"
 * Templates containing a call to itself with "subst:" and producing a similar call with updated info, either replacing or adding to the previous info:
 * - example: Last edit of page User:Mindrones/Manual:Substitution: 2011-07-3 T 22:08 UTC, by Mindrones

= TEXT TO EVALUATE =

Template parameters
Some extensions have the restriction that if they are used in a template with parameters, they only work if the template is substituted. This applies for example in the case of a template parameter inside an in-page query in Semantic MediaWiki.