Page MenuHomePhabricator

Optional parameters (and/or default parameter values) in templates
Closed, ResolvedPublic

Description

Author: ahoerstemeier

Description:
To use templates with infoboxes, especially with the taxoboxes of the "Tree of
Life" wikiproject, optional parameters are needed to avoid many very similar
templates for each variation - every optional parameter increases the number of
templates needed by factor of two. On [[meta:Extended template syntax]] one
possible syntax in the templates is suggested.


Version: unspecified
Severity: enhancement

Details

Reference
bz364

Event Timeline

bzimport raised the priority of this task from to Medium.Nov 21 2014, 6:54 PM
bzimport set Reference to bz364.
bzimport added a subscriber: Unknown Object (MLST).

all parameters are optional: if a parameter is not given, the value is taken
from a template with that name. I.e. if the first parameter is missing, the
value of [[Template:1]] is used. This approach works rather badly, I filed a
separate bug about this, #847.

rowan.collins wrote:

(In reply to comment #1)

all parameters are optional: if a parameter is not given, the value is taken
from a template with that name.

Strictly speaking, this is not true; if the parameter is not present, the outer
{ and } are written directly, and the inner {{text}} is parsed as a template,
simply because that's how {{text}} is always parsed. This is essentially a
parser bug, and appears to have been fixed in CVS (test.wikipedia.org just
writes the "{{{text}}}" out directly).

I'm going to mark bug 847 as a dupe of this, on the grounds that:

  1. the current behaviour doesn't really count as "optional parameters" in any way
  2. a minimally sensible kind of "optional parameters" would be to default a

parameter to being blank

  1. it's probably sometimes useful to *see* that a parameter has been omitted, so

this behaviour should be enabled on a template-by-template basis

  1. allowing the user to specify the default value for a parameter is therefore

the sane way of creating optional parameters (if you set the default as "", it
disappears by default; but if you want to set a default, that's still an
"optional parameter")

  1. the two bugs are therefore requesting exactly the same feature

rowan.collins wrote:

*** Bug 847 has been marked as a duplicate of this bug. ***

ok, i didn't realize that. It would be really great if defaults could be
implemented.

To re-state the suggestion i made in #847: I would like to be able to specify a
default value for a parameter like this: {{{ParamName|DefaultValue}}}. The
parser should be written so it can cope with things like
{{{ParamName|{{PAGENAME}}}}} and {{{ParamName|[[Some Link|Piped Link]]}}}.

rowan.collins wrote:

One of the biggest problems with defining a syntax for this is what to do when a
parameter is used multiple times in one template. That is:

  • should the parameter be given a default the first time it is used, and that

default be used everywhere in the template? (In which case, editing the template
requires finding that first use)

  • or, should each instance of the parameter have to define its own default? (In

which case, you'll need to hunt through and find *every* use of the parameter if
you want to change the default)

  • or, should you have to define the default *before* the parameter is first

used, or be able to do so at an arbitrary location in the template? (In which
case, how do we design the syntax for doing the defining so that it's obvious it
will be invisible)

  • or, is there some combination of these - like, you *can* define it on first

use *or* you can use an invisible define-default-parameter statement.

It's a tricky one. And the meta page referenced in comment #0 includes some even
crazier ideas...

[And btw, the "parser" keyword isn't appropriate here: it's for bugs in the
parser that exist because of its non-parser-ness, and will go away once we have
a proper one; which this won't, as it is an entirely new feature]

ahoerstemeier wrote:

The main idea is not simply to leave a parameter empty which isn't set (the fact
that isn't done now may be a different bug), and a simple default value isn't
enough for those case I hope to solve with this feature request. Of the crazy
ideas in the Meta page the one IMHO most needed is probably the simple
if-then-else, in pseudo-code:

if defined(parameter) then

wikicode using parameter

else

other wikicode, e.g. saying "not applicable", or simply blank

end

e.g. [[w:Template:Infobox_German_district]] - if the parameter
"Regierungsbezirk" isn't set, the whole table row should be left out.

gangleri wrote:

I like the ideas from [[meta:Extended template syntax]] and this discussion.

I want only to point out that if "'''some'''" minimal requirements are
implemented (recursion, comparision as "if ..." ...) it would be possible
to emulate a more complex "''programming environment''". I think that "1"
and "(empty)" would be enough to emulate additions, doing this
multiplications ... and finaly Ackermann (?).

This maight be / is a security issue and it raises the problem who would be
allowed to save / test these constructs, also how the templates are
verified if only sysops may save such templates and how arbirary
combinations of all available templates could harm the system.

Some years ago the only way to implement an application for a real buggy
measurement equipment was to analyse all its "inherent functions" and
implementation constraints (memory limitations, overruns). According to
the "documentation" it could not do c:=a+b but it could doo a++, if's,
loops and triggers. That was sufficient to implement a state machine
triggered by events.

A solution would be to use [[commons:]] as THE ONLY SOURCE from where
templates can be shared as this is done with images in 1.4-cvs and limit
such syntax to commons: only. On the other hand this would meen also
required nationalisation (at [[commons]]) and additional complexity of
templates.

Regards Reinhardt

with conditionals, loops and recursion this would indeed become a programing
language of turing-powers. While this would be cool for some reasons (especially
if...then...else would be useful), it would also be hard to avoid infinite loops
and such. I think that this would be overkill for now.

I would suggest the following: allow advanced parameter expansion as bash does.
Here is an excerpt vom man bash:

${parameter:-word}
       Use  Default  Values.  If parameter is unset or null, the expan-
       sion of word is substituted.  Otherwise, the value of  parameter
       is substituted.
${parameter:=word}
       Assign  Default  Values.   If  parameter  is  unset or null, the
       expansion of word is assigned to parameter.  The value of param-
       eter  is  then  substituted.   Positional parameters and special
       parameters may not be assigned to in this way.
${parameter:?word}
       Display Error if Null or Unset.  If parameter is null or  unset,
       the  expansion  of  word (or a message to that effect if word is
       not present) is written to the standard error and the shell,  if
       it is not interactive, exits.  Otherwise, the value of parameter
       is substituted.
${parameter:+word}
       Use Alternate Value.  If parameter is null or unset, nothing  is
       substituted, otherwise the expansion of word is substituted.

by just using {{{...}}} instead of ${...}, this could be used as a advanced
syntax for parameter expansion and would suffice in most cases that are now
problematic. Also i belive this would be fairly easy to implement.

egil wrote:

Sorry to be part of the choir, but not making undefined template arguments
appear as empty surely must considered a bug. The current behaviour serves no
purpose. (The other enhancements suggested here are fine, but they are enhancements)

avarab wrote:

(In reply to comment #9)

Sorry to be part of the choir, but not making undefined template arguments
appear as empty surely must considered a bug. The current behaviour serves no
purpose. (The other enhancements suggested here are fine, but they are

enhancements)

They serve the purpose of showing you that you made a syntax error, just as [[]]
does.

avarab wrote:

*** Bug 2299 has been marked as a duplicate of this bug. ***

gangleri wrote:

[[de:Benutzer:Gangleri/tests/Yiddish at wikipedia]]
shows a workaround to reduce the handling to a minimum
note: this is not a full substitute of bug 364

The datas are in [[de:user:Gangleri/tests/Yiddish (template)]].
this includes for each line

EXT1=SEEALSO/EXT1INFO=EXT2=LINKS/EXT2INFO=EXT3=SOURCES/EXT3INFO=EXT4=CATEGORIES/EXT4INFO=

if a value should be specified the "/" character should be removed and the
parameter is "activated"

Regards Reinhardt [[user:gangleri]]

kjosmoen wrote:

Patch for Parser.php for allowing default values

attachment Parser.php.patch ignored as obsolete

kjosmoen wrote:

I was really missing this bug, so I wrote a patch that will allow you to use default values. Here's the syntax:
{{{Variable name|default=Default value}}}

The default value can also be a template, as such:
{{{Variable name|default={{Default value}}}}}

I haven't been able to assess how much of a performance penalty it puts on the wiki yet, so be careful. Also, can someone check and see if there's
any security problems with my patch? Anyway, I hope this will be useful to someone.

kjosmoen wrote:

Seems my patch doesn't work with 1.5 beta3. I'll post a new patch here when I have it figured out.

kjosmoen wrote:

Apparently, the patch worked fine. It was a different problem leading me to believe the patch didn't work. My bad.

French wikipedians got a hack for that. I translated the "documentation"
in english. It's available on the english wikipedia:

http://en.wikipedia.org/wiki/Template_talk:Ifdef

Contact Aoineko & R for details.

kjosmoen wrote:

Patch for Parser.php for allowing default values, take 2

Here's a new patch for allowing default values. It solves some problems that I
had with the first version, and should also be much more efficient. As with the
first patch, it allows using templates as default values, but the syntax has
changed a little. (In order to make as little changes as possible elsewhere.)

Usage:
{{{Parameter name &default=Default parameter value}}}
or, with templates as default value:
{{{Parameter name &default={{Default parameter value template}} }}}

Please note the space between the last brackets when using a template as
default value. Without that space, the parsing will be wrong.

Good luck :) I hope someone will find this useful.

attachment Parser.php.patch ignored as obsolete

avarab wrote:

(In reply to comment #18)

Created an attachment (id=699) [edit]
Patch for Parser.php for allowing default values, take 2

Here's a new patch for allowing default values. It solves some problems that I
had with the first version, and should also be much more efficient. As with the
first patch, it allows using templates as default values, but the syntax has
changed a little. (In order to make as little changes as possible elsewhere.)

Usage:
{{{Parameter name &default=Default parameter value}}}
or, with templates as default value:
{{{Parameter name &default={{Default parameter value template}} }}}

Please note the space between the last brackets when using a template as
default value. Without that space, the parsing will be wrong.

I took a look at the Parser.php code earlier today to check how difficult it
would be to implement this, and I found that it would be a bit harder if I used
syntax like {{{value|default}}}, however that syntax (using |) is a logical
continuance of the current template syntax and introducing something like "
&default=" which isn't used anywhere else would complexify the syntax.

Point being: great start, but it would be awsome if you could make a version
that uses the pipe syntax.

kjosmoen wrote:

(In reply to comment #19)

I took a look at the Parser.php code earlier today to check how difficult it
would be to implement this, and I found that it would be a bit harder if I used
syntax like {{{value|default}}}, however that syntax (using |) is a logical
continuance of the current template syntax and introducing something like "
&default=" which isn't used anywhere else would complexify the syntax.

Point being: great start, but it would be awsome if you could make a version
that uses the pipe syntax.

Yes, using {{{value|default}}} was what I wanted to use, and tried to use. It worked excellent, until I put a parameter inside a table. The
result was that the table parsing code split up the {{{value|default}}} code, making it useless. In the interest of making a fix fast, I
chose to use a syntax that wasn't used anywhere else so that I could keep the complexity down. I really didn't want to risk having to
rewrite half of the Parser.php file in order to introduce another exception case, though this would most definitely be the preferred way.
Maybe I'll get to it one day, but it's probably not going to happen soon. :-/

kjosmoen wrote:

Patch for Parser.php for allowing default values, take 3

Here's a minor edit to the previous patch, and it seems to work just fine so
far, and it follows the mediawiki syntax:
{{{Parameter|Default value}}}
or
{{{Parameter|{{Default template}} }}}

I hope this works well, and it would be nice with some feedback. Also, I hope
to see this included in the 1.5 release. ;-)

attachment Parser.php.default-parameter.patch ignored as obsolete

  • Bug 3363 has been marked as a duplicate of this bug. ***

alarm wrote:

(In reply to comment #21)

Created an attachment (id=738) [edit]
Patch for Parser.php for allowing default values, take 3

Here's a minor edit to the previous patch, and it seems to work just fine so
far, and it follows the mediawiki syntax:
{{{Parameter|Default value}}}
or
{{{Parameter|{{Default template}} }}}

I hope this works well, and it would be nice with some feedback. Also, I hope
to see this included in the 1.5 release. ;-)

This patch would be a very nice addition to wiki, but it still has some flaws - syntax {{{{{param}}}}} no longer works, but it is widely used in
Wikipedias (to specify name of included template as parameter), so many templates can be broken.
Also a minor flaw -{{{Parameter|{{Default template}} }}} does not work very well - template is not expanded, so {{Default template}} is shown in
the page.

avarab wrote:

A different way to do it

attachment defaultargs.patch ignored as obsolete

avarab wrote:

(In reply to comment #24)

Created an attachment (id=903) [edit]
A different way to do it

I accedentally hit commit.

There are a few issues with this patch, first it needs to not run on save-time
so that stuff like {{{foo|bar}}} isn't converted into "bar", I made a hack to
avoid this by checking for $this->mTitle->getNamespace() != NS_TEMPLATE so it
doesn't do the default argument replacement if the text is in the template
namespace.

If there was some bool member varible in the parser that defined whether or not
the parser was saving text to the database I could use that and there wouldn't
be a problem.

avarab wrote:

A combonation of the two

The following is a merge of the two patches using your changes to
replaceVariables() and my function for argSubstitutionWDefaults(), it seems to
work just fine for at least the follwing input (saved to a template)

{{{1}}}
{{{argument|[[foo|bar]]}}}
{{{argument2|{{PAGENAME}}}}}

I'm applying this to HEAD

Attached:

rowan.collins wrote:

(In reply to comment #26)

I'm applying this to HEAD

Note: Brion reverted the change because HEAD currently runs the Wikimedia
projects, and they all broke.

alarm wrote:

Fix for bug 3526 includes default argument and template in template features, so probably this should be marked as resolved

robchur wrote:

Might I be correct in thinking that Avar's done something in the not-too-distant
past which causes this one to be FIXED?

netoholic wrote:

This feature has given rise to a number of conditional functions (see en:wikipedia's [[Category:If
Templates]] and [[Category:Boolean Templates]]). From a practical standpoint, I don't see where,
unless it is the intention to support conditionals, that any normal use of templates would be
harmed by the following changes:

Default parameters - There should be no more than 2 levels of evaluation of a parameter default.
{{{A|text}}}, {{{A|{{{B}}}}}}, and {{{A|{{{B|text}}}}}} should work, but {{{A|{{{B|{{{C}}}}}}}}}
and deeper should not. Additionally, parameter defaults should not accept template calls in the
form of {{{A|{{template}}}}}}. That would be an avenue to skirt the restriction.

Template nesting (WP:AUM) - The parser should not evaluate more than one level deep on any
template. For example, if a page uses Template:X, which in turn has a call for Template:Y, it
works, but if Template:Y in turn calls Template:Z, then Z is not evaluated. This prevents the more
outrageously complex meta-templating practices, but gives a little flexibility in certain areas.

gangleri wrote:

(In reply to comment #30)

This feature has given rise to a number of conditional functions (see

en:wikipedia's [[Category:If

Templates]] and [[Category:Boolean Templates]]).

They where not there because this was not possible in the past.

Default parameters - There should be no more than 2 levels of evaluation of a

parameter default. ...

This is a personal viewpoint. It is against general concepts of software design
to hardcode such limitations. Remember: "640 kB should be enough."
Restrictions, limitations, extensions, activation of features is up to the
individual projects.