WP:SAFESUBST

From Iwe

<languages/> Template:PD Help Page <translate> Substitution is [[<tvar name=1>m:Special:MyLanguage/Help:Automatic conversion of wikitext</tvar>|automatic conversion of wikitext]] of a page when the page is saved, in the case that the wikitext refers to one or more [[<tvar name=2>Special:MyLanguage/Help:Templates</tvar>|templates]], [[<tvar name=3>Special:MyLanguage/Help:variable</tvar>|variables]], or [[<tvar name=4>Special:MyLanguage/Help:parser function</tvar>|parser functions]]. </translate>

<translate> In the case of template substitution the template call is replaced by the template content with substitution of the parameters.</translate> <translate> Thus a template is used as macro and the page is macro expanded when the page is saved rather than, as usually happens, when the page is viewed.</translate>

<translate> In the case of substitution of a variable or parser function the reference to it is replaced by the resulting value. </translate>

<translate> Substitution is done by putting the [[<tvar name=1>Special:MyLanguage/Help:Magic Words</tvar>|magic word]] <tvar name=2>subst:</tvar> or <tvar name=3>safesubst:</tvar> after the double opening braces without intervening spaces like in the examples: <tvar name=4>{{subst:FULLPAGENAME}}</tvar> and <tvar name=5>{{safesubst:FULLPAGENAME}}</tvar>.</translate> <translate> The code <tvar name=1>safesubst:</tvar> is useful in multilevel substitution, see [[<tvar name=2>#Multilevel substitution</tvar>|below]].</translate>

<translate> The result (in the form of the difference with the saved wikitext) can be seen before (or without) saving by pressing "Show changes".</translate> <translate> However, if the text covers more than one paragraph this diff page is not very suitable for copying the result (e.g. for stepwise substitution without saving every step), because of plus signs in the margin.</translate>

<translate>

Contents

[edit] Applications

Substitution of a template: </translate>

  • <translate> Make a rendered page independent of the template:</translate>
    • <translate> The rendered page does not change when the template is edited.</translate>
    • <translate> The page can be copied to another MediaWiki wiki without copying the template.</translate>
  • <translate> Make page rendering easier and therefore faster for the server.</translate>
  • <translate> Analyse and demonstrate the working of templates.</translate> <translate> However, in some cases substitution works differently.</translate>
  • <translate> Make the correspondence between wikitext and rendered page easier to understand (this may apply, the opposite may also apply).</translate>

<translate> Substitution of a time-dependent variable: </translate>

  • <translate> Make a rendered page independent of the time.</translate>

<translate> Substitution of a page-dependent variable: </translate>

  • <translate> Make a rendered page independent of renaming of the page and of copying the wikitext to another page (the opposite applies if the variable <tvar name=1>PAGENAME</tvar> is used in a no-include part of the page to include the page itself).</translate>

<translate> Some MediaWiki extensions have the restriction that if they are used in a template with parameters, they only work if the template is substituted.

[edit] Overview

</translate> <translate> For the discussion of substitution, an "ordinary template" is the page that is referred to by either in the pattern {{<tvar name=1>tmpl|0=Template:((subst:$1 Template:))</tvar>|pagename}} (for pages in the template namespace) or {{<tvar name=1>tmpl|0=Template:((subst:$1 Template:))</tvar>|fullpagename}} (for pages in other namespaces).</translate> <translate> A "predefined template" is a [[<tvar name=1>Special:MyLanguage/Help:variable</tvar>|variable]] or [[<tvar name=2>Special:MyLanguage/Help:parser function</tvar>|parser function]] that is similarly substituted.</translate>

<translate> Substitution is a separate process that is performed before expansion of any non-substituted templates, variables, parser functions, or parameters. </translate>

<translate> A substitution call can have other substitution calls embedded in it.</translate> <translate> Similarly a substitution's substituted template can contain other substitution calls.</translate> <translate> Substitutions in the expression for the name of the template or parser function, in the parameter definitions of the substituted template or parser function and in the body of the substituted template are done first.</translate>

<translate> Since expansion is done later, any expression used in a substitution that happens to contain pairs of double braces, will have the braces treated as plain text.</translate> <translate> Thus during substitution there can be a parameter name with braces in the substitution call (e.g. <tvar name=1>{{subst:foo|a{{bc}}d=...}}</tvar>) that matches a parameter with the same name in the template body (e.g. <tvar name=2>{{{a{{bc}}d}}}</tvar>).</translate>

<translate> If one attempts to apply substitution to a non-existing template etc. there is no substitution, the "subst:" prefix is kept in the wikitext. </translate>

<translate> After the substitution process, expansion of templates etc. and other processing of the resulting wikitext works as usual.</translate> <translate> Because substitution is over, this cannot undo a mismatch of parameter names that occurred during substitution (see also the section "[[<tvar name=1>#Partial substitution</tvar>|Partial substitution]]" below).</translate>

<translate> Substitution is only possible if the following has been fully evaluated:</translate>

  • <translate> the name of the template, variable, or parser function</translate>
  • <translate> in the case of a template: the parameter names in the template call and in the template itself</translate>
  • <translate> in the case of <tvar name=1>#if, #ifexpr, #ifexist</tvar> and <tvar name=2>#iferror</tvar>, the parameter after the colon</translate>
  • <translate> in the case of <tvar name=3>#ifeq</tvar>, the parameter after the colon and the next one</translate>
  • <translate> in the case of <tvar name=4>#switch</tvar>, the parameter after the colon and the expressions to the left of the equals signs</translate>

<translate> Since, as said, substitution is done before other expansion, the abovementioned required evaluation has not taken place if the expressions involve non-substituted expansion.

Also in the case of other parser functions than mentioned, a not fully evaluated parameter after the colon causes the parser function to be applied to the wikitext with braces and not the expanded wikitext, affecting the result.

Examples: </translate>

  • <translate> <tvar name=1>{{subst:Help:L{{tc}}k}}</tvar> using <tvar name=2>Template:tc</tvar>, does not do substitution, because <tvar name=3>Help:L{{tc}}k</tvar> is not an existing page, although <tvar name=4>Help:L{{tc}}k</tvar> is rendered as <tvar name=5>Help:LTemplate:Tck</tvar>.</translate> <translate> Thus the resulting wikitext is the same as the original wikitext and rendered as <tvar name=1>{{subst:Help:LTemplate:Tck}}</tvar>.</translate>
  • <translate> <tvar name=1>{{#if:{{void|abc}}|yes|no}}</tvar> (using <tvar name=2>Template:void</tvar>) is rendered as "<tvar name=3>{{#if:|yes|no}}</tvar>", and so <tvar name=4>{{subst:#if:{{subst:void|abc}}|yes|no}}</tvar> similarly gives the wikitext "<tvar name=7>no</tvar>".</translate> <translate> On the other hand, <tvar name=6>{{subst:#if:{{void|abc}}|yes|no}}</tvar> gives the wikitext "<tvar name=7>yes</tvar>", because <tvar name=1>Template:void</tvar> is not resolved until after substitution.</translate>

<translate> In principle the wikitext resulting from full substitution is, immediately after that, rendered the same as the wikitext with ordinary inclusion.

Note however that on substitution of a parser function, an undefined parameter with default, used in a parameter value, is not replaced by the default (in English Wikipedia), and is for example not allowed in the numerical expression evaluated on substitution of <tvar name=1>#expr</tvar>: </translate>

  • <translate> <tvar name=1>{{#expr:2*{{{p|3}}}}}</tvar> gives <tvar name=2>{{#expr:2*3}}</tvar>, while <tvar name=3>{{subst:#expr:2*{{{p|3}}}}}</tvar> gives:</translate> Expression error: unrecognised punctuation character "{"

<translate> On substitution of a template that contains this, <tvar name=1>{{{p|3}}}</tvar> is either replaced by the value of <tvar name=2>{{{p}}}</tvar> or by 3, so then there is no complication.</translate>

<translate> <tvar name=1>{{ {{t6}} }}</tvar> using <tvar name=4>Template:t6</tvar> containing "<tvar name=5>[[:Template:T6]]</tvar>" is rendered as <tvar name=3>{{ Template:T6 }}</tvar>.</translate> <translate> <tvar name="1">{{subst:{{subst:t6}} }}</tvar> gives the wikitext <tvar name="2">{{subst:t2demo|a }}</tvar> rendered the same as the wikitext, and on the next edit/save changed into <tvar name=3>start-a -middle-{{{2}}}-end</tvar>.</translate> <translate> <tvar name="1">{{ {{subst:t6}} }}</tvar> gives the wikitext <tvar name="2">{{ t2demo|a }}</tvar>, rendered as <tvar name=3>Template:T2demo</tvar>.</translate> <translate> This is because, both without substitution and in the case of full substitution, the pipe characters in template calls, excluding those inside inner template calls, template parameters, links, and image tags, determine the separation of parameter definitions from each other and from the template name.</translate> <translate> This separation does not depend on possible extra pipe characters in the expanded form of the template name and parameter definitions.</translate> <translate> However, if after substitution of an inner template the pipe character is in the outer template call it is one like any other and plays its part in determining the separation.</translate> <translate> In other words, parsing is done first once for substitution, and then once for rendering, but in both cases not an extra time in between.</translate> <translate> In the case of substitution of the inner template only, two subsequent parsings are effective.</translate>

<translate> When substituting a template containing <tvar name="1">{{{p|q}}}</tvar> (a parameter tag with default) this results in the value of <tvar name=2>p</tvar> if it is defined, and otherwise in <tvar name=3>q</tvar>.</translate> <translate> For example, using <tvar name="1">&lbrace;&lbrace;timc|t pd}}</tvar> (in English Wikipedia), <tvar name="2">{{subst:t pd}}</tvar> gives the wikitext 2.</translate> <translate> If a page substitutes itself (e.g. in the noinclude-part of a template page) it substitutes the old version.</translate>

<translate>

[edit] Usage considerations

</translate> <translate> As mentioned, a change of an ordinary template after substitution does not affect the page in which it was substituted, and a substituted variable depending on time no longer depends on time, etc.</translate> <translate> However, a substitution of e.g. <tvar name=1>{{#expr:2*3}}</tvar> does not affect rendering at all.</translate>

<translate> The relationship between wikitext of a page and its rendering can become easier to understand after substitution, because one has all wikitext together, and parameter substitutions have been performed.</translate>

<translate> It can also become more complex.</translate> <translate> Separately focusing on understanding a template call and understanding the template content can be easier.</translate> <translate> Wikitext after substitution is often more complex than when the required wikitext would have been written directly.</translate>

<translate> Unlike a template call (if one knows about templates), wikitext after substitution does not show how one can produce a similar result.</translate> <translate> 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.</translate> <translate> 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.</translate>

<translate> In such cases documentation of the template call is useful.</translate> <translate> 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.</translate>

<translate>

[edit] Ordinary templates

In the case of substituting an ordinary template, the template tag is replaced by the wikitext of the template, with the parameter values substituted for the parameters. </translate>

<translate> Example:</translate> <translate> <tvar name=1>Template:Tim</tvar>, containing</translate>
start-{{{1}}}-middle-{{{2}}}-end
<translate> and called as <tvar name=1>{{subst:t2|[[a]]|{{tc}}}}</tvar> (see <tvar name=2>{{tc}}</tvar>) gives the wikitext:</translate>
<translate> <tvar name=1>start-[[a]]-middle-{{tc}}-end</tvar>, rendering as</translate>
start-a-middle-Template:Tc-end.

<translate> Substitution removes the noinclude parts and the includeonly tags.</translate>

<translate> Parameters:</translate>

  • <translate> A substitution with <tvar name=1>p=r</tvar> replaces <tvar name=2>{{{p}}}</tvar> and <tvar name=3>{{{p|q}}}</tvar> by <tvar name=4>r</tvar>.</translate> <translate> This includes the cases that <tvar name=1>r</tvar> is of the form <tvar name=2>{{{s}}}</tvar> or <tvar name=3>{{{s|t}}}</tvar>.</translate>
  • <translate> A substitution with undefined <tvar name=1>p</tvar> preserves <tvar name=2>{{{p}}}</tvar> and replaces <tvar name=3>{{{p|q}}}</tvar> by the default <tvar name=4>q</tvar> (in English Wikipedia).</translate>

<translate> With <tvar name=1>subst:</tvar> the replacement of a template tag by wikitext does not work recursively.</translate> <translate> For full recursive substitution use <tvar name=1>Special:ExpandTemplates</tvar>.</translate> <translate> See also <tvar name=1>substall</tvar>, and [[<tvar name=2>#Multilevel substitution</tvar>|multilevel substitution]] below.</translate>

<translate> Stepwise substitution of templates including other templates including more templates etc. can be useful for analyzing and documenting the behaviour of complex templates, for an example see <tvar name=1>m:Template talk:Lop</tvar>.

However, after a substitution a page may render differently, e.g. if templates produce braces, pipes, and/or equals signs which after substitution determine expansion of other templates, but without substitution are treated as plain text. </translate>

<translate> In the absence of parameters, template substitution can be compared with copying the wikitext, or the rendering of a previewed or saved {{<tvar name=1>tmpl|0=Template:(( msgnw:$1 Template:))</tvar>|pagename}} inclusion.</translate> <translate> However, template substitution excludes <tvar name=1>Template:Tag</tvar> parts, removes <tvar name=2>Template:Tag</tvar> tags, and replaces undefined parameters with defaults by those defaults.</translate>

<translate>

[edit] Predefined templates

In the case of substituting a predefined template, without parameters depending on other templates, the tag is replaced by the result. </translate>

<span class="citation wikicite" id="endnote_<translate> <tvar name=1>subst:</tvar> has to be added directly in front of the predefined template name without intervening spaces.</translate>">[[#ref_<translate> <tvar name=1>subst:</tvar> has to be added directly in front of the predefined template name without intervening spaces.</translate>|^]]</span>

<translate> Applying subst to a variable works like applying it to a template.</translate> <translate> E.g. a timestamp:</translate>

{{subst:CURRENTYEAR}}-{{subst:CURRENTMONTH}}-{{subst:CURRENTDAY}} T {{subst:CURRENTTIME}} [[w:UTC|]]

<translate> may give the wikitext</translate>

2010-04-10 T 06:30 [[w:UTC|UTC]]

<translate> rendered as</translate>

2010-04-10 T 06:30 UTC

<translate> In the case of substituting a predefined template with a parameter depending on another template, that has to be substituted too, with a separate <tvar name=1>subst:</tvar> modifier, otherwise the result is undefined.</translate>

  • {{subst:UC:{{subst:tc}}}} - <translate> gives IN, the same wikitext as <tvar name=1>{{UC:{{tc}}}}</tvar> is expanded to; <tvar name=2>UC:</tvar> is applied to the output "in" of <tvar name=3>Tc</tvar>.</translate>
  • {{subst:ns:{{subst:#expr:2*3}}}} - <translate> gives File.</translate>
  • {{ns:{{subst:#expr:2*3}}}} - <translate> gives wikitext <tvar name=1>{{ns:6}}</tvar> rendered as <tvar name=2>File</tvar>.</translate>
  • {{subst:t1|{{subst:NAMESPACE}}}} - <translate> gives the wikitext <tvar name=1>startHelpend</tvar> (see <tvar name=2>{{t1}}</tvar>)</translate>
  • {{subst:t1|{{subst:#expr:3*4}}}} - <translate> gives the wikitext <tvar name=1>start12end</tvar></translate>
  • {{subst:t1|{{subst:uc:AbCdEf}}}} - <translate> gives the wikitext <tvar name=1>startABCDEFend</tvar></translate>
  • {{subst:#expr:{{subst:3X|11*}}1}} - <translate> gives the wikitext <tvar name=1>{{#expr:Template:3X1}}</tvar></translate>
  • {{subst:UC:{{subst:3X|abc}}}} - <translate> gives the wikitext <tvar name=1>TEMPLATE:3X</tvar></translate>
  • {{subst:LC:{{subst:#expr:1/100000}}}} - <translate> gives the wikitext <tvar name=1>1e-05</tvar></translate>
  • {{subst:#expr:2*{{subst:CURRENTDAY}}}} - <translate> gives (at the time of writing) the wikitext 30</translate>
  • {{subst:UC:{{subst:CURRENTDAYNAME}}}} - <translate> gives (at the time of writing) the wikitext <tvar name=1>THURSDAY</tvar></translate>

<translate> However:</translate>

  1. {{subst:UC:{{tc}}}} - <translate> gives the wikitext <tvar name=1>{{TC}}</tvar> rendered as <tvar name=2>Template:TC</tvar>.</translate>
  2. {{subst:ns:{{#expr:2*3}}}} - <translate> stays <tvar name=1>{{subst:ns:{{#expr:2*3}}}}</tvar>, rendered as <tvar name=2>{{subst:ns:{{#expr:2*3}}}}</tvar>.</translate>

<translate> As mentioned before, on substitution, all calls without substitution of templates, variables, and parser functions are treated as plain text.</translate> <translate> As a result substitution of the outer <tvar name=1>x:</tvar> in a nested <tvar name=2>{{ x:...{{ y:...}} }}</tvar> often is only suitable if all inner <tvar name=3>y:</tvar> are also substituted.</translate>

<translate> In the case of substitution of a predefined template, if the expression for one of its parameters contains <tvar name=1>{{{p|3}}}</tvar> with undefined <tvar name=2>p</tvar>, this code reduces to 3.</translate> <translate> However, on the page itself, <tvar name=1>{{{p|3}}}</tvar> is treated as such, not as 3.</translate>

<translate> Examples:</translate>

  • {{#expr:2*{{{p}}}}}{{#expr:2*{{{p}}}}}
  • {{#expr:2*{{{p|3}}}}}{{#expr:2*3}}
  • {{subst:#expr:2*{{{p|3}}}}}Expression error: Unrecognized punctuation character "{".
  • <translate> substituting a template containing <tvar name=1>{{<includeonly>subst:</includeonly>#expr:2*{{{p|3}}}}}</tvar> gives 6 if <tvar name=2>p</tvar> is not assigned a value, and twice the number <tvar name=2>p</tvar> if it is assigned a value.</translate>
  • <translate> the same result can be obtained from a template containing <tvar name=1>{{{{{subst}}}#expr:2*{{{p|3}}}}}</tvar>, if the substitution call has a parameter of "<tvar name=2>subst=subst:</tvar>".</translate>

<translate> Compare:</translate>

  • {{uc:2*{{{p}}}}}2*{{{P}}}
  • {{uc:2*{{{p|q}}}}}2*Q
  • {{subst:uc:2*{{{p|q}}}}} → <translate> the wikitext <tvar name=1>2*{{{P|Q}}}</tvar> rendered as <tvar name=2>2*Q</tvar></translate>

<translate> and also (from above):</translate>

  • {{subst:UC:{{subst:tc}}}} - <translate> gives IN, just like <tvar name=1>{{UC:{{tc}}}}</tvar> does; <tvar name=2>Template:Ll</tvar> is applied to the output "in" of <tvar name=3>Tc</tvar>.</translate>
  • {{subst:UC:{{tc}}}} - <translate> gives the wikitext <tvar name=1>{{TC}}</tvar> rendered as <tvar name=2>Template:TC</tvar>.</translate>

<translate> In the substitution of <tvar name=1>UC</tvar>, the inclusion tag <tvar name=2>{{tc}}</tvar> is treated as string just like <tvar name=3>{{{p|q}}}</tvar>.

[edit] Partial substitution

</translate> <translate> 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.</translate> <translate> It amounts to automatically merging the two templates (creating a "composite template" like a composite function).</translate> <translate> It is not possible if the inner and/or outer template is predefined.</translate> <translate> (However, manually merging e.g. a call of <tvar name=1>#expr</tvar> inside another one is useful for increasing the accuracy of the result by avoiding intermediate rounding to 12 digits.)</translate>

<translate> This way one can dispense with the optional substitution technique described below, and apply substitution of the resulting outer template by simply using <tvar name=1>subst:</tvar> (unless there are more nesting levels).

Example: </translate>

  • {{subst:t}} - <translate> gives the wikitext <tvar name=1>start-{{{1|pqr}}}-end</tvar>, just that of <tvar name=2>Template:Tim</tvar>, without noinclude parts and includeonly tags</translate>
  • {{subst:t|a{{{p|q}}}b}} - <translate> gives the wikitext <tvar name=1>start-a{{{p|q}}}b-end</tvar></translate>

<translate> Examples with double substitution:</translate>

  • {{subst:3X|{{subst:t}}}} - <translate> gives the wikitext <tvar name=1>start-{{{1|pqr}}}-endstart-{{{1|pqr}}}-endstart-{{{1|pqr}}}-endstart-{{{1|q}}}-end</tvar></translate>
  • {{subst:3X|{{subst:t|{{{1|q}}}}}}} - <translate> gives the wikitext <tvar name=1>start-{{{1|q}}}-endstart-{{{1|q}}}-endstart-{{{1|q}}}-end</tvar></translate>

<translate>

[edit] Multilevel substitution

</translate> <translate> When substituting a template it may be desirable to carry out a substitution inside the template too.</translate> <translate> This can be done with <tvar name=1>safesubst:</tvar> in the template.</translate> <translate> To prevent premature substitution (i.e., when the template is saved), this code is provided as default value of an unused parameter.</translate> <translate> 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 unused parameter, so we can use the code <tvar name=1>{{{|safesubst:}}}</tvar>.</translate>

<translate> The difference with <tvar name=1>{{{|subst:}}}</tvar> is that <tvar name=2>{{{|safesubst:}}}</tvar>, evaluating to <tvar name=3>safesubst:</tvar> 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.</translate> <translate> To make the template such that it allows the choice between these two options as well as one-level substitution (and more choices if more templates, variables, and/or parser functions are involved) one or more parameters are needed, see below.</translate>

<translate> 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 {{<tvar name=1>ll|Help:Templates#Template tag lay-out</tvar>|template tag lay-out}}.</translate> <translate> This would affect the working of the code <tvar name=1>{{{|safesubst:}}}</tvar>.</translate> <translate> To allow this other dummy use of the parameter, another parameter name can be used in {{<tvar name=1>tmpl|0={{{$1|safesubst:}}}</tvar>|parameter name}}, or to avoid any possible clash of dummy parameter names, includeonly tags can be used, see below.</translate>

<translate>

[edit] Multilevel substitution with independent control of each substitution separately

</translate> <translate> A parameter subst (or more, each with its own name) can be used with <tvar name=1>safesubst:</tvar>" and the empty string as possible values.</translate> <translate> Thus we can for example control whether an inner template is substituted too when the outer template is substituted.</translate> <translate> Either possibility can be made the default.</translate>

<translate> 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.

Similarly, if there are multiple templates, variables, and/or parser functions in the inner template(s) we can control substitution of all, either independently by using different parameters, or with some or all using the same parameter.

For example, if template <tvar name=1>T</tvar> uses parameter <tvar name=2>subst1</tvar>: </translate>

  • <translate> with the empty string as default, <tvar name=1>T</tvar> calls inner templates and parser functions prefixing their names with <tvar name=2>{{{subst1|}}}</tvar>; for calling <tvar name=1>T</tvar> we can use:</translate>
    • {{t|..}} - <translate> no substitution</translate>
    • {{subst:t|..}} - <translate> one-level substitution</translate>
    • {{subst:t|subst1=subst:|..}} - <translate> two-level substitution</translate>
    • {{subst:t|subst1=safesubst:|..}} - <translate> ditto</translate>
  • <translate> with default <tvar name=1>"safesubst:"</tvar>, <tvar name=2>T</tvar> calls inner templates and parser functions prefixing their names with <tvar name=3>{{{subst1|safesubst:}}}</tvar>; for calling <tvar name=2>T</tvar> we can use:</translate>
    • {{t|..}} - <translate> no substitution</translate>
    • {{subst:t|subst1=|..}} - <translate> one-level substitution</translate>
    • {{subst:t|..}} - <translate> two-level substitution</translate>

<translate> To transfer the choice of substituting or not to templates and parser functions called inside the inner templates of <tvar name=1>T</tvar>, we can add to the call of these inner templates something of the form <tvar name=2>subst2={{{subst1|}}}</tvar> or <tvar name=3>subst2={{{subst1|safesubst:}}}</tvar>, respectively ({{<tvar name=4>ll|Help:variable</tvar>|variables}} and {{<tvar name=5>ll|Help:parser function</tvar>|parser functions}} don't get the additional parameter).</translate>

<translate> See also [[<tvar name=1>m:Special:MyLanguage/Help:Calculation#Substitution</tvar>|m:Help:Calculation#Substitution]] and <tvar name=2>m:Template:Example table with computations, with optional substitution</tvar>.

[edit] Partial substitution

</translate>

<translate> Using a template prepared for optional <tvar name=1>subst=subst:</tvar> only with ordinary substitution, without specifying parameter values, allows to insert its code into another template, like copy and paste, but all <tvar name=2>Template:Tag</tvar> parts and <tvar name=3>Template:Tag</tvar> keywords automatically stripped.</translate> <translate> Executing inserted code instead of calling it may be more efficient for the server.</translate>

<translate> A typical example for this technique is expanding, within another template, a template used as test expression in a <tvar name=1>#switch:</tvar> like <tvar name=2>Template:Tim</tvar>:</translate>

  1. <translate> Development code:</translate>
    Template:Tmpl
  2. <translate> Standard solution:</translate>
    Template:Tmpl
  3. <translate> Better solution: create template code by applying substitution using this wikitext:</translate>
    Template:Tmpl

<translate> <tvar name=1>Template:Tim</tvar> is prepared for optional substitution, therefore both solutions work, but the latter solution substituting its code is simpler and more efficient.

See <tvar name=1>Template:Tim</tvar> and <tvar name=2>Template:Tim</tvar> for cases where <tvar name=3>Template:len</tvar> was substituted in this way. </translate>

<translate> If a template uses a parameter whose name is an expression containing a template or parser function, and the template is called with a corresponding parameter definition (in terms of the final name of the parameter) it expands properly only if at the time of expansion of the template the expression for the name of the parameter is or has been evaluated.</translate> <translate> Thus if the template is substituted without substituting the expression for the parameter name, the parameter definition is "lost", so the parameter becomes undefined.</translate> <translate> Therefore in such a case no substitution can give the same rendered result as full substitution, while partial substitution gives a different result.</translate> <translate> See e.g. <tvar name=1>Template:Tim</tvar>.</translate>

<translate>

[edit] Composite operations

</translate>

<translate> By <tvar name=1>{{A|{{B|p}}}}</tvar> a template <tvar name=2>A</tvar> is called with, as parameter, a call of template <tvar name=3>B</tvar> with a parameter <tvar name=4>p</tvar>.</translate> <translate> We could integrate such template calls to a single call <tvar name=1>{{C|p}}</tvar> of a "composite template" <tvar name=2>C</tvar> with parameter <tvar name=3>p</tvar>.</translate>

<translate> The wikitext for template <tvar name=1>C</tvar> would be <tvar name=2>{{A|{{B|{{{1}}}}}}}</tvar>, or with optional substitution the following construct</translate> :
Template:(( Template:(((subst|Template:))) A|Template:(( Template:(((subst|Template:))) B|{{{1}}} |subst=Template:(((subst|Template:))) Template:)) |subst=Template:(((subst|Template:))) Template:))
<translate> The <tvar name=1>subst={{{subst|}}}</tvar> is only necessary for recursive substitution as explained above.</translate>

<translate> Note that it is not useful to specify <tvar name=1>{{subst|subst:}}</tvar> since in the substitution phase this tag does not reduce to the default <tvar name=2>subst:</tvar>.</translate>

<translate> If <tvar name=1>A</tvar> and/or <tvar name=2>B</tvar> is predefined the construct is similar, but without <tvar name=3>subst={{{subst|}}}</tvar> for that template. </translate>


[edit] includeonly

<translate> An alternative method to prevent premature substitution, known as "includeonly subst magic", is with a pair of <tvar name=1>includeonly</tvar> tags.</translate> <translate> Substitution is prevented by having the template call inside these tags.</translate> <translate> Substitution is also prevented by having one or both tags anywhere in the template call except inside a parameter definition.</translate> <translate> Thus the tag(s) can be before, inside, or after <tvar name=1>safesubst:</tvar> or <tvar name=2>subst:</tvar>, or inside or after the template name.</translate> <translate> The positions of the two tags only influence the rendering of the template page itself.</translate>

<translate> The form {{<tvar name=1>tmpl|0=Template:((Template:^(includeonlyTemplate:)^safesubst:Template:^(/includeonlyTemplate:)^$1Template:))</tvar>|something}} suggests that substitution is prevented by discarding <tvar name=2>safesubst:</tvar> on the page itself, but actually substitution is prevented because the safesubst-syntax is disturbed by the tags.</translate>

<translate> 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 {{<tvar name=1>ll|Extension:InputBox#Parameters</tvar>|Extension:InputBox}} and "substitution" in {{<tvar name=2>ll|Help:Magic_words#Transclusion modifiers</tvar>|Help:Magic words}}.

[edit] Creating a page which applies substitution on the next save

</translate> <translate> See [[<tvar name=1>m:Special:MyLanguage/Help:Recursive conversion of wikitext</tvar>|Help:Recursive conversion of wikitext]].</translate>

<translate>

[edit] Forced substitution

</translate> <translate> Some templates deliberately refuse to work without substitution, for an example see <tvar name=1>Template:Tiw</tvar>.</translate> <translate> This technique is essential for templates like <tvar name=1>Template:Tiw</tvar> producing some kind of timestamp, e.g. adding pages to dated categories.</translate>

<translate> The following code in any template <tvar name=1>T</tvar> outputs a warning unless recursive substitution with <tvar name=2>subst=subst:</tvar> is in effect</translate>:
{{{{{subst|}}}ifdef|{{{{{subst|subst:}}}ns:0}}|'''Warning'''}}.
  1. <translate> Output for <tvar name=1>Template:((TTemplate:))</tvar> or <tvar name=2>Template:((subst:TTemplate:))</tvar></translate> - Warning
  2. <translate> Output for <tvar name=1>Template:((T|subst=subst:Template:))</tvar></translate> - Template:Ifdef
  3. <translate> Output for <tvar name=1>Template:((subst:T|subst=subst:Template:))</tvar></translate> - <translate> nothing (no remaining wikitext)</translate>
<translate> This is a rare case where replacing <tvar name=1>ifdef</tvar> by <tvar name=2>#if:</tvar> doesn't work directly.</translate>

<translate>

[edit] Substitution of part of the parameters

</translate> <translate> Let template <tvar name=1>Feelings</tvar> use parameters 1 and 2.</translate> <translate> Consider creating a template Emotions with one parameter 1, corresponding to <tvar name=1>Feelings</tvar>, with a given value <tvar name=2>love</tvar> of parameter 2.</translate> <translate> Compare <tvar name=1>{{Feelings|2=love}}</tvar> and <tvar name=2>{{Feelings|1={{{1}}}|2=love}}</tvar>.</translate> <translate> They look the same on the template page, see e.g. <tvar name=1>Template:Tim</tvar>, but the first does not work because <tvar name=2>{{{1}}}</tvar> is treated as text, not as parameter.</translate>

<translate> However, with substitution (using <tvar name=1>subst:</tvar> or <tvar name=2>Special:Expandtemplates</tvar>) the resulting wikitext is the same, without distinction between a text <tvar name=3>{{{1}}}</tvar> and a parameter, it is a parameter anyway, so <tvar name=4>1={{{1}}}</tvar> is not needed.

If <tvar name=1>Feelings</tvar> contains e.g. <tvar name=2>#expr</tvar> with an expression containing both parameters the same applies, except that we can only substitute the highest level (<tvar name=3>Feelings</tvar>), not the parser function, so we cannot use <tvar name=4>Special:Expandtemplates</tvar>.

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: </translate>

  • <translate> <tvar name=1>Feelings</tvar> template containing <tvar name=2>With {{{1}}} one can {{{2}}}</tvar></translate>
    • <translate> When substituted with <tvar name=1>1=love</tvar>, <tvar name=2>2=help</tvar>, it gives <tvar name=3>With love one can help</tvar>.</translate>
    • <translate> When substituted with <tvar name=1>2=help</tvar>, it gives <tvar name=2>With {{{1}}} one can help</tvar>.</translate> <translate> This itself, when substituted with <tvar name=1>1=compassion</tvar>, it gives <tvar name=2>With compassion one can help</tvar>.</translate>
  • <translate> Two-level substitution of a template containing <tvar name=1>{{#if:{{{4}}}|{{{3}}}p}}</tvar>.</translate>
    • <translate> When substituted with <tvar name=1>3=u</tvar>, <tvar name=2>4=v</tvar>, it gives <tvar name=3>up</tvar>.</translate>
    • <translate> When substituted with <tvar name=1>4=v</tvar>, it gives <tvar name=2>{{{3}}}p</tvar>.</translate> <translate> This itself, when substituted with <tvar name=1>3=u</tvar>, it gives <tvar name=2>up</tvar>.</translate>

<translate> Examples without equality:</translate>

  • <translate> Two-level substitution of a template containing <tvar name=1>{{#if:{{{3}}}|{{{4}}}p}}</tvar></translate>
    • <translate> When substituted with <tvar name=1>3=</tvar>, <tvar name=2>4=v</tvar>, it gives the empty string.</translate>
    • <translate> When substituted with <tvar name=1>4=v</tvar>, it gives <tvar name=2>vp</tvar>.</translate> <translate> This itself, when substituted with <tvar name=1>3=u</tvar>, it remains <tvar name=2>vp</tvar>.</translate>
  • <translate> Two-level substitution of a template containing <tvar name=1>{{#if:{{{2}}}|{{{1}}}p}}</tvar></translate>
    • <translate> When substituted with <tvar name=1>1=u</tvar>, <tvar name=2>2=v</tvar>, it gives <tvar name=3>up</tvar>.</translate>
    • <translate> When substituted with <tvar name=1>2=v</tvar>, it gives <tvar name=2>{{{1}}}pp</tvar> (the bug).</translate> <translate> This itself, when substituted with <tvar name=1>3=u</tvar>, it gives <tvar name=2>upp</tvar>.</translate>
  • <translate> Two-level substitution of a template containing <tvar name=1>{{#expr:{{{1}}}*{{{2}}}}}</tvar></translate>
    • <translate> When substituted with <tvar name=1>1=7</tvar>, <tvar name=2>2=8</tvar>, it gives <tvar name=3>56</tvar>.</translate>
    • <translate> When substituted with <tvar name=1>2=8</tvar>, it gives <tvar name=2>Expression error: Unrecognised punctuation character "{"</tvar>.</translate> <translate> This itself, when substituted with <tvar name=1>1=7</tvar>, it remains the same.</translate>

<translate> Thus without equality we may or may not get an error message.</translate>

<translate> One example shows that substitution of one parameter can be affected by the bug mentioned above.</translate> <translate> However, we can then replace e.g. <tvar name=1>{{{1}}}</tvar> by <tvar name=2>{{{1{{{{{substvoid|}}}void}}}}}</tvar> and do full substitution, except that <tvar name=3>substvoid</tvar> is undefined, preventing the bug.</translate> <translate> The result works already correctly with transclusion.</translate> <translate> Subsequently it can be substituted with <tvar name=1>substvoid=subst:</tvar> so that we get the plain <tvar name=2>{{{1}}}</tvar>.</translate>

<translate> With defaults:</translate>

<translate> Rendered the same as without substitution:</translate>

  • <translate> Two-level substitution of a template containing <tvar name=1>With {{{1|love}}} one can {{{2}}}</tvar> with <tvar name=2>2=help</tvar> gives <tvar name=3>With {{{1|love}}} one can help</tvar>.</translate>
  • <translate> Two-level substitution of a template containing <tvar name=1>{{#if:{{{4}}}|{{{3|d}}}p}}</tvar> with <tvar name=2>4=v</tvar> gives <tvar name=3>dp</tvar>.</translate>

<translate> Not rendered the same as without substitution:</translate>

  • <translate> Two-level substitution of a template containing <tvar name=1>{{#if:{{{3|}}}|{{{4}}}p}}</tvar> with <tvar name=2>4=v</tvar> gives <tvar name=3>vp</tvar>.</translate>
  • <translate> Two-level substitution of a template containing <tvar name=1>{{#if:{{{2}}}|{{{1|d}}}p}}</tvar> with <tvar name=2>2=v</tvar> gives <tvar name=3>dpp</tvar> (the bug).</translate>
  • <translate> Two-level substitution of a template containing <tvar name=1>{{#expr:{{{1|6}}}*{{{2}}}}}</tvar> with <tvar name=2>2=8</tvar> gives:</translate> Expression error: Unrecognised punctuation character "{"

<translate> After substitution with the parameter definition:</translate>

  • {{subst:#if:{{{3|}}}|vp}}vp
  • {{subst:#if:v|{{{1|d}}}p}}dpp <translate> (the bug)</translate>
  • {{subst:#expr:{{{1|6}}}*8}}Expression error: Unrecognised punctuation character "{"

<translate> Rewritten:</translate>

  • {{subst:#if:{{subst:#ifeq:{{{3|+}}}|{{{3|-}}}|vp}}}} → <translate> the empty string</translate>
  • {{subst:#if:v|{{subst:#ifeq:{{{1|+}}}|{{{1|-}}}|{{{1}}}|d}}p}}dp
  • {{subst:#expr:{{subst:#ifeq:{{{1|+}}}|{{{1|-}}}|{{{1}}}|6}}*8}}48

<translate>

[edit] Limitations

</translate> <translate> Substitution is not available inside parser tags like <tvar name=1>Template:Tag</tvar> and <tvar name=2>Template:Tag</tvar>.</translate> <translate> If you write <tvar name=1>Template:Tnull</tvar>, it is not substituted nor transcluded, but remains as-is.</translate>

<translate>

[edit] Documenting substitution

</translate> <translate> Usage of a template through <tvar name=1>subst:</tvar> does not automatically show up in page histories.</translate> <translate> Therefore providing the line of wikitext containing "<tvar name=1>subst:</tvar>" in the [[<tvar name=2>m:Special:MyLanguage/Help:Edit summary</tvar>|edit summary]] is especially useful.</translate>

<translate> 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.</translate> <translate> 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.</translate> <translate> Also, comments outside noinclude tags are included in the wikitext.</translate> <translate> Thus a comment can be used to mention the template.</translate> <translate> It can even contain the values of the parameters, because substitution of parameters works even in comments.</translate>

<translate>

[edit] See also

</translate>

[[Category:Templates{{#translation:}}]]

Personal tools