Extension talk:Variables

About this board

You can use this board to submit questions and requests concerning the Variables extension. If you want to participate in development, please pick a task on Phabricator or create a new one,

Archive

163.62.112.95 (talkcontribs)

Can i retrieve pages var values when exporting pages and importing them to another mediawiki ?

Reply to "Export pages"

Deprecated hook (InternalParseBeforeSanitize)

12
Cavila (talkcontribs)

This extension needs an update for 1.35.

Use of InternalParseBeforeSanitize hook (used in VariablesHooks::onInternalParseBeforeSanitize) was deprecated in MediaWiki 1.35.

(used for '#var_final' parser function)

MGChecker (talkcontribs)
Cavila (talkcontribs)

Thanks. Personally, I can live without #var_final, but it's good to have things cleared up.

MGChecker (talkcontribs)

The thing is, apparently there are not even plans for hook removal. And complete Parsoid compatibility is out of reach anyway without a complete rewrite, which might very well be impossible and I won't do.

Kghbln (talkcontribs)

So in the end the code for #var_final will be removed from the extension. This does make sense or is it better to do so once the hook was removed completely from MediaWiki core? I am assuming here that this parser function still works on MW 1.35.x though I may be wrong.

MGChecker (talkcontribs)

The problem lays deeper.

According to the points of the parsing team, this hook might actually continue to work indefinitely even though the deprecation.

On the other hand, I do not feel like listening to these deprecations will help us in the long run, because the whole principle of this extension is uncertain in the context of Parsoid.

Kghbln (talkcontribs)

Thanks for the information. Still I do not know if the parser function will work or not for 1.35. I guess this is the question people will ask in the short run.

Apparently in the long run the situation appears to not look to bright.

MGChecker (talkcontribs)

It will work, but there will be deprecation notices on upgrade.

MGChecker (talkcontribs)

It would be possible to make deprecation warnings disappear, I think, by migrating back to InternalParseBeforeLinks and sanitize inside this extension. However, the only reason InternalParseBeforeLinks is not deprecated yet, is its use inside SemanticMediaWiki, which is even more widely used than Variables. I could not achieve a similar exception for Variables, but might have got one if I would have been aware of this process earlier.

It stands to reason that the migration to InternalParseBeforeLinks would bring no fruit anyway, since it will probably be removed at the same point as InternalParseBeforeSanitize. I will try averting a removal of the hook from the old parser if possible, pointing out my discussions with the Parsing-Team regarding this point, but I can not promise anything.

Kghbln (talkcontribs)

Thank you! I appreciate your effort!

Cavila (talkcontribs)

Thanks for looking into this!

MGChecker (talkcontribs)
Reply to "Deprecated hook (InternalParseBeforeSanitize)"

Calling #var on a different template?

2
Summary by MGChecker

This is possible.

119.92.13.245 (talkcontribs)

I'm pretty new to this so it's still confusing to me.

So I have template1 and template 2. Template 1 does usd=12345, template 2 on the other hand has prize=5000. Is it possible to do match between these two tho they're on two different templates? I was trying the following but can't make it work and I'm stuck.

