Jump to content

Help talk:ParserFunctions

From Meta, a Wikimedia project coordination wiki
This is an archived version of this page, as edited by Bookofjude (talk | contribs) at 08:52, 13 April 2006 (#nowiki:). It may differ significantly from the current version.

Latest comment: 18 years ago by Bookofjude in topic #nowiki:

Happy days

Yippee! Yay! 'Oh frabjous day! Callooh! Callay!'

Ahem. Ok, so this looks wonderful. Just a couple of comments;

{{if: <condition> | <then text> | <else text> }}

Using pipes (|) as the argument separator is problematic when the <text> sections include wiki table markup (i.e. |-, |, ||) and sometimes even wiki links (i.e. [[Page name|Text to display]]). Would it be possible to use some other character to separate the arguments?

Also, does the expr function take commas into consideration? For example;

{{expr: 1,440 / 60}}

Would this evaluate to '24' or choke on the comma and need '1440' to be used instead? --CBDunkerson 16:09, 5 April 2006 (UTC)Reply

1) Pipes are used as the argument separator for templates too, that's why it's used here. Every ASCII punctuation character has its uses in plain text. What's needed is an escaping method, or a way to change the separator. 2) It would choke on the comma. Is this a problem? Are you sure the answer should be 24, not 0.024? Commas are used in some locales as a decimal point. -- Tim Starling 17:30, 5 April 2006 (UTC)Reply
  1. Plain text isn't so much the problem. In the cases where a specific character is needed you can just use the equivalent ascii code... it'll be converted for display purposes, but won't otherwise impact the markup. The problem with '|' is that we want it to be considered in the markup, just as 'table markup' rather than 'next argument' markup. As such, most characters other than '|' would be fairly safe and something like '\' or ':' could probably be used. Obviously, making the separator definable would work also... though I must warn you that I (or someone else) would immediately expand that into a method of performing string splitting operations.
  2. No, comma handling is not vital. I just had a thought of using things like {{expr: {{NUMBEROFARTICLES}} mod 10}} to generate a 'random' number between 0 and 9 to simplify how w:Wikipedia:Featured content picks the date of materials to display. And yes... I know I am evil. --CBDunkerson 21:34, 5 April 2006 (UTC)Reply
