- Note: this page is outdated. Some suggestions may still be relevant, but many have been addressed by
Help:ParserFunctions
.
The new parameterized template feature is very useful. However, it is limited enough that some useful things remain difficult to do. There is currently no simple way of having optional parameters or a variable number of parameters.
(This was first proposed in
message substitution
. The version there uses the more programming-language-like single word pseudo-namespaces "ifdef" and "foreach", while this version takes advantage of wikitext's support for spaces in URLs and the like to make things more readable)
The syntax proposed here is an extention of the
{{{
parameter
}}}
parameter inclusion syntax, based on the
{{
template
|
parameters
}}
template transclusion syntax. The various constructs are specified through the use of "pseudo-namespaces": prefixes that look like namespace declarations (ending with a colon) but would be used in triple-
braced
parameter inclusions where namespaces are not currently used. The conditional inclusion constructs defined here generally follow the pattern
{{{
construct
:
parameter
|
inserted wikitext
}}}
.
It is sometimes the case that a certain field in a template is important enough for inclusion for some articles but not for others. However, no argument may be unspecified when a template is included in an article, or else bits of the template code show through. The only solutions are to either specify the argument in all uses of the template (even in articles where it is irrelevant) or make two separate templates, one with the field and one without. As an example, look at
w:Template:Language
: the "Regulated by" row in the table is important information for languages with a regulatory academy (like French) but just takes up space in articles for languages that do not. Clearly, this is not ideal.
The
if defined:
pseudo-namespace would be useful for situations like this. An "if defined" construct would follow this syntax:
{{{if defined:
parameter
|
inserted wikitext
}}}
When used in a template, this would insert
inserted wikitext
only if
parameter
was specified in the referring article, and nothing otherwise.
Thus, in the language databox template, this code:
{{{if defined:agency|
|-
| valign="top"|Regulated by:
| valign="top"|{{{agency}}} }}}
would result in the "regulated by" table row appearing only if the referring article specified the
agency
argument.
If no pipe and inserted wikitext were provided, it would insert the value of the parameter:
{{{if defined:
parameter
}}}
would be the same as
{{{if defined:
parameter
|{{{
parameter
}}}?}}}
This would simplify the syntax for what would probably be a common case.
Variable argument length
[
edit
]
Sometimes it is useful to accept an indefinite number of parameters, and treat them in the same fashion. A (convoluted) example is printf(format,...). What I suggest is a syntax to allow this:
In the template code:
In {{{1}}}, {{{2}}} is true. See also: [[{{{3}}}]]&&, [[{{{...}}}]]&&.
In the calling article:
{{foo|this case|that|article 1|article 2|article 3}}
Which produces:
In this case, that is true. See also: [[article 1]], [[article 2]], [[article 3]].
The contents of the && block would be repeated for each parameter that isn't explicitly mentioned (as parameters 1, 2 and 3 are). This can be used for lists, for example, and combined with the if structures suggested elsewhere in this article can lead to complex and powerful templates.
The && block can also be used to iterate through multiple parameters, as an alternative or in addition to the {{{for each:...}}} suggestion below.
Further proposals for the branching construct.
Benc
's proposal
[
edit
]
A generalized if condition as follows:
{{{if:
type
|
arguments
...
}}}
The
type
could be:
- defined
? the arguments being:
parameter-name
|
replacement-if-true
, with the last being optional, meaning the parameter itself if omitted. To conform with
equal
and
contains
(below), the
parameter-name
can optionally be enclosed in triple-braces.
- equal
?
text1
|
text2
|
replacement-if-equal
? substitute
then
if
text1
and
text2
are equal
- contains
?
haystack
|
needle
|
replacement-if-contained
- not (type)
? simple boolean negation to emulate
else
constructs. Elses are not implemented as part of the
if
construct itself to allow for table markup and other things that use pipes. There's no need to support more than one
not
(i.e.
{{{if:not not defined|parameter}}}
is equivalent to
{{{if:defined|parameter}}}
).
Examples:
{{{if:defined|extrainfo|Note: {{{extrainfo}}} }}}
- The following are equivalent:
{{{if:defined|{{{param}}}|{{{param}}}}}}
{{{if:defined|param|{{{param}}}}}}
{{{if:defined|{{{param}}}}}}
{{{if:defined|param}}}
{{{if:equal|{{{SERVER}}}|http://en.wikipedia.org/|I'm the Real McCoy}}}
{{{if:not equal|{{{SERVER}}}|http://en.wikipedia.org/|I'm a mirror}}}
{{{if:contains|{{{text}}}|shit|(WARNING: the following message contains profanity)}}} {{{text}}}
{{{if:contains|motherfucker shit cunt|{{{username}}}|(offensive username removed)}}} {{{if:not contains|motherfucker shit cunt|{{{username}}}|{{{username}}} }}}
These would be very useful, and each
type
could be implemented independantly of the others. This sub-proposal is more robust than its parent, though it still lacks the ability to construct complex boolean expressions (and, or, etc.). Such functionality might very well be more trouble than it's worth.
The syntax of a conditional would be
{{{if:
parameter
|
options
}}}
where "if:" is the pseudo-namespace for the conditional,
parameter
is the template parameter to be compared, and
options
is one or more pairs of comparison and text to be inserted. The syntax of an option is
{
condition
|
inserted text
}
where
condition
is one of a set of tests that can be applied to
parameter
, and
inserted text
is wikitext to be transcluded if the test is true.
The possible conditions are:
- is:
value
- The text is inserted if the value of
parameter
is equal to
value
.
- contains:
substring
- The text is inserted if the value of
parameter
contains the substring
substring
. If
parameter
is a multi-value parameter, the text is inserted if any of the subparameters contain
substring
.
- does not contain:
substring
- The text is inserted if
substring
is not in
parameter
.
- in:
set
- The text is inserted if the value of
parameter
matches one in
set
.
Set
is a cmma-separated list of one or more values or ranges. Ranges are of the form
range start
--
range end
, and may be of any type MediaWiki knows how to order (numbers, dates).
- undefined
- The text is inserted if
parameter
is undefined (that is, the argument was not provided in the template call). This is the opposite of the "if defined" construct.
- else
- The text is inserted if
parameter
doesn't match any preceding condition. This "test" always succeeds if it is reached.
A single
if
construct may contain several options, which
parameter
is tested against in order until one succeeds. It therefore behaves more like a switch/case statement than a traditional if/then statement, but the term "if" was chosen because it is more readable to English-speaking nonprogrammers.
An example of an
if
construct in action:
- {{{if:color|
{in:red,fuschia,crimson,scarlet|red}
{is:blue|blue}
{contains:green|green}
{undefined|}
{else|technicolor}
}}}
A template containing this conditional would insert "red" if the
color
parameter was given as one of a few types of red; "blue" if it was exactly equal to "blue"; "green" if
color
was "green", "bluegreen" or any other string containing the substring "green"; nothing if the color argument wasn't given; and "technicolor" if the value of
color
was something unexpected.
Because extended template syntax does not need to adhere to normal wiki syntax, it might perhaps be better to have a syntax that is distiguish from normal wiki syntax, and allow a more programmable way to handle the syntax.
Example of proposed syntax (might look lot like perl):
{#
foreach($params) {
echo "param: $_<br>\n";
}
echo $params['param'];
echo $variables['date'];
call 'Template:Main', $params[2], $params['note'];
if($params['type'] eq 'true' AND ($params['year'] gt 1997 AND $params['year'] lt 2005)) {
echo "true $params['year']";
} else {
echo 'false';
}
$tmpvar = $params[3];
$tmpvar ~= s/a/b/g;
#}
Another feature would be nice for Wiktionaries. The possibility to strip a suffix/prefix from parameter.
Proposed syntax:
{{{subst:
in-text
|
regexp
|
replacement
}}}
This should be as simple as one
eregreplace()
call in PHP.
Message truncation
[
edit
]
This functionality would be immensely useful for huge multi-part pages like
en:WP:VFD
. Note that this can be accomplished (messily) using regular expressions, but a cleaner syntax would be preferable.
Proposed syntax: (
length
is an optional integer parameter, defaulting to 64 (or some arbitrary number) if omitted or if a non-integer is entered)
{{{trunc:
in-text
|
length
}}}
The output would simply be the template's normal output, truncated after
length
characters. A bolded ellipsis (
...
) linking to the full text would be appended whenever there is text left over after truncation.
The template would have to be parsed before being truncated to avoid situations where there's half of a wikilink (e.g.,
[[Page nam
).
Also, a
truncnw
mode would be useful, analogous to the difference between
msg
and
msgnw
. The template being included and truncated would not be parsed in this case, of course.
In some cases a single field in a template may contain a variable number of items. For example, the language databox contains a field for "genetic classification", which contains one or more language family names.
The solution proposed here would allow a parameter name to be used more than once when a template is used in an article. The parameter would be treated as a list or array by the template code. Simply including the parameter in the template code would insert a comma-separated list of the values assigned to that parameter.
Octothope #subscript notation
[
edit
]
Individual elements of a multi-value parameter could be included by using a subscript notation: the parameter name followed by an
octothorpe
(#) and the index of the element:
{{{
parameter
#
index
}}}
. The numeric indexes could be provided explicitly in the template call, but would otherwise be implicitly assigned based on the order in which the values are given.
So these two template calls:
{{example|param=A|param=B|param=C}}
{{example|param#2=B|param#1=A|param#3=C}}
would both result in
{{{param#1}}}
being "A",
{{{param#2}}}
being "B", and
{{{param#3}}}
being "C".
An argument could also use a named index. The resulting element would be accessible by name (
{{{
parameter
#
indexname
}}}
) and by the implicitly assigned numeric index.
Inserting multiple elements: the "for each" construct
[
edit
]
The "for each" pseudo-namespace would be used to insert a bit of wikitext for each element in a multi-valued parameter. The syntax is:
{{{for each:
parameter
|
inserted wikitext
}}}
Inside
inserted wikitext
,
{{{#}}}
would be replaced with the value of each element in turn. Additionally, equivalently-indexed elements from other multi-valued parameters could be inserted with
{{{
otherparameter
#
}}}
, allowing multi-valued paramters to be used in pairs.
The "number of" construct
[
edit
]
The "number of" construct is replaced by the number of elements in the given parameter. It would mainly be useful for specifying the rowspan or colspan attributes of table cells so that they can sit next to an arbitrary number of for each-created cells. The syntax is simple:
{{{number of:
parameter
}}}
.
Silence Missing Pages
[
edit
]
The transclusion of non-existent templates and pages is now rendered as a link to that template's or page's Edit page. Sometimes it's useful to have
nothing
rendered instead. A special template keyword of the form:
{{EXISTS:pagename}}
would return the pagename if it exists, and nothing otherwise. Combining this feature with phaseIII's default-parameter substitution, one could achieve numerous desired results, and without sacrificing simplicity. For instance, using this it would not be hard to change the link title, depending on whether or not the file exists. Using the {{if}} template:
{{if|test={{EXISTS:newpagename}}|then=[[newpagename|An updated topic]]|else=[[newpagename|Please Add this topic!}}
The template syntax features proposed above would, admittedly, potentially make some templates more difficult to edit. However, they could also make templates easier to use in articles. As the syntax for coding templates is already somewhat technical and difficult for casual editors, and as articles outside of the Template: namespace are, in general, edited more often than the templates themselves, this seems like a reasonable trade-off.
What do you think, sirs?
- Most of the functions listed here are already fairly easily achievable. See Wikipedia's Cateogory for If templates, which offers a fair array of "if defined"'s, "if parameter = value"'s, and so on. These are all achieved with the introduction of being able to put parameters
anywhere
, including
within
other parameters. In short, most of the above-described extensions to template syntax aren't required.
- Furthermore, templates should never be turned into ways of inserting code or complex functions. Look at the name: template. Templates should ultimately transclude. And templates should ultimately be simple to use. That we are able to do some quite complex things (i.e. If templates) with the very simple {{{parameter|default}}} code is astonishing. But we can. No need to go beyond that simplicity. --
131.111.8.104
03:42, 28 February 2006 (UTC)
[
reply
]