{{#vardefine:{{{result}}}|{{#expr:{{#var:prize}}*{{#var:usd}}}}}}

Dinoguy1000 (talkcontribs)

If the current template designs allow for it, I would recommend explicitly passing the needed values as template parameters, instead of relying on Variables. Not only does this bypass the problems you're facing now, but it also avoids a whole host of maintenance and code comprehension issues into the future.

How to transclude invisible text?

1
Summary by MGChecker

Variables is not involved into HTML sanitization, out of scope.

Johnywhy (talkcontribs)

If template contains:

<nowiki><!-- this is a comment --></nowiki>

then the whole thing gets rendered as visible text on the host page.

If template contains:

<!-- this is a comment -->

then none of it gets transcluded.

Really just want to put some invisible text on the host page-- doesn't have to be an HTML-comment.

This doesn't get transcluded either:

<span style="display:none">Hidden Span</span>

Distribution missing "extension.json"

2
Summary by MGChecker

Read the docs.

أحمد (talkcontribs)
Kghbln (talkcontribs)

The docu states: "To users running MediaWiki 1.30 or earlier", so for MW 1.30 this extension has to be invoked via require_once ....

Can you query the contents of these variables for a given page id using the API?

4
Summary by MGChecker

No, but a feature like this could be added and is tracked in T191575.

174.97.28.4 (talkcontribs)
Danwe (talkcontribs)

That's not supported by the extension. You'd need to write a new extension on top of Variables to achieve this but it's not impossible.

MGChecker (talkcontribs)

It's an interesting thought to save the distinct var_final values in page_props to make it queryable… Maybe I will put some effort in implementing this additional functionality at some point in the future.

MGChecker (talkcontribs)

Creating a variable using vardefine adds to extra space in wiki

4
Summary by MGChecker

Beware of trailing whitespace.

84.46.53.105 (talkcontribs)

I am using the variable extension to us define some variables which I use later in my wiki. But adding these variables adds extra undesirable space at the top of the wiki. Am I missing something?

Cavila (talkcontribs)

Did you use newlines? Avoid them, wrap a div around your vardefines with display:none, or comment out each line break (I just tried to demonstrate this with pre-tags, but MediaWiki messed up my code).

84.46.52.252 (talkcontribs)

Cool! Thanks Cavila. display:none did the trick. :)

Dinoguy1000 (talkcontribs)

Just to add one more option, my preferred method is to place the closing braces for each vardefine on the same line as the opening braces for the next vardefine, e.g.

{{ #vardefine: var1 | foo
}}{{ #vardefine: var2 | bar
}}{{ #vardefine: ...

how to undefine a previously-defined variable?

8
Summary by MGChecker

There are no plans to support undefining a previously defined variable for minuscle performance benfits.

2600:1700:1B0:BA0:A82F:CAEB:C7F7:8FAF (talkcontribs)

I have a template whose behavior changes based on the existence of a variable. It uses {{#varexists...}} for this purpose. I'd like to be able to define/undefine this variable multiple times, e.g.

#vardefine:debug_flag}}
{{My Template}}
{{#varundef:debug_flag}}
{{My Template}}

But currently there is no way that I know of to undefine a variable after defining it. --~~~~

Dinoguy1000 (talkcontribs)

To be honest, I've never had any use for #varexists; instead, I just define variables with a dummy value (e.g. {{ #vardefine: foo | 1 }}) and then test if the variable has a value with an #if. That way, if I need to later undefine the variable, I can simply clear its value via {{ #vardefine: foo }}.

194.230.155.242 (talkcontribs)

It is a feature that this is not possible, thus a definition of a variable can never be done.

Instead, I recommend Dinoguys approach of checking if a variable is empty. --MGC

2600:1700:1B0:BA0:988E:1F3E:9575:814C (talkcontribs)

What do you mean by "it is a feature"? What is the advantage of {{#varundef}} not existing? I guess I will have to do it the way Dinoguy1000 suggested. Equivalently, no one ever needs to use {{#varexists}} -- they can always use {{#if}}. But then, why does {{#varexists}} exist?

Dinoguy1000 (talkcontribs)

I would have to check this, but at a glance I'd guess that {{ #varexists: foo | ... }} is very slightly more efficient than {{ #if: {{ #var: foo }} | ... }} (at the very least, it does make the intention of the code clearer). I wouldn't say to avoid using #varexists entirely, but to use it only for variables that are fully static flags (i.e. the variable is defined - or not - in only one place in the template, and it isn't touched afterwards except to check for it). Certainly, now that I've taken a closer look and thought about it a bit, I'll be going over my own templates and using it where appropriate (after testing to see how it stacks up to #if: #var:, in terms of template limits, at least).

2600:1700:1B0:BA0:2D95:883D:C0D7:C5DC (talkcontribs)

I wouldn't recommend you change all of your templates for an infinitesimal efficiency improvement. You will be giving up the option of doing what I mentioned in my initial post. If you have a thousand references to your template on a page, and you only want the variable to be defined for the first half of them (maybe you're doing a binary search), you won't be able to do it.

Dinoguy1000 (talkcontribs)

I'm keenly aware of the gotcha's here, believe me. The changeover would be to benefit code readability (and thus maintainability); any potential efficiency improvement (even an infinitesimal one) would just be a nice bonus.

Dinoguy1000 (talkcontribs)

Revisiting this now that I've looked a bit more into it: careful use of #varexists can save a significant amount on the NewPP parser report metrics (in particular "Preprocessor visited node count", "Post-expand include size", and "Template argument size"), over my go-to {{ #if: {{ #var: construction.

For example, this version of "Template:Chapter" on my wiki (the current version as of writing this, but it won't be for long), as used on the current version of the page "Dark Yugi (manga)" (where the template is transcluded 338 times), results in the following NewPP report:

NewPP limit report
Cached time: 20210907163321
Cache expiry: 1209600
Dynamic content: false
[SMW] In‐text annotation parser time: 0.017 seconds
CPU time usage: 4.748 seconds
Real time usage: 8.358 seconds
Preprocessor visited node count: 64228/1000000
Preprocessor generated node count: 60933/1000000
Post‐expand include size: 418313/2097152 bytes
Template argument size: 35083/2097152 bytes
Highest expansion depth: 17/40
Expensive parser function count: 0/100
Unstrip recursion depth: 1/20
Unstrip post‐expand size: 112756/5000000 bytes
Lua time usage: 2.450/20.000 seconds
Lua virtual size: 14.27 MB/50 MB
Lua estimated memory usage: 0 bytes

However, changing the first line in the template:

<includeonly>{{ #vardefine: $smw | {{ #var: $smw | {{ #if: {{ #show: }} | off | on }} }}<!-- standard implementation -->

to

<includeonly>{{ #varexists: $smw || {{ #vardefine: $smw | {{ #if: {{ #show: }} || 1 }} }}<!-- standard implementation -->

and line 40 from

}}{{ #vardefine: $chapter-name | {{ #ifeq: {{ #var: $chapter-mode }} | number || {{ #ifeq: {{ #var: $smw }} | on | {{ #show: {{ #var: $chapter-pagename }} |?English name }} }} }}

to

}}{{ #vardefine: $chapter-name | {{ #ifeq: {{ #var: $chapter-mode }} | number || {{ #if: {{ #var: $smw }} | {{ #show: {{ #var: $chapter-pagename }} |?English name }} }} }}

...results in the following report:

NewPP limit report
Cached time: 20210907165826
Cache expiry: 1209600
Dynamic content: false
[SMW] In‐text annotation parser time: 0.015 seconds
CPU time usage: 4.776 seconds
Real time usage: 8.623 seconds
Preprocessor visited node count: 63678/1000000
Preprocessor generated node count: 60933/1000000
Post‐expand include size: 417637/2097152 bytes
Template argument size: 35083/2097152 bytes
Highest expansion depth: 17/40
Expensive parser function count: 0/100
Unstrip recursion depth: 1/20
Unstrip post‐expand size: 112756/5000000 bytes
Lua time usage: 2.570/20.000 seconds
Lua virtual size: 14.3 MB/50 MB
Lua estimated memory usage: 0 bytes

Note in particular that "Preprocessor visited node count" dropped from 64228 to 63678, and "Post-expand include size" dropped from 418313 to 417637.

However, as things stand, I am unable to use this method in more places in "Template:Chapter", since other variables I'd like to use it on are always defined, and communicate meaningful state if they are empty (there is no way around this, since subsequent transclusions may store nonempty values to these variables, and then empty values again, and so on). For example, changing line 28 from

}}{{ #vardefine: $chapter-subseries | {{ #if: {{ #var: $chapter-series }}

to

}}{{ #vardefine: $chapter-subseries | {{ #varexists: $chapter-series

...would result in "Preprocessor visited node count" dropping further to 60641, and "Post-expand include size" dropping to 371846, but would not work correctly in some cases of multiple transclusions of the template on the same page, as explained above. However, you don't even need to look past $smw to find suboptimal behavior: because it can be defined but empty, it must be tested on line 40 via {{ #if: {{ #var: $smw }} ..., instead of being able to just use {{ #varexists: $smw ...!

This could be fixed in one of two ways: add a function to undefine a variable entirely, or add a way to test for variable existence that considers empty-but-defined variables to not exist (whether by a modification of #varexists, or the introduction of a new parser function).

(I am, of course, aware of Scribunto and Lua - and we do use modules for a number of things on the wiki already - but we currently only have one editor who is able and willing to develop and maintain modules for us, and they don't have much time to spend on the wiki; I've tried learning myself, but could never get the hang of it.)

would like to use #ifexpr: with #len: and #var:

8
Summary by MGChecker

Interactions of parser functions with references are complex, and unexpected behavior is unlikely to be fixed.

Gunnar.offel (talkcontribs)

I would like to use a expression to check a length.

{{#ifexpr:{{#len:{{#var:refs|}} }} > 10 | [..]

That provides no exeption, as far as good, but the

{{#len:{{#var:refs|}} }}

provides always 0 so the check doesn't work. Any Idea how to solve the issue or change the behavior?

____ i wrote the ask allready in Help_talk:Extension:ParserFunctions but maybe this point is the better choice.

Gunnar.offel (talkcontribs)

i tried also the given alternatives, but sadly they also doesn't work in my case. :S

MGChecker (talkcontribs)

Are you sure the refs variable is populated? If this is not the case, you get an empty string out of `refs`, matching your reports.

MGChecker (talkcontribs)

At least

{{#vardefineecho: refs | Tree }}
{{#ifeq: {{#var: refs }} | Tree | 1 | 0 }}

works properly for me, on the contrary to the reports on the ParserFunctions. Sadly, I have no wiki with StringFunctions and Variables at hand at the moment, so I can not reproduce your claims.

Dinoguy1000 (talkcontribs)

On my own wiki with ParserFunctions, StringFunctions, and Variables, I have never had any issue using the three together as described here. @Gunnar.offel: could you provide what versions of MediaWiki, Ext:ParserFunctions, and Ext:Variables your wiki has installed?

Dinoguy1000 (talkcontribs)

Actually, based on the name of the variable, is it meant to store references? Trying to work with <ref> tags with parser functions is difficult, because of the special parsing that takes place around them. If it's an option for you, you may have better luck using Scribunto/Lua for this instead.

Gunnar.offel (talkcontribs)

@MGChecker, if i use vardefineecho and also if i call the #var it outputs the wanted things. So i'm pretty sure, that i populate the variable. i just can't get it to work with the parser function.


@Dinoguy1000: sure, - MediaWiki 1.34.0 - ParserFunctions 1.6.0 - Variables 2.5.1 (d6ce860) 08:16, 4. Sep. 2019

Yes, the variable stores the references and it works, but at the moment not in the parser functions. actually i just want to hide an empty table and only show if content is available. That's a big gun on a little problem, sure but keeps me up for a better understanding how to use/solve the extension.

MGChecker (talkcontribs)

As Dinoguy said, this is properly a really hard problem. References are a really complicated feature, kind of using variables as internal counter as well, and being evaluated at a different time during parsing. This leads to many features of stock MediaWiki already to behave weird when used together with references – especially advanced syntax features offered by extensions.

What is properly happening here that the references are not populated at the (quite early) point during parsing when variables are evaluated in this logic. I do not know exactly what is happening, but trying to get the references at multiple points, at different parsing stages, is quite typical for problems related to references.

Hence, your references var is always empty for parser functions. On the other hand, variables not encapsulated into the template tree can properly evaluated properly.

Allowing more than 1000 caracters in Variables

6
Summary by MGChecker

Variables have no length limitation, but string functions do. Out of scope here.

2A01:CB15:258:1A00:3C42:E043:373C:AD79 (talkcontribs)

I encounter bugs when I seek to allocate a variable of more than 1000 characters. The error I get is (in french) :

<strong class="error">Erreur : la chaîne dépasse la limite maximale de 1 000 caractères.</strong>

meaning the string exceedes the maximal size of one thousand characters.

Yet I did not find any configuration parameter to allow for more than one thousand characters (I probably need 5000 or possibly more).

Any idea how I could fix this ?

Frederic.

for web site dufal.fr

e.g. you'll find the problem in page dufal.fr/index.php/Sp%C3%A9cial:Parcourir/:F.AGSO.S0001

MGChecker (talkcontribs)

This is confusing, as Variables have no such limit. Are you combining them with the Loops extension, by chance?

Can you reproduce this on a normal page, given that this case is kind of weird? I do not know how this special page comes together.

Dinoguy1000 (talkcontribs)

Are you using StringFunctions as well? These have a length limit of 1000 characters for strings. (I tried checking myself, but I don't speak French so I had a hard time telling what was going on.)

2A01:CB15:258:1A00:74BC:4610:8CC4:F7CE (talkcontribs)

Thanks for your prompt help. I'm using ParsingFunctions, Variables, and MyVariables (loaded in this order).

By adding the line

$wgPFStringLengthLimit=9996;

at the end of my LocalSettings.php rather than just after the loading of ParsingFunctions, it solved my problem. (I'm not sure I fully understand why).

Many thanks again.

Frederic.

Dinoguy1000 (talkcontribs)

That means you're using StringFunctions somewhere in the templates that page uses. The limit you increased is important for preventing denial-of-service attacks against your wiki, and the better solution here is to redesign your templates so they're not trying to pass extremely long strings through StringFunctions.

MGChecker (talkcontribs)

It would probably be better (more efficient and more versatile) to use Scribunto for string processing, instead of StringFunctions.