We could always request a {{rand:min|max}}. =) Looking at the code in ParserFunctions.php, it looks like this would be easy to do. —Locke Coletc 04:39, 6 April 2006 (UTC)Reply
Actually writing it yourself is even easier: User:Locke Cole/Rand/Rand.php. =) See talk page there for caveats. —Locke Coletc 05:39, 6 April 2006 (UTC)Reply
Agree with CBD, {{if:...}} would need to allow table markup to be handled correctly to be really useful (an if: would still be useful on it's own, but it'd be more useful (a lot more) if it allowed table markup. BTW: Thank you Tim, you're awesome. =) —Locke Coletc 22:15, 5 April 2006 (UTC)Reply
Check out Template:! [ talk edit history links ] for cases where you need a literal "|" (in wiki tables), see also Qif conditionals and its talk page. -- Omniplex (w:t) 04:09, 6 April 2006 (UTC)Reply
There you can read: "For obvious reasons this is a high risk template, and it cannot be substituted."
MediaZilla:02777 / bugzilla:02777 – "Request for a {{substall:foo}} beside {{subst:bar}}"
One should offer a "clean" implementation from the beginning. Best regards Gangleri · Th · T 09:13, 6 April 2006 (UTC)Reply
Yes, somebody went to the trouble to protect it on Wikipedia, probably a good idea, a template generating one character can't be improved. Conditional templates can't be substituted, and {{!}} is only relevant for conditional templates within Wiki tables. No additional problem with your substall idea, you'd get a working "!" minus the condition, so far (only templates) it 'is clean.
For the ParserFunctions mixing this with {{!}} is dubious. We'd need something on the same level as {{if: x | y | z }}, and if we don't want to waste other special characters maybe {{|}} could be hardwired to generate a vertical bar everywhere. -- Omniplex (w:t) 14:30, 6 April 2006 (UTC)Reply

I guess it replaces the templates and magicwords first isn't? So for example {{if: {{expr: {{tomorrow}} / 7}} | {{expr: {{tomorrow}} / 7}} | 7}} where TemplateTomorrow is {{expr: {{CURRENTDAY}} + 1}} would give the week day number of tomorrow and not any ugly error. Note that this template-into-template wouldn't work with current templates.

BTW. How are unrecognized expressions handled? What error message is shown?

Platonides 19:50, 5 April 2006 (UTC)Reply

It interacts quite well with other templates, in the tests I've done. I guess we'll have a demo running soon so you can test it yourself. At present, only a generic "Invalid expression" error message is displayed on error, but this could easily change. There's already some extra information available for debugging. -- Tim Starling 04:21, 6 April 2006 (UTC)Reply

is this running anywhere?

so we can play with it and try to port some of the current qif using templates? 130.88.171.52 00:34, 6 April 2006 (UTC) Plugwash 00:45, 6 April 2006 (UTC)Reply

Maybe in a day or two. -- Tim Starling 04:21, 6 April 2006 (UTC)Reply
This is now "a day or two" plus three. I say Tim go ahead and apply this parser functions now. Borgx 13:40, 9 April 2006 (UTC)Reply
Is the code running properly already? Using MW 1.6.1 with the code and it will not really work for me. Using this in a template:
{{if:title|Title: {{{title}}}|notitle}}
 {{if:developer|Developer: {{{developer}}}|nodeveloper}}
If i leave one of the two paramaters away, it simply prints {{{title}}} as an example. My intention is to use this instead of a qif template in my own wiki. --Simon Moon 01:37, 7 April 2006 (UTC)Reply
You should be using this I believe:
{{if:{{{title|}}}|Title: {{{title}}}|notitle}}
 {{if:{{{developer|}}}|Developer: {{{developer}}}|nodeveloper}}
Also, and Tim will know for certain, but I think this might require MW 1.7 (in other words, you might have to use something from SVN (which is what I'm using)). —Locke Coletc 01:53, 7 April 2006 (UTC)Reply
When you think you did something wrong, you did. Thanks, tested and works fine with your example now. This works just great now. Currently i am trying some more advanced things, with calling templates inside those constructs, but this really works just great as a replacement for qif.--Simon Moon 02:11, 7 April 2006 (UTC)Reply

Tested it, with the code above, and failed. The code works, no problem there, as well as the example above works as intended. The problems start when you try to use wiki pipe (not working because of the delimiter), html (does also not work, it converts everything inside the construct from the real tags to their html_etinities values) and templtes with variables (seem to brake also because of the delimiter). If somebody can get it to work like qif does currently work (in any possible way) please leave a note here with what you did. --Simon Moon 03:03, 7 April 2006 (UTC)Reply

Yeah, I'd already hit upon the HTML limitation, but I hadn't tried calling a template from within it (and if what you say is true, that's bad). Without some kind of escaping, table markup will likely never work (not a major issue if HTML works, but it'd still be nice). —Locke Coletc 04:13, 7 April 2006 (UTC)Reply
Messed around more with it, so it really is impossible to use html in templates, even if referenced, as long as its inside one of these constructs. It would be sadly, very useless if there is no possiblity to either use anything advanced (including a pipe) directly, or for that matter html (direct or in an included template). The basic goal i am trying to accomplish is to get it to write a row in a table only, if it really is needed (the field is filled with something). This basic technique is used in a ton of templates (see the qif template). I think finding a way to do this is very important, as this could lead to the removal of many of meta templates, that as far as i can read up, would be pretty big relief on the system once they are gone. --Simon Moon 05:40, 7 April 2006 (UTC) Just found an interesting discussion with a comment from Brion. There is no impact on server performance, at least none that is known of. Still, a direct parser approach is imho the better way and i will stick to this one here. --Simon Moon 05:56, 7 April 2006 (UTC)Reply
I suspect (or really hope) that HTML at least will be allowed. BTW, I successfully called a template from within {{if:...}}, was that a problem for you still? —Locke Coletc 10:28, 7 April 2006 (UTC)Reply
You can use a template, but HTML within that template break. To show you the exact meanings of this.

This is a Box template as i test it (calling it Box Game):

<table class="wikitable" style="width:200px; height:200px" align=right>
 <tr><td colspan="2">'''{{{title|Please fill in a Title!}}}'''</td></tr>
 {{if:{{{developer|}}}|{{Box Row|Developer:|{{{developer}}}}}}}</table>

Within that we have the template Box Row, that contains this:

<tr><td>{{{1}}}</td></td>{{{2}}}</td></tr>

Now i call the template like this:

{{Box Game
 | title = Sandbox Game
 | developer = The best Developer Ever
 }}

Which results with this as output in the pages sourcecode:

<table class="wikitable" style="width:200px; height:200px" align="right">
 <tr><td colspan="2"><b>Sandbox Game</b></td></tr>
 &lt;tr&gt;&lt;td&gt;Developer:&lt;/td&gt;&lt;/td&gt;The best Developer Ever&lt;/td&gt;&lt;/tr&gt;</table>

Of course the above html code for the developer line shows as "normal" html code on the page, like you would write it in the code to be displayed correctly, but that does not help at all really. I messed with wiki pipe for tables, but that did not work at all inside template calls. What really gets me is how simple the implementation is. Its only 7 lines of code plus a few for registering into the software. There must be a simple solution to this problem, but i have not found it yet. --Simon Moon 20:24, 7 April 2006 (UTC)Reply

Working example of if, to replace qif, using wiki pipe

I got it to work with wiki pipe now. It is very picky about how its written. Here the working examples. Be sure to not include any spaces or empty lines, this can break it.

Template:Box Game

{| class="wikitable" style="width:400" align=right
| colspan="2"|'''{{{title|Please fill in a Title!}}}'''
{{if:{{{developer|}}}|{{Box Row|[[Developer|Developer:]]|{{{developer}}}}}}}
{{if:{{{publisher|}}}|{{Box Row|Publisher:|{{{publisher}}}}}}}
|}

Template:Bow Row

|-
| {{{1}}} || {{{2}}}

Example of how to apply it in a page:

{{Box Game
| title = Sandbox Game
| developer = Some Coders
| publisher = New Publisher
}}

Title needs always to be filled out or it prints that nice warning about filling in a title. If you leave away developer or publisher, the whole table row is left out of the loop. I also added the example of pipe link for developer. Its safe to use them there, but also directly inside the construct like this:

{{if:{{{publisher|}}}|[[Publisher|Publisher:]]{{{publisher}}}}}

The whole construct works this way as a sound replacement for qif, as long as this extension is installed.

There is a big drawback in this, when you have a lot of lines. In the above example, if you add like 10 lines with the if constructs and they are all empty, the result will be a lot of

<br>

and

<p>

tags. This can only be gotten around by putting them together on basically the same line. So right after the closing brackets of one if, the next opening brackets of the other. This looks ugly as hell in the template code, but will make the template work exactly as planed.

Double colons?

A suggestion has been made on the mailing list to require double colons for extension functions, e.g. {{if:: condition | then | else }} and {{expr:: 1 + 1}}. Vote for the syntax below:

Single colon

Double colon

Hash/Number sign

I previously suggested using {{#if…}} which would AFAICT conflict with nothing existing. It is currently rejected by the parser, would it be very difficult to make it valid? HTH HAND —Phil | Talk 11:59, 6 April 2006 (UTC)Reply

It's not rejected by the parser when I try it. -- Tim Starling 00:19, 7 April 2006 (UTC)Reply

Discussion

Is this necessary? I mean, I don't see the conflict between {{if:...}} and the interwiki links (which use [[xx:...]]).. or is there something I'm missing here? =) FTR, I'd prefer a single colon, but if there's some technical reason why double colons would be better, I'm open to voting for double colons. —Locke Coletc 04:28, 6 April 2006 (UTC)Reply

You can have interwiki transclusion in MediaWiki, it's just that the feature isn't enabled. Note that there might ultimately be quite a lot of these parser functions, I suppose that's an argument for keeping the namespace separate. -- Tim Starling 05:56, 6 April 2006 (UTC)Reply

Might there not be another approach as well, instead of the mentioned above? A pseudo namespace as with Special, containing those functions? It would be standarized in every wiki, not interfereing with any interwiki operability. Example would be to use Parse:if or Parse:expr for this. --Simon Moon 00:13, 7 April 2006 (UTC)Reply

Division operator

Is there any objection to using div instead of / (forward slash) as the division operator? I think it would make it a bit more readable (especially when nested within template code for example). —Locke Coletc 06:09, 6 April 2006 (UTC)Reply

I'm quite happy with forward slash. div can be a synonym if you really want. -- Tim Starling 08:23, 6 April 2006 (UTC)Reply
That'd work I guess. =) —Locke Coletc 08:47, 6 April 2006 (UTC)Reply

using "e" as syntax delimiter

  • What about this:
{{if: <condition> e <th&#x65;n t&#x65;xt> e <&#x65;ls&#x65; t&#x65;xt> }}<br />
example: {{if: {{satisfied}} e gr&#x65;at! e sorry! }}<br />
Yeah, very funny. If you've got any sensible suggestions for how to solve this, please speak up. We can't just change the delimiter to some other punctuation character, that would break backwards compatibility. As I keep saying, we need a delimiter declaration tag or an escaping system. -- Tim Starling 10:15, 6 April 2006 (UTC)Reply
How would {{if: <condition> | <then text> | <else text> }} support
  1. definition of two / three table lines
  2. inclusion of templates
    1. bidirectional code like
      {{if: {{PAGENAME}}=ערשטע זײַט | הײַנט | {{א||b= demo only}}{{{mode|פּרוּװ}}} }} א
Writing everything in one line and using one delimiter reminds me about Lisp. I never got involved and my superficial knowledge dates back nearly 20 years.
Sincerly traying to find another soution Gangleri · Th · T 11:48, 6 April 2006 (UTC)Reply
Who says it would have to be in one line? I assumed it would be possible to do;

<tr>{{if: {{{Param|}}} |<th>Header 1<td>{{{Param}}} |<th>Header 2<td>{{Template}}

}}</tr>

Note that {{NS:4}} works just fine if a line break is inserted between the ':' and '4'... so this ought to as well given that it uses the same method. Of course, that's where the issue with '|' specifically comes in since multi-line entries would allow wiki table markup... but the '|' characters used in table markup get interpreted as argument delimeters for the 'if'. Hence my suggestion of some other character... in less common use than 'e'. I'm ok using HTML, but as noted some prefer wiki table markup. Being able to define 'these pipes' as argument separators but 'these other pipes' as table markup and 'these yet other pipes' as straight text would work... but frankly seems likely to be insanely convoluted in both implementation and execution. Definable argument separators (e.g. something like {{if:\: <test>\<then text>\<else text>}}) would be great, but add a level of complexity. --CBDunkerson 16:10, 6 April 2006 (UTC)Reply
Hang on, why are you all complaining about the use of | in table syntax? Why not just use HTML tables? -- Tim Starling 10:19, 6 April 2006 (UTC)Reply
Certain editors think using HTML is "yucky" and "gross"... FWIW, I don't care and I think HTML is better (table syntax is evil), but if there were a way to make table syntax work with this it'd curb the complaints people sometimes make. =) To be absolutely clear, some people dislike HTML on the principle that HTML is inferior to wiki-markup table syntax. Still others dislike mixing wiki-markup table syntax with HTML (as is often done to try and make non-dynamic portions of templates simpler to read). —Locke Coletc 10:33, 6 April 2006 (UTC)Reply
I would recommend that anyone who needs to write complex conditionals push their arguments down a level into other templates, in the best traditions of structured programming.  :-) --baylink@en.wp
I do neither complain about the usage of "|" in table syntax nor in templates, optional parameters, pipes. I would be happy to have another delimter/keywords for {{if:}}.
"We can't just change the delimiter to some other punctuation character, that would break backwards compatibility." I know Tim how painfull "migration" can be and how difficult it is not to break a live site. With Special:Whatlinkshere/template:if one can identify where this particular template is used.
For a transition time we could use two delimiters, clean the code from the pages where "|" are used and switch to the final syntax at day "Z". This might not be the "smartest" way. If you know other alternatives just let us all know about them.
Regards Gangleri · Th · T 12:02, 6 April 2006 (UTC)Reply

reducing the costs of {{rand:}}

  • In a similar manner one could solve issues related to caching:
{{rand: <number> | <number> }}
Yeah that'd be good. Let's do that. :]
Or maybe we could implement random number logic, but restrict it to just a few pages like w:Wikipedia:Featured content (where pseudo 'randomly' selected 'featured' items are displayed currently) where it'd serve some useful purpose. No, those pages wouldn't get cached but a few 'showcase' pages which update constantly would not be a terrible strain on the servers. --CBDunkerson 16:29, 6 April 2006 (UTC)Reply
I have no intention of making the rand function reduce the parser cache effectiveness. You can use it if you want but you'll have to run action=purge to make it change. -- Tim Starling 23:40, 6 April 2006 (UTC)Reply
Having it generate a new number every time the page is loaded would indeed be bad. But having it generate a new random number every 15/30 minutes (or every few hours) wouldn't be so bad, would it? I found the method for disabling caching entirely, but is there a way to set an expiry period? (e.g. - use the cached results for XX minutes, after which, call me again and reset the timer, using the cached results for XX minutes, repeat). —Locke Coletc 23:49, 6 April 2006 (UTC)Reply

hall of shame

hey sorry everybody i didn't mean to open a can of worms with the en:category:date math templates. it just kinda got out of hand. all i really wanted was to do a few timezone calculations. --Ed Poor 00:26, 7 April 2006 (UTC)Reply

Documentation

I am pretty new to extensions here, and i would say many others are as well. So if i get this right, all this needs is to put those two files in your medawiki (in extensions clearly to make it nice) and then inclode it in the localsettings (ParserFunctions.php file of course). Right? If so, this little piece of info added would be good for the content page imho. --Simon Moon 00:29, 7 April 2006 (UTC)Reply

Yes, that's it (and to be clear (I think you hint at this above), you only add ParserFunctions.php to LocalSettings.php, not Expr.php (but both files must be in /extensions for it to work)). I don't know if instructions would be appropriate or not and will defer to Tim on that (my gut feeling is we shouldn't include instructions; there's probably a page explaining extension installation elsewhere). —Locke Coletc 00:49, 7 April 2006 (UTC)Reply
Changed, my Tim forgive an unexpierenced user :) --Simon Moon 01:03, 7 April 2006 (UTC)Reply

Leap Year

Here's a slightly more advanced example of {{expr:...}}-

{{expr:((({{CURRENTYEAR}} mod 4) = 0) and (({{CURRENTYEAR}} mod 100) <> 0)) or ((({{CURRENTYEAR}} mod 100) = 0) and (({{CURRENTYEAR}}} mod 400) = 0))}}

*or*, more readable-

{{expr:
(
  (
    ({{CURRENTYEAR}} mod 4) = 0
  ) and (
    ({{CURRENTYEAR}} mod 100) <> 0
  ) 
) or (
  (
    ({{CURRENTYEAR}} mod 100) = 0
  ) and (
    ({{CURRENTYEAR}} mod 400) = 0
  )
)
}}

Locke Coletc 10:33, 7 April 2006 (UTC)Reply

2nd part: when ({{CURRENTYEAR}} mod 400) = 0, also ({{CURRENTYEAR}} mod 100) = 0 :-) WebBoy 13:25, 7 April 2006 (UTC)Reply

ifeq

Is ifeq case-sensitive or case-insensitive? WebBoy 13:27, 7 April 2006 (UTC)Reply

Looks like it's case sensetive. I imagine a case-insensetive version would be possible though (similar to stricmp() in C) by using strcasecmp(). —Locke Coletc 18:08, 9 April 2006 (UTC)Reply

xor

I posted this on Wikipedia:Village pump, but wanted to mention it here as well. While I can't see any use for it right now, for completeness sake, it would be nice if xor were added to the logical operators. In keeping with and, or and not, I would also propose it use the word xor (as opposed to ^ if we were to use the C syntax). —Locke Coletc 09:15, 8 April 2006 (UTC)Reply

Second that, it actually does have its uses. Shouldn't be to haard to add anyways, looking at the code. --Simon Moon 09:27, 8 April 2006 (UTC)Reply

Condition checks

Is that these functions have the pre-condition checks, like something didive by zero? And also, I think if possible, maybe can include some functions like log functions. Some logs maybe useful like log (base on 10), ln (base on e) and lg (base on 2), or maybe can customised buy putting a base into the function. :) --Shinjiman 00:51, 9 April 2006 (UTC)Reply

Yup, division by zero does cause an error to be displayed (a PHP error I mean). This was fixed by changing the code in Expr.php, in function doOperation for case EXPR_DIVIDE to:
                        case EXPR_DIVIDE:
                                if ( count( $stack ) < 2 ) return false;
                                $right = array_pop( $stack );
                                $left = array_pop( $stack );
                                if ($right == 0) {
                                        $stack[] = 0;
                                } else {
                                        $stack[] = $left / $right;
                                }
                                break;
This causes it to return zero on a division by zero (and no longer displays the error message of course). It would probably be better if an error were displayed though (not a PHP error). —Locke Coletc 01:45, 10 April 2006 (UTC)Reply

Can this be substed?

Just a side question: can templates that use these new functions be substed? I'm asking this because the templates that use en:template:qif today cannot be substed, because qif cannot be substed. Not that I am a special fan of substing - rather the opposite. Just asking... --Ligulem 22:32, 10 April 2006 (UTC)Reply

Fairly certain the answer is yes. Though subst'ing templates (with a few exceptions anyways) is just plain silly. —Locke Coletc 00:51, 11 April 2006 (UTC)Reply

will it go live?

Is this assumed to go live on the wikis in the next time? --::Slomox:: >< 23:38, 10 April 2006 (UTC)Reply

<sarc>I hope so, hmm was just thinking with enough nested funtions, and logic gates, anything is possible :) </sarc> xaosflux Talk 01:51, 11 April 2006 (UTC)Reply

