Extension talk:VariablesExtension

From MediaWiki.org

Jump to: navigation, search
The following discussion has been transferred from meta.wikimedia.org.
Any user names refer to users of that site, who are not necessarily users of MediaWiki.org (even if they share the same username).

Contents

[edit] Variables and Conditional Parser Functions

It must be noted that everything in conditionals gets executed (though only one result gets displayed). Because of this, every instance of #vardefine will always get executed, regardless of to what the conditional gets evaluated.

Given the following:

{{#vardefine:variable|value}}{{
#ifeq:
    {{#var:variable}}|
    value|
    {{#vardefine:variable|nextvalue}}|
    {{#vardefine:variable|prevvalue}}
}}

{{#var:variable}} gives prevvalue.

Instead you have to nest the conditional inside #vardefine:

{{#vardefine:variable|value}}{{
#vardefine:variable|
    {{#ifeq:
        {{#var:variable}}|
        value|
        nextvalue|
        prevvalue
    }}
}}

In this case, {{#var:variable}} gives nextvalue.

Sledged 16:12, 24 October 2006 (UTC)

[edit] Multiple assignments

It would be good if this extension allowed multiple assignments. Say I have a template data that contains a=1|b=2 . I call {{usedata|data}} and usedata gets one template-variable, a, with value 1|b=2. If I could make data say a=1,b=2 and usedata could call variablesextension to set both variables at once, that would be useful.--201.216.136.95 18:24, 10 January 2007 (UTC)

[edit] Bugzilla request

The bug requesting this to be added for the big sites (wikipedia, etc.) is bugzilla:8570. If you really want these functions, go (register and) vote for that bug. If you have an concern, that bug would also be an appropriate place to express it.--201.216.136.95 18:24, 10 January 2007 (UTC)

[edit] MediaWiki version 1.9

How is the compability with MediaWiki version 1.9?

[edit] use of undefined variables

Sometimes you want to use a variable which has not been set before and you expect it to return an empty string. I suggest to change the code of function "varf" as follows:

 function varf( &$parser, $expr = '' ) {
   if (isset($this->mVariables) && array_key_exists($expr,$this->mVariables)) return $this->mVariables[$expr];
   return '';
 }
84.58.192.102 09:11, 28 January 2008 (UTC)

[edit] Number incrementing through page

I'm trying to write a template, two templates in fact, that will increment a number through a page, ie.

{{@@}}
{{@}}
{{@}}
{{@}}
{{@@}}
{{@}}
{{@}}

@@ starts the counter at 1 and prints it and @ increments the number and prints it.

I expect the following to appear:

1 2 3 4 1 2 3

But I get the following:

1 2 2 2 1 2 2

I'm using the following code for the templates.

Template: @@

{{#vardefine:n|1}}{{#var:n}}

Template: @

{{#vardefine:n | {{#expr:{{#var:n}} + 1}}}}{{#var:n}}

Thanks.

--Wahooney 14:05, 11 April 2008 (UTC)

Your problem is that variables don't persist across templates, so you need to pass the value of n from @@ to @. So, your page needs to be:
{{@@}}
{{@|{{#var:n}}}}
{{@|{{#var:n}}}}
{{@|{{#var:n}}}}
{{@@}}
{{@|{{#var:n}}}}
{{@|{{#var:n}}}}
--Snuck 05:31, 15 April 2008 (UTC)
  • On a 1.12 version of MediaWiki, I get 1 2 3 4 1 5 6 which is not what was expected, but:
{{@@|{{#var:n}}}}
{{@|{{#var:n}}}}
{{@|{{#var:n}}}}
{{@|{{#var:n}}}}
{{@@|{{#var:n}}}}
{{@|{{#var:n}}}}
{{@|{{#var:n}}}}

gives (to me): 1 2 3 4 1 2 3 . --Nbrouard 14:38, 25 June 2008 (UTC)

{{@@|}}
{{@|}}
{{@|}}
{{@|}}
{{@@|}}
{{@|}}
{{@|}}

is also working with the new parser. --Nbrouard 15:14, 26 June 2008 (UTC)

[edit] Multiple inclusions in a template, still counting

Let funcone be the following template:

{{@|}}
{{@|}}
{{@|}}
{{@|}} Inclusion of content
{{{content}}}
Redefining n for second inclusion
{{#vardefine: n|36}}
{{@|}}
{{@|}}
Second inclusion of content
{{{content}}}
after second content

Trying on the following wiki text:

Testing Funcone
{{@@|}}
{{funcone|content=
{{@|}}
{{@|}}
{{@|}}
{{@|}}
{{@|}}
}}
{{@|}}

I get:

Testing Funcone 1 2 3 4 5 Inclusion of content 6 7 8 9 10 Redefining n for second inclusion
37 38 Second inclusion of content 6 7 8 9 10 after second content 39

instead of:

Testing Funcone 1 2 3 4 5 Inclusion of content 6 7 8 9 10 Redefining n for second inclusion
37 38 Second inclusion of content 39 40 41 42 43 after second content 44

Any idea to make substitution earlier? --Nbrouard 13:10, 30 June 2008 (UTC)

Mmmh, until now I thought the default behaviour is, that a variable is global (global means all over the article for all templates which are called from the article). I often use a variable with very special name like "countCalls" as "global variable" which is defined in template X. In another call of Template X or another Template Y I can see if the template was already called in this article or not.
Perhaps it should be possible to define local variables {{#vardefine|name|value}} and global vars like {{globalvardefine:name|value}}. So the default would be local variables which are only available at the current call of the template or on the article page but NOT in sub-calls of templates.
On the other hand, perhaps default behaviour should be global variable like it's now in the current version of MW so you would have {{#localvardefine:name|value}} for local ones and {{#vardefine:name|value}} for global ones. Than you could call it with {{#localvar:name}} btw. {{#var:name}}. Global variables are also good for using them as a kind of template parameters in very complex templates which work with semantic forms arraymap function or something like that where you can call a template but can't give common template parameter values.
Normally I would say that local must be the default behaviour of such a variable. But the compatibility to the oder versions of these plugins should be as big as possible and it looks like currently (MW 1.13) all variables are “global”. But perhaps here should be a cut and everybody who wants to use the new version perhaps must change some templates. I hope this is going to be implemented, would be very useful and it would ensure that we could avoid such strange behaviours in the future. --Danwe 22:04, 11 February 2009 (UTC)
I thought about page global variables again and I just came to the conclusion that additional functions to define global/private variables would be to much functions. better would be to define a prefix in globalsettings.php (or an default prefix) which defines global or private variables. The default (private or global) could be defined in the globalsettings as well, so the compatibility to the actual version would be given to each wiki.
{{#vardefine:<GLOBAL>name |value}} for example could define a page global var you can use it with {{#var:<GLOBAL>name}}. Each var which is defined without the prefix would be private by default.
An alternative would be a third parameter in #vardefine like {{#vardefine:name|value|global}}, the default behaviour should be configurable in the localsettings.php too.
I prefer the first method because I already use the prefix <GLOBAL> for variables which I use as global vars yet. But the main reason is that this method has no name conflicts like a private and a global var with same names. --Danwe 11:12, 28 March 2009 (UTC)

[edit] Complications

The wiki I work on is on the brink of updating from 1.11 to 1.13 (two days from now). We use a huge number of variables, mostly so we can get data in and out of templates. Some of our templates set many variables meanwhile other templates utilize multiple dynamic variables. We use the variables and templates to centralize information and make editing easier on the user. They can utilize a template that accesses many variables and not have to deal with the very ugly logistics of where the data is coming from.

If you need some examples:

What can I do so that I literally don't have to rework 50 to 100 templates and thousands of articles? -- BlindWanderer 21:54, 21 October 2008 (UTC)

[edit] Default Value

Am I missing how to declare a default value when recalling it? Or does that need to be defined only when defining it? 68.226.0.35 16:58, 8 December 2008 (UTC)

It's not possible to use a default value like {{#var: myVar |defaultvalue if not definded or void}}. I think that would be a great improvement. I really often have to use something like: {{#var:myVar}} what is much more code than only {{#var:myVar |alternativeValue}} would be!
Please, would you add this feature into the plugin? --Danwe 21:46, 11 February 2009 (UTC)
Looks like there is no one left who's developing this plugin. So I decided to release a new version 1.2 which contains this feature. --Danwe 12:53, 28 March 2009 (UTC)

[edit] Use in Wikiprojects

Is it planned to install this extension in Wikipedia and other projects too? It would be extremelly useful for creating templates. Nevertheless, now it doesn't work. --Petrus Adamus 22:06, 19 February 2009 (UTC)

I think this is the wrong place to discuss this. Perhaps you should ask that on the wikipedia project page. But I don't think they will use it because every new extension could be a security hole and maybe they are afraid of it would be to complicated and to much for some users. --Danwe 17:01, 21 February 2009 (UTC)
It has been requested here, but the answer was (and still is) "no." —Sledged (talk) 23:47, 25 February 2009 (UTC)

[edit] Caching bug?

I think I've found a bug in the extension, using version 1.1 on MediaWiki 1.13.3. Assuming you have ParserFunctions installed, say you have a template called Startthevariable containing {{#vardefineecho:i|1}} and a template called Increasevariable containing {{#vardefineecho:i|{{#expr:{{#var:i}}+1}}}}. Let's say you then run this code in a page:

{{startthevariable}}
{{increasevariable}}
{{increasevariable}}
{{increasevariable}}
{{increasevariable|}}
{{increasevariable}}
{{increasevariable}}
{{increasevariable|}}
{{increasevariable|a}}
{{increasevariable|b}}
{{increasevariable|a}}
{{increasevariable|c}}
{{increasevariable|}}
{{increasevariable|}}
{{increasevariable|}}
{{increasevariable|}}
{{increasevariable}}
{{increasevariable}}
{{increasevariable}}
{{increasevariable}}

The result for this should ideally be 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20. However, the actual result comes out as 1 2 2 2 3 2 2 4 5 6 7 8 9 10 11 12 2 2 2 2. Note the various ways Increasevariable is called, some with a |, and some actually specifying a parameter after it. Also note that it does not have any place to accept those parameters in the template itself. So, to recap, if it isn't called with a parameter, it will always return what it returned the first time it was run. If it is called with a parameter, no matter what the parameter is, it will increment it how it should have been incremented in the first place. It won't cache even if you run it with the same parameter multiple times.

Sorry if this seems a little wordy or weird, or if I haven't explained myself well enough. 98.15.203.22 23:30, 21 March 2009 (UTC)

This is exactly the same what we discussed above under Number incrementing through page.
But this is very strange it's obviously a bug!
My explenation for this phenomenon is that Mediawiki simply calculates the content of templates without parameter one thime and after that all the calls for this template without any parameter getting replaced. After that alle the templates with parameters are calculated one after another because they could have dynamic contents because of the parameters. Template calls without parameter normaly have the same text because there is no variable content inside them. At least untill the variables extension came.
Try the following code as code of increasevariable:

{{#var:i}} '''{{#vardefineecho:i | {{#expr:{{#var:i}}+1}} }}''' &#123;&#123;{{#ifeq:{{{1|<%&>}}}|<%&>|Increasevariable|Increasevariable&#124;{{{1|}}}}}&#125;&#125;<br/>

with this code:
{{#vardefine:i | 1}}
{{increasevariable}}
{{increasevariable}}
{{increasevariable|}}
{{increasevariable}}
{{increasevariable}}
{{increasevariable|}}
{{increasevariable|a}}
{{increasevariable|b}}
{{increasevariable|c}}
{{increasevariable|}}
{{increasevariable|}}
{{increasevariable}}
{{increasevariable}}
{{increasevariable}}
the result is:
1 2 {{Increasevariable}}
1 2 {{Increasevariable}}
2 3 {{Increasevariable|}}
1 2 {{Increasevariable}}
1 2 {{Increasevariable}}
3 4 {{Increasevariable|}}
4 5 {{Increasevariable|a}}
5 6 {{Increasevariable|b}}
6 7 {{Increasevariable|c}}
7 8 {{Increasevariable|}}
8 9 {{Increasevariable|}}
1 2 {{Increasevariable}}
1 2 {{Increasevariable}}
1 2 {{Increasevariable}}
The first number shows the value of #var:i before the template call, the second the value after the call. Behind that you can see the exact template call.
This shows us that the #vardefine and #expr functions itself woriking as expected. I think actually variables only should be used inside one template or page but not as page global variables. I'd love to see such global page variables working like expected. It would be very helpful for some issues. Adding a (void) parameter to any template wich won't need a parameter should help too. --77.191.250.232 02:15, 28 March 2009 (UTC)

[edit] Implementation of variable scopes like private, public and static

I am just about to implement the above mentioned private and public variables scope. But there is a big problem and I found no possibility to get rid of it:

I am just able to add the hook Manual:Hooks/BeforeParserFetchTemplateAndtitle into the class which tells me when the parser calls a template, I also can get the name of the template so I know when I have to enter into a new private scope or something. But I still can't find a hook which tells me when the parser is thru with a template. But I need to know wich part of the template the parser handles when he found an variables parserfunction so I could take the variable from the right variables scope. Any ideas? --Danwe 23:32, 11 May 2009 (UTC)

[edit] varexists function

A function with which it's possible to check if a variable already is defined would be helpful. You can use {{#if: {{#var:i}} |defined |void/undefined}} but it could be possible that a variable is defined but only has an void content, it's not possible to differ between void but defined and undefinet variables yet. --77.191.148.245 10:54, 28 March 2009 (UTC)

I just added this and released a new version 1.2 with varexists function and the possibility to add a parameter to var function which contains a string which is the output when the variable is void or undefined. --Danwe 12:50, 28 March 2009 (UTC)
The #varexists: function of the 1.2 version seems to have a slight bug, in that it assumes there is at least one variable already defined on your page (to have triggered creation of the mVariables array). Invoking it on a page where there are (yet) no variables defined generates a PHP error message complaining about the second argument to array_key_exists(). See #Accept Command Line Args below for the code. --Paul Lustgarten 20:45, 30 March 2009 (UTC)
Thanks, I just added this little change in the extension code. --Danwe 18:27, 6 April 2009 (UTC)

[edit] Accept Command Line Args

In using this extension, we find it useful to have the option of defining variables within the page's URL (e.g., tacking on "&fish=swimming&cow=moo" to define the variables "fish" & "cow" to have the values "swimming" and "moo", respectively). This is like assimilating the function of the #arg: parser function from the Extension:DynamicFunctions extension.

Also, specific to the new 1.2 version, we find some boundary conditions where the mVariables array is referenced before being defined, so propose that it be automatically defined as part of the class.

Here are the modified portions of the v1.2 Variables.php code incorporating these changes, for your consideration:

class ExtVariables {
	var $mVariables = array();
 
	function varf( &$parser, $expr = '', $defaultVal = '' ) {        
		global $wgRequest;
		if (!array_key_exists($expr, $this->mVariables)) {
			$val = $wgRequest->getVal($expr);  # pull value from command line, err, URL
			if ($val != NULL) {
				$this->mVariables[$expr] = $val;
			}
		}
		if (array_key_exists($expr, $this->mVariables)) {
			return $this->mVariables[$expr];
		}
		return $defaultVal;
	}
 
	function varexists( &$parser, $expr = '' ) {
		global $wgRequest;
		if (!array_key_exists($expr, $this->mVariables)) {
			$val = $wgRequest->getVal($expr);  # pull value from command line, err, URL
			if ($val != NULL) {
				$this->mVariables[$expr] = $val;
			}
		}
		return array_key_exists($expr, $this->mVariables);
	}
}

This extends the #var: and #varexists: functions to pull a variable's definition from this page's URL (if a definition is present there), if that variable is not already defined in the mVariables array.

It also guarantees that the mVariables array always exists, so we can successfully call #varexists: on a wiki page in which no variables have yet been defined. --Paul Lustgarten 20:55, 30 March 2009 (UTC)

I'am not sure if I understood that poperly. You want to use page parameters to define vars. But what if you'd like to define a var called action which is a page parameter which already has a meaning on MW? Isn't a syntax like &var_fish=swimming&var_cow=moo a better one?
Your code is not working for me, I tried &fish=swimming&cow=moo in the url and added {{#var:fish|fish not defined!}} and {{#var:cow|cow not defined!}} to the page. The result was the alternative text. Shouldn't be the result swimming and moo? --Danwe 18:40, 6 April 2009 (UTC)
The first character of the query portion of a URL needs to be a "?", not a "&". Try adding ?fish=swimming&cow=moo to the URL.
--Paul Lustgarten 15:00, 17 April 2009 (UTC)
There is also still another bug in your modified code. Void variables with default values like {{var:definedbutvoid |defaultvalue}} return a void string instead of defaultvalue. Per definition in the current version 1.2.2 the output for defined but void variables AND for undefined variables should be defaultvalue. --Danwe 14:03, 15 April 2009 (UTC)
Danwe - Those are good points you raise.
I, likewise, had run into the collision with internally-used variable names such as "action". The solution I have implemented now works, but yours (using a "var_" prefix on each variable) is probably better. Part of the challenge (which I have now solved but hadn't when I first posted this) is how to change the core wiki code itself (in includes/Title.php) so that one can provide variables as part of an internal page link - the best syntax for which I've been able to come up with being this:
  [[Some page ?fish=swimming&cow=moo|Nice name for what that does]]
(I'd love to simplify/improve on that syntax somehow - any suggestions?.) And that then motivates changing includes/parser/Parser.php to remove the suppression of selflinks, so that we can even do this:
  [[{{PAGENAME}} ?fish=swimming&cow=moo|Nice name for what that does]]
Combined with some #if:'s, we can start to craft some interestingly adaptive pages!
And I hadn't noticed that refs to a void var return its default value. I'm working to meet a deadline these next couple weeks (to demo the stuff I'm building for which this is one of the building blocks, in fact), and will post a new & improved set of changes after I'm clear of that. (And I fixed my email prefs on this wiki so I'll be notified of comments; I didn't see yours until yesterday :-( )
--Paul Lustgarten 15:00, 17 April 2009 (UTC)

[edit] dead and unused code

  1. Why is "author" defined twice?
  2. Why is "$wgMessageCache" included twice but never used?

I think the answer to these questions is that people forgot to remove them. -- BlindWanderer 16:03, 11 May 2009 (UTC)

I think I forgot to remove the first one perhaps. Removing $wgMessageCache shouldn't be a problem, don't know why this was declared perhaps it was used before. --Danwe 23:23, 11 May 2009 (UTC)

[edit] Minor bug: Undefined index in Variables.php on line 33 (function varf)

Replace

    function varf( &$parser, $expr = '', $defaultVal = '' ) {        
        if ( $this->mVariables[$expr] != '' ) {
            return $this->mVariables[$expr];
        } else {
            return $defaultVal;
        }
    }

by

    function varf( &$parser, $expr = '', $defaultVal = '' ) {
        if ( array_key_exists($expr, $this->mVariables) && $this->mVariables[$expr] != '' ) {
            return $this->mVariables[$expr];
        } else {
            return $defaultVal;
        }
    }

--F.trott 09:27, 28 August 2009 (UTC)