create new tag
, view all tags
As an experiment, more to see if it was possible or not, I just extended %SECTION to support an "if" type and an ELSE clause. This lets you write something like this:

%SECTION{type="if" condition="defined FLUB"}%
FLUB is defined
FLUB is *not* defined

Fun, eh? The syntax is rather clumsy, but it shows how easy it is to add something like this. It's basically what the IfDefinedPlugin does, if I'm not much mistaken, but with syntax consistent with the rest of the core.

The syntax is evaluated after verbatim and literal sections are protected, just before the startRenderingHandler, and before any other TWiki variables are evaluated.

This means that any TWiki variables inside the failing side of the condition are never evaluated. So you can't "build" a %SECTION{type="if" out of other TWiki variables (though I have evaluated them inside the condition value).

This construct cannot be used to conditionally assign TWiki variables.

Patch (against rev 14684) attached. I did not write any unit tests, and I have absolutely no idea of the effect on performance. It was just an hour long experiment.

-- Contributors: CrawfordCurrie - 01 Sep 2007


Why is the syntax of IfDefinedPlugin inconsistent with the core? It reuses TML as much as possible without changing anything, even valuation order is kept as it is. It uses the same $percnt, $nop and stuff known from FormattedSearch rather than doing anything fancy. Nothing else. Simple and very flexible.

That said, IF's syntax is inconsistent with any other syntax in the core and thus very hard to remember.

-- MichaelDaum - 01 Sep 2007

IfDefinedPlugin is forced to be inconsistent because it is done in the common tags handler. This is out of step with the core "structured block" handlers (the code that deal with TML blocks such as SECTION, and pseudo-HTML blocks like verbatim and literal). Not your fault, it's just the way plugin handlers work. You couldn't have done anything else without violating core encapsulation.

You have never mentioned any concerns about the syntax of IF statements before. Can you be more specific? The IF statement and type="query" search share a common expression syntax, so if there's a problem, we really need to fix it now rather than waiting for post-4.2.

-- CrawfordCurrie - 01 Sep 2007

The fact that IFDefinedPlugin is forced to extract blocks on its own (there is no "takeout/putback blocks" API in Func.pm) does not mean that it is inconsistent with TML. It does so in a very sensible way.

You invented a completely island syntax for the boolean expressions in IF statements. You were forced to implement a parser of its own, that is outside of the normal TML parser and you still keep adding features to it. In contrast to this IfDefinedPlugin just takes an arbitrary TML expression and checks a regex against it. Therefore it is much leaner. Despite of its approach, IfDefinedPlugin superseeds functionality of IF plus your proposal here. So the approach I took in IfDefinedPlugin can't be that wrong.

Baseline, IfDefinedPlugin is there to be used. If there is a problem with it we should fix it instead of inventing the wheel once again.

-- MichaelDaum - 01 Sep 2007

Prior to the introduction of %IF, the only way to evaluate boolean expressions was using SpreadSheetPlugin. IfDefinedPlugin acknowledges a dependency on SpreadSheetPlugin to evaluate boolean expressions. To claim it is "leaner" is missing the point somewhat; it is dependent on either SpreadSheetPlugin (or %IF, now) for boolean expression evaluation. When I started coding %IF I looked at the SpreadSheetPlugin expression syntax - it is also an invented, non-TML syntax. I elected not to re-use that syntax for various human interface reasons.

I introduced %IF because it was increasingly the case that the core templates were becoming dependent on SpreadSheetPlugin. Personally I don't believe it is sensible to delegate such an important core concept as an IF statement to a plugin, even when that plugin is bundled with the core. The core should be able to stand on it's own.

My belief is that we need a way to express templates as efficiently as possible, and that means that the inactive side of the condition - 'then' or 'else' - must not be evaluated unconditionally, as it must be in an %IF. We can solve this problem in a couple of ways:

  1. Accept a core dependency on IfDefinedPlugin
  2. Adopt a similar approach to IfDefinedPlugin, but implement it in the core
I was aiming to address (2).

If the general opinion is that a block-structured IF statement is not required in the core, and that IfDefinedPlugin is adequate for all end user requirements, then I'm quite happy to forget this proposal.

-- CrawfordCurrie - 02 Sep 2007

Tell you what, we can go on debating endless who invented what concept and why, which code is leaner in what terms, which syntax is more inconsistent, or wether the core is standing on its own or not. The syntaxes are already inconsistent (TML, SpreadSheetPlugin, IfStatement); the core does not stand on its own (see how it neglects TWikiTables); and so on ...

I'd prefer to find the best solution for conditionals and therefore let's see what we can do. Goals:

  1. add conditional sections, based on what is there in IF and IfDefinedPlugin
  2. fix the Func Api to make IfDefinedPlugin more efficitent

First, I'd like to have takeout/putback blocks in the Func Api. Thus IfDefinedPlugin and others can make use of it. Pending proposal for 4.3. No problem.

Second, let's refine your proposed syntax. The syntax of IF is already clumbsy/no beauty. IfDefinedPlugin gets way with less meta chars and is more intuitive to read. Let me rework you above proposal a bit:

%IFSECTION{"defined FLUB"}%
FLUB is defined
FLUB is not defined, but FLOP is
FLUB and FLOP are *not* defined

What do you think?

Third, how do we deal with whitespaces between blocks?

Fourth, I'd like to evaluate escaped TML in argument positions (using $percnt and similar, to work around inside-out).

Fifth, IfDefinedPlugin does regex checks ...

-- MichaelDaum - 02 Sep 2007

to simplify Micha's eg further... and to seperate concerns, and reduce needless bundling up to make monster TML's.

   %IF{"defined FLUB"}%
      FLUB is defined
  %ELSIF{"defined FLOP"}%
      FLUB is not defined, but FLOP is
      FLUB and FLOP are *not* defined

-- SvenDowideit - 03 Sep 2007

So you are saying that an IF that has no 'then' or 'else' should be treated as a %SECTION{type="if"? Hmmmm. Well, it's certainly do-able (it's just syntax).

I do not propose to support ELSIF - it's not english, and it's not necessary (it's just shorthand for %ELSE% %IF...)

I'm also not going to fix the Func API. While I agreed a fix is needed, I just don't have the energy. frown

BTW %IF supports the escaped TML standard in 4.2, though not before.

-- CrawfordCurrie - 03 Sep 2007

on reflection we can't overload %IF to serve double-duty as a section and inline tag. The reason is a user can write:

   * Set BLAH = "condition" then
and the inside-out-left-right rule will ensure it expands to a valid if. However during section processing no other variables have been expanded (this is essential for late evaluation) so the section processor can't tell if this is a block-level IF or an inline IF. So we have to use Michael's %IFSECTION..%ELSESECTION%...ENDSECTION% (personally I think this is fine; I always disliked ambiguity in keywords).

-- CrawfordCurrie - 06 Sep 2007

Topic attachments
I Attachment History Action Size Date Who Comment
Unknown file formatdiff ifblocks.diff r1 manage 13.3 K 2007-09-01 - 10:06 CrawfordCurrie Diff against 14684
Edit | Attach | Watch | Print version | History: r10 < r9 < r8 < r7 < r6 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r10 - 2007-09-06 - CrawfordCurrie
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by Perl Hosted by OICcam.com Ideas, requests, problems regarding TWiki? Send feedback. Ask community in the support forum.
Copyright © 1999-2017 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.