It's live now. -- Tim Starling 10:01, 12 April 2006 (UTC)Reply

Can we use white space like in template calls?

Can we use white space (space, newlines) as in template call? For example like this:

{{if:: {{{title|}}}
  | title is: {{{title}}}
  | no title was specified
}}

It would be good if the white space handling were the same as for template call, I mean please ignore white space:

  • before and after the "|"
  • before the closing "}}"
  • after the "if::"

--Ligulem 10:05, 11 April 2006 (UTC)Reply

It seems to (currently) ignore whitespace (including line feeds) as you describe. If you haven't, you should setup a local copy of MediaWiki to play with it. (Apache is free, MySQL is (mostly?) free, MediaWiki is free; give it a try, heh). =) —Locke Coletc 10:52, 11 April 2006 (UTC)Reply
Probably will do so, if this here has any chance to succeed. The problem is not to invent stuff like this here (Carl has already done that). Problem is to get it live :-). --Ligulem 11:13, 11 April 2006 (UTC)Reply

note on usage of whitespace in templates

  • Please note that whitespace can breake templates:
template:vandal
{{vandal|foo}}<br clear="all" />
----
{{vandal
|bar
}}<br clear="all" />
----

generates:‎
foo (talk • contribs • deleted contribs • logs • filter log • block user • block log • GUC • CA)


[//meta.wikimedia.org/wiki/User:Bar bar ] ([[User talk:bar |talk]] • [[Special:Contributions/bar |contribs]] • [[Special:DeletedContributions/bar |deleted contribs]] • logs • filter log • [[Special:Block/bar |block user]] • block log • [[luxo:bar |GUC]] • [[Special:CentralAuth/bar |CA]])


bugzilla:05121 – "Virtual lines using a trailing escape character (as "\")"

Can we nest if-constructs?

For example like this:

{{if:: {{{title|}}}
  | {{if:: {{{author|}}}
      | {{{author}}}, {{{title}}}
      | {{{title}}}
    }}
  | no title was specified
}}

? --Ligulem 11:19, 11 April 2006 (UTC)Reply

What about using ¦ instead of |?

Like this:

{{if:: <condition> ¦ <then text> ¦ <else text> }}

Could this help to prevent the parsing problems with table syntax? --Ligulem 11:24, 11 April 2006 (UTC)Reply

I'd really prefer an US ASCII solution, typing raw UTF-8 on an OS and browser strongly believing in charsets with at most 256 characters would be a PITA. Or could I just say &brvbar; to get your UTF-8 proposal? -- Omniplex (w:t) 12:26, 11 April 2006 (UTC)Reply
"&brvbar;" reminds me at escaping techniques. Please do not use "&brvbar;". Best regards Gangleri · Th · T 12:43, 11 April 2006 (UTC)Reply
Well, it usually works on browsers supporting only Latin-1 or windows-1252. Actually it should work on any browser, it's a part of the HTML DTDs back to stoneage. Unfortunately that point is moot here, because the Mediawiki software destroys backwards compatibility by replacing UTF-8 for HTML 3.2 entities, except from &nbsp; or &#160; - otherwise I wouldn't be here, replacing nbsp entities would be too clueless. -- Omniplex (w:t) 18:46, 12 April 2006 (UTC)Reply

Question

On the Wikipedia, why does this:

<u onmouseover="alert(document.cookie);">text</u>

Come out as:

Text (underlined)

But this:

 {{#if: 1=1|<|}}{{#if: 1=1|u onmouseover="alert(document.cookie);"|}}{{#if: 1=1|>|}}{{#if: 1=1|text|}}{{#if: 1=1|</u>|}}

Come out as:

 <u onmouseover="alert(document.cookie);">text  (not underlined, no "</u>")

?

All the best,
Nick.

A bit above, you can see my tries of implementing a replacement for qif. i came across teh same problem you do have now. As soon as you use html inside the if statements, it breaks. It simply displays the html special codes instead. --Simon Moon 06:53, 12 April 2006 (UTC)Reply
Actually HTML is fixed now and seems to work. However, it appears the person above was wondering why he couldn't get an exploit to work? My guess would be that the lone < is translated into &lt;, so the HTML never properly forms. The </u> is likely removed by HTML Tidy (or MW's internal sanitizer) because of the lack of an opening <u>. This is a good thing. —Locke Coletc 06:57, 12 April 2006 (UTC)Reply
FYI, I wanted to confirm that the exploit did not work. Also, I don't think HTML is fixed now - see below - because if it were fixed, then both should give the same output, because they are logically equivalent, whereas currently they do not. -- All the best, Nick.

text

text


Wrong result?

result of {{#if: 3+9-10|3+9 is 10|3+9 is not 10}}: 3+9 is 10

According to documentation, if the condition is 0 then it is considered false, and the else text is returned. But the according to expression above, the result returned is the then section although the condition is not 0. Borgx 08:37, 12 April 2006 (UTC)Reply

You're using it wrong. =) Try {{#if: {{#expr:((3 + 9) = 10)}}|3+9 is 10|3+9 is not 10}}. Also, read the documentation for #if more closely. —Locke Coletc 08:42, 12 April 2006 (UTC)Reply
) sorry, forgot the {{#expr}}. Borgx 08:44, 12 April 2006 (UTC)Reply

Or do:

{{#ifeq:{{#expr:3+9}}|10|3+9 is 10|3+9 is not 10}}

which gives:

3+9 is not 10

...but ...

3+7 is 10

-- All the best, Nick.

You can also use {{#if: {{#expr:3+7=10}} | 3+7 is 10 | 3+7 is not 10}} -- Tim Starling 09:41, 12 April 2006 (UTC)Reply

Server or client?

Sorry for asking stupid question: does the computation done by Wikimedia server or by the client computer (my computer, for example) ? 134.157.5.208 08:19, 12 April 2006 (UTC)Reply

Server. 218.215.2.197 08:42, 12 April 2006 (UTC)Reply
Thanks, so it come to the server-client philosophy. Why we pay more for the computation on our server, when we could give the user the work load? I notice that MediaWiki have been constantly/consistently applying the rule of server computation, there must be good reasons. But I guess for simple math calculation, client computer may do it well, saving us the load on server? 134.157.5.208 08:56, 12 April 2006 (UTC)Reply
The server needs to know the targets of links so it can register them in the database. And some clients can't do even the simplest of mathematical calculations. -- Tim Starling 09:46, 12 April 2006 (UTC)Reply

some functions

How to implement this simple pseudocode:

if the month is April then write This is April else write This is not April

Since we can not use:

{{#if: {{CURRENTMONTHNAME}}=April|This is April|This is not April}}

Because

{{#if: {{CURRENTMONTHNAME}}=Aprils|This is April|This is not April}}

also return This is April

The only way i can think of is:

{{#if: {{#ifeq: {{CURRENTMONTHNAME}}|April|somestring|}}|This is April|This is not April}}
{{#if: {{#ifeq: {{CURRENTMONTHNAME}}|Aprils|somestring|}}|This is April|This is not April}}

How about make simple function {{#is:}} with same function as {{#ifeq:}} but returns non-empty string (character 'a' for ex) for equal condition and returns empty string for not equal condition.

So:

{{#if: {{#is: {{CURRENTMONTHNAME}}|April}}|This is April|This is not April}} will return "This is April"
{{#if: {{#is: {{CURRENTMONTHNAME}}|Aprils}}|This is April|This is not April}} will return "This is not April"
{{#if: {{#isnot: {{CURRENTMONTHNAME}}|April}}|This is not April|This is April}} will return "This is April"
{{#if: {{#isnot: {{CURRENTMONTHNAME}}|Aprils}}|This is not April|This is April}} will return "This is not April"

Borgx 09:05, 12 April 2006 (UTC)Reply

{{#if:{{#expr:({{CURRENTMONTH}} = 4)}}|This is April|This is not April}} which produces This is April. —Locke Coletc 09:18, 12 April 2006 (UTC)Reply

Locke Cole, thanks for the answer, but I was refered to string comparison in general. Borgx 09:24, 12 April 2006 (UTC)Reply

Okay, if you want to do the string compare, try {{#if:{{#ifeq:{{CURRENTMONTHNAME}}|April|1}}|This is April|This is not April}}
  • {{#if:{{#ifeq:{{CURRENTMONTHNAME}}|April|1}}|This is April|This is not April}} produces This is not April
  • {{#if:{{#ifeq:{{CURRENTMONTHNAME}}|Aprils|1}}|This is April|This is not April}} produces This is not April
We return "1" on a match so #if will equate it to "true". —Locke Coletc 09:31, 12 April 2006 (UTC)Reply
What's wrong with {{#ifeq: {{CURRENTMONTHNAME}}|April|This is April|This is not April}}? -- Tim Starling 09:33, 12 April 2006 (UTC)Reply
Nothing actually, I assumed from the complexity of the examples that Borgx was looking for something.. complicated. :P I was probably wrong. =) —Locke Coletc 12:39, 12 April 2006 (UTC)Reply

Trial implementations

I've been rewriting the hideously complex logic code behind the Vietnamese Wikipedia's front page to use this extension's syntax instead, wherever possible. You can clearly see the difference at some of the transcluded templates, and it's working like a charm. [1] [2] I've also started to port some of the more generic logic templates to the new syntax. [3]

Someday I'll try and tackle that notorious language infobox. *shakes head in utter amazement*

 – Minh Nguyễn (talk, contribs) 09:31, 12 April 2006 (UTC)Reply

In [4], instead of {{#if: {{{1|{{CURRENTWEEK}}}}} + 52 - 1 > 52 |{{#expr: ({{{1|{{CURRENTWEEK}}}}} + 52 - 1) mod 52}}|{{#expr: {{{1|{{CURRENTWEEK}}}}} + 52 - 1 }}}}, can't you just use {{#expr: ({{{1|{{CURRENTWEEK}}}}} + 51) mod 52}}? -- Tim Starling 10:00, 12 April 2006 (UTC)Reply
I don't think so, because this segment of the code is used to determine which week's featured article to link to. During Week 1, the template is supposed to link to the articles for Weeks 50, 51, and 52. Simply modding the week number will make it link to Week 0, which doesn't exist. Then again, I'm horrible at math, particularly with mods, so I probably did miss several ways to make it more efficient. – Minh Nguyễn (talk, contribs) 10:31, 12 April 2006 (UTC)Reply
I think should work:
1 week before
{{#expr: ({{{1|{{CURRENTWEEK}}}}} + 50) mod 52 + 1}} (45)
2 weeks before
{{#expr: ({{{1|{{CURRENTWEEK}}}}} + 49) mod 52 + 1}} (44)
3 weeks before
{{#expr: ({{{1|{{CURRENTWEEK}}}}} + 48) mod 52 + 1}} (43)
-- Tim Starling 10:58, 12 April 2006 (UTC)Reply
Alright, thanks a lot! – Minh Nguyễn (talk, contribs) 11:28, 12 April 2006 (UTC)Reply

whitespace handling

User:Ligulem/if-test-1 contains:

{{#if: {{{a|}}}|param a has value {{{a}}}}}

User:Ligulem/if-test-2 contains:

{{#if: {{{a|}}}
  | param a has value {{{a}}}
}}

(1) *-{{User:Ligulem/if-test-1|a=val_a}}- produces:

  • -param a has value val_a-

which is fine, but

(2) *-{{User:Ligulem/if-test-2|a=val_a}}- produces:

  • -param a has value val_a-

this is different behaviour as in en:template:qif, which ignores whitespace (general template param behaviour). How can I achieve the same as with qif, without having to write the whole template code on a single line? Writing the the whole m:template:cite book on a single line is a bit tough. --Ligulem 12:45, 12 April 2006 (UTC)Reply

Ok. I can use comments:
User:Ligulem/if-test-3 contains:
{{#if: {{{a|}}}
  |param a has value {{{a}}}<!--
-->}}
*-{{User:Ligulem/if-test-3|a=val_a}}- then produces
  • -param a has value val_a-
--Ligulem 12:51, 12 April 2006 (UTC)Reply
I can have it trim whitespace, but are you sure that's what you want? It means you won't be able to use #if to insert spaces or line breaks. -- Tim Starling 12:58, 12 April 2006 (UTC)Reply
For spaces, they could use &#32; (or if it's hex, I always mix it up, &#20;) couldn't they? Linespaces with BR? (not optimal, I agree). —Locke Coletc 13:00, 12 April 2006 (UTC)Reply
Tim, you are right. Leave it as it is. It can well be that this is better than with qif. With qif we had to do &32; for example to insert a space (as Locke writes above). --Ligulem 13:08, 12 April 2006 (UTC)Reply
Please trim the whitespace as offered. Substituting this new function for {{qif}} without having the whitespace trimmed in the same way as for template parameters will make it much more difficult to produce legible wikitext. Also there should be no real reason why anybody should need to use this function to introduce line-breaks: if a simple space using is not suffucient then use <br />. HTH HAND —Phil | Talk 13:34, 12 April 2006 (UTC)Reply
There's also some interaction with "*" lists; see w:User:Phil Boswell/cite book regression tests where I have simply substituted {{qif|test=…|then=…|then=…}} with {{#if:…|…|…}} and the white-space suddenly introduced has thoroughly broken the template. HTH HAND —Phil | Talk 13:39, 12 April 2006 (UTC)Reply

#ifexpr

This was something I suggested on IRC, and just wanted to document here. #ifexpr is a proposal to wrap together a call to #if and #expr in one single call. So instead of--

{{#if: {{#expr:((10 + 1) = 11)}} | 10 + 1 is 11 | 10 + 1 is not 11}}

you'd do this

{{#ifexpr: ((10 + 1) = 11) | 10 + 1 is 11 | 10 + 1 is not 11}}

The syntax would be this--

{{#ifexpr: <expression to be tested> | <true text> | <false text>}}

Your expression in #ifexpr would need to result in zero (or blank) to be considered false, and result in non-zero to be considered true. This would help reduce the complexity (and nesting) of these calls.

Thoughts? —Locke Coletc 13:04, 12 April 2006 (UTC)Reply

Yes, seems like a good idea to me. In fact, it's actually what I originally thought the new #if construct did, and it was only after reading the docs, because I was not able to get it to work that way, that I realised it was different. So yes, I'd support this. -- All the best, Nickj. 02:22, 13 April 2006 (UTC)Reply

#switch

The #if function seems to work a treat. Could we possibly also have #switch as per {{en:template:switch}}? Currently usage is as follows:

{{switch
 |VALUE-TO-BE-TESTED
 | case: foo=hello
 | case: bar=world
 | default=Neither ''foo'' nor ''bar''
}}

where VALUE-TO-BE-TESTED is a parameter or a variable

Constraints
  • The variable to switch have some constraints because the value must be able to be used as a parameter name.
    • Characters known not to work are: =|
    • There mustn't be any space between the pipe character and the first character.
  • There is no fall-through (if you look at the code, you know why).
  • If default is not defined, the result if no value matches will be blank.

The same constraints would apply with any luck, making it easy to convert. You might want to consider obviating the "case:" construct. HTH HAND —Phil | Talk 14:52, 12 April 2006 (UTC)Reply

Suggested syntax

Neither ''foo'' nor ''bar''

I'm having some difficulty deciding how to specify the default condition: any suggestions? HTH HAND —Phil | Talk 15:29, 12 April 2006 (UTC)Reply

Personally I think we should keep the "case:" bit (which would also make it easier to come up with that "default" condition). Syntax would be:
default: Neither ''foo'' nor ''bar''
Only the first colon would be significant as a delimeter/separator, so you'd still be able to use colons in the return value for example (same for the equal sign; only the first equal sign would be significant). For the default case, there would be no equal/test value. I do absolutely believe a switch construct is necessary though, otherwise we'll end up with nested #if's (assuming we want to ditch the switch template). —Locke Coletc 22:19, 12 April 2006 (UTC)Reply
Actually, let's expand this a bit. One of the things that bugged me about the Switch template was that there was no way to do fall-through. So how about, if there's NO equal sign, it "falls through" until it finds a case with an equal sign? Here's an updated syntax:
default: Neither ''foo'' nor ''bar''
Note here that if "foo" is a match to VALUE-TO-BE-TESTED, it falls through to "case: bar=hello". Note also that you should be able to fall-through to the "default:" case as well. —Locke Coletc 00:59, 13 April 2006 (UTC)Reply

testing for string non-emptyness

I am trying to do something like:

{{#if: {{#expr: {{{a|}}} or {{{b|}}} }} |a or b is not empty}}

which I mean to be that the then-string ("a or b is not empty") should be emitted if a or b are not empty (of course it doesn't work like that). How can I achieve that? Do we need a new operator for #expr to achieve this? For example "nonempty"?

{{#if: {{#expr: nonempty({{{a|}}}) or nonempty({{{b|}}}) }} |a or b is not empty}}

please consider also the "and" example:

{{#if: {{#expr: nonempty({{{a|}}}) and nonempty({{{b|}}}) }} |a and b is not empty}}

Things like that are quite common. See for example en:template:booland of en:Category:Boolean templates. --Ligulem 16:51, 12 April 2006 (UTC)Reply

You do it like this: {{#if: {{{a|}}}{{{b|}}} || a or b is not empty}} -- Tim Starling 18:42, 12 April 2006 (UTC)Reply
Yes, I know this transformation (we have done this with the weeble) trick. This is for the "or" case. BTW, it must be like this: {{#if: {{{a|}}}{{{b|}}} |a or b is not empty}}. The 'and' case can be done by nesting. --Ligulem 21:15, 12 April 2006 (UTC)Reply

But how would you do that: I need a template that has two parameters a and b. if a or b or both are empty, the template should emit the string "a and b must both be nonempty" and the empty string in all other cases. The pseudo-code would be:

if (not(nonempty(a) and nonempty(b))) {
  return "a and b must both be nonempty"
}

--Ligulem 21:15, 12 April 2006 (UTC)Reply

I guess I found a solution. User:Ligulem/if-test-5 contains:
{{#if: {{#if: {{{a|}}} | {{#if: {{{b|}}} |1}}}} ||a and b must both be nonempty}}
*-{{User:Ligulem/if-test-5}}- gives
  • -a and b must both be nonempty-
*-{{User:Ligulem/if-test-5|a=xx}}- gives
  • -a and b must both be nonempty-
*-{{User:Ligulem/if-test-5|b=yy}}- gives
  • -a and b must both be nonempty-
*-{{User:Ligulem/if-test-5|a=xx|b=yy}}- gives
  • --
Anyone a better idea? --Ligulem 21:42, 12 April 2006 (UTC)Reply
Not a better idea (currently anyways), but this might be a bit cleaner if #ifexpr were available:
{{#ifexpr:({{#if:{{{a|}}}|1|0}} and {{#if:{{{b|}}}|1|0}})||a and b must both be nonempty}}
Locke Coletc 22:26, 12 April 2006 (UTC)Reply
Ah. Looks nicer yes. This strongly smells like another m**a-template {{nonempty|{{{a|}}}}} containing {{#if:{{{1|}}}|1|0}}. I can already hear the hooting...:-) --Ligulem 23:24, 12 April 2006 (UTC)Reply
OH NOES, NOT META-TEMPLATES! ;) But yes, barring an extension function, it seems like a reasonable meta-template to me. —Locke Coletc 03:01, 13 April 2006 (UTC)Reply

Notes on syntax

  • Why is the "trailer" "deprected" in the sixth example?
# "{{#if: always | yes is yes | no is no }}"
# "{{#if: always |  yes is yes  |  no is no  }}"
# "{{#if: | yes is yes | no is no }}"
# "{{#if: |  yes is yes  |  no is no  }}"
# "{{#if: ||  no is no  }}"
# "{{#if: ||  no is no  | trailer as table code}}"
# "{{#if: ||  no is no
multi line text<br />
...
}}"

generates:‎

  1. "yes is yes"
  2. "yes is yes"
  3. "no is no"
  4. "no is no"
  5. "no is no"
  6. "no is no"
  7. "no is no

multi line text
..."

I would say the result of {{#if: || no is no | trailer as table code}} is not specified (erroneous use). As such the implementation may emit what it pleases. And what it does is fairly reasonable. But I fear I have not understood what you want to tell with that testcase. --Ligulem 22:04, 12 April 2006 (UTC)Reply
The example is using an empty <then text>. If you look carefully at the syntax, the start, the expression, the delimiters and the fields inbetween and compare with the result you may see that you will not be able to generate "reasonable table code" with the <else text>. It is simply "blocked". Gangleri · Th · T 23:39, 12 April 2006 (UTC)Reply
Yes. I believe I have understood that there is an empty "then-text" in {{#if: || no is no | trailer as table code}}, due to the "||". Because ParserFunctions uses "|" as a syntax element, ParserFunctions cannot be used for Manske tables (tables using the "|" as a syntax element). This is by design. This has already been said. --Ligulem 07:30, 13 April 2006 (UTC)Reply
Here's a working example (I hope, actually a test):
	# "{{#if: always | yes is yes {{!}} no is no }}"
	# "{{ifdef | 0 | empty is empty {{!}} 0 is 0 }}"
	# "{{#if: || no is no }}"
	# "{{ifdef || isn't ifndef }}"
	# "{{#if: || no is no {{!}} trailer as table code }}"
  1. "yes is yes | no is no"
  2. " empty is empty | 0 is 0 "
  3. "no is no"
  4. ""
  5. "no is no | trailer as table code"
Not pretty, but does the trick. For an #if: without else {{ifdef|test|then}} is very similar (for a void test, not for 0), and probably not slower than #if:, so maybe check out ifdef for your purposes if you want to avoid the layer violation. -- Omniplex (w:t) 04:57, 13 April 2006 (UTC)Reply

minimal multiline RTL compatibility test

  • looks OK
׳{{#if:
שטענדיק
| יאָ יז יאָ
| נײן יז נײן
}}׳
----
׳{{#if:
|| נײן יז נײן
}}׳

generates:‎
׳יאָ יז יאָ׳


׳נײן יז נײן׳

What means "RTL"? --Ligulem 22:08, 12 April 2006 (UTC)Reply
"right to left" script see RTL: "Right-to-left writing, as applied in Arabic and Hebrew. See Bi-directional text and Writing system." Gangleri · Th · T 23:44, 12 April 2006 (UTC)Reply

subst variant 19:48, 12 April 2006 (UTC)

  • looks OK
׳{{subst:#if:
שטענדיק
| יאָ יז יאָ
| נײן יז נײן
}}׳
----
׳{{subst:#if:
|| נײן יז נײן
}}׳

generates:‎
׳יאָ יז יאָ׳


׳נײן יז נײן׳

asymmetry between expression parts and result parts

  • If you look closer at the syntax you might discover the asymmetry between expression parts and the result parts. The expression parts may contain the "( )" "Grouping operators" but the result parts lack such "meta" constructs ("begin" / "end, "{" / "}" etc.). The "result parts" end at the "hardwired" pipe chacater; as shown above this aplies also for the "<else text>" without any need.
  • My objections are not theoretical. The actual syntax can not be used to generate conditional wikitable syntax as optional table lines, variable table subdivisions etc. Gangleri · Th · T 20:11, 12 April 2006 (UTC)Reply

I'm wondering if it might be better to use the HTML syntax for tables in these cases, anyhow. As the wikitable syntax and the ParserFunctions syntax use a similar set of characters (not to mention the template syntax), the HTML table syntax might serve to create less confusion and make the templates easier to manage. Some of the code I've written at Wikipedia has an uncanny resemblance to Lisp, as it uses a very limited set of characters for everything under the Sun, except that it's all written on one line.

I know that using the HTML syntax isn't really an answer to the objections you've brought up, but it might be more useful, since it'd be a lot easier to spot the HTML syntax in en:Template:Infobox Language, for example.

 – Minh Nguyễn (talk, contribs) 03:09, 13 April 2006 (UTC)Reply

FWIW, I prefer pure XHTML for the most part as well. It's, IMO, easier to pick out the conditionals (and other template calls) in XHTML than it is to pick it out in table syntax. —Locke Coletc 03:32, 13 April 2006 (UTC)Reply

Plus, I've also seen a lot of infoboxes that use meta-templates just because no one thought to use XHTML. Since you can actually mix XHTML table syntax with wikitable syntax, it's just inexcusable in some of these cases. – Minh Nguyễn (talk, contribs) 07:08, 13 April 2006 (UTC)Reply

AND, OR, and XOR

Why are And and OR just logical ops instead of binary ops? Like "111 AND 101 == 101" in C++ or PHP, here they should be implemented in C++ standard. Furthermore, XOR is also a needed op for completeness sake. 67.15.34.251 05:26, 13 April 2006 (UTC)Reply

XOR is proposed further up on this page (and I suspect Tim will add it soon). Regarding binary ops, the way it's implemented, I don't even know if that'd be (easily) possible. It'd be (sort of) nice to have, but I don't know if it'd be worth the effort. —Locke Coletc 05:39, 13 April 2006 (UTC)Reply
I mean those bit operators. It just take a few changes in expr.php. Like:
case EXPR_AND:
  if ( count( $stack ) < 2 ) return 'missing_operand';
  $right = array_pop( $stack );
  $left = array_pop( $stack );
  $stack[] = ( $left && $right ) ? 1 : 0;

Changing the "( $left && $right ) ? 1 : 0" into "$left & $right" is just okay. 67.15.34.251 05:51, 13 April 2006 (UTC)Reply

Give a few more infomation in error message

I suppose if the position of error occurring is given, debugging will be much more conveniet especially in some long expressions, or it's better to return the source with error in bold. This is also easy to implement. Just add "$p" in expr.php after returning error message. Like:

case EXPR_AND:
  if ( count( $stack ) < 2 ) return 'missing_operand';

return 'missing_operand' to 'missing_operand "$p"' and add a few handling functions in ExprParser->error() or ExtParserFunctions->expr(). 67.15.34.251 05:59, 13 April 2006 (UTC)Reply

#nowiki:

I was thinking about something that would strip [[Wiki Markup]] out of a variable, so I decided to go ahead and try it:

{{#nowiki:[[This is a random snippet]] of Wikimarkup.}}

Results in:

This is a random snippet of Wikimarkup.

This is the code. Thoughts? There's still an issue with table markup. Jude(talk,contribs) 08:52, 13 April 2006 (UTC)Reply