See also
ConditionalRendering.
--
JeroenVanDongen - 10 Aug 2002
Nice Plugin. Some comments / I have not tried it out yet:
- Looking at the code, non-greedy regex is used. This makes sense, you can have several if-else-endif in a topic. In turn, nesting of if-else-endif is not supported. This should be documented.
- This is now documented. Support for nested constructs and/or elsif clauses will only be added if there is a clear demand for it. I've toyed with those features, though the parsing and handling gets pretty complex and it would take quite some time to get it right (jvd)
- The
Safe module is part of Perl 5.005_03
, thus fits the TWiki requirements. Worth mentioning in the Plugin dependencies that it is already in the required Perl distribution.
- added to the doc section (jvd)
- You could do a lazy loading of the
Safe module so that topics that we do not have a performance hit on topics that do not have conditional statements. See the ChartPlugin for an example.
- Done. I'll upload a new package soon (jvd)
--
PeterThoeny - 11 Aug 2002
This is an interesting plugin and in conjunction with
TopicVarsPlugin might solve one of my problems.
I am building a new skin with a left side panel. Easy enough, but I want to give the user the ability to remove the left side panel for certain topics that are very wide. Thus I need the ability to conditionally define template params. Would this plugin work for that or is the template processing special??
--
JohnCavanaugh - 10 Jan 2003
Interesting indeed. I'm not sure I grasp the details. While Perl is used to process topics, is there a way to "plugin" or "embed" perl commands? It just seems like with conditionals we are starting to recreate a full language. That may be necessary and desired, I'm just curious.
--
GrantBow - 16 Jan 2003
GrantBow: not without a plugin there isn't, because it would be
hideously insecure under most circumstances. This plugin actually interprets the conditional as Perl, but only if it fits within a very, very restricted form, and only inside a "sandbox" interpreter where it can do little harm.
BTW, I've attached a
patch to this plugin to allow for nested conditionals.
--
WalterMundt - 25 Jan 2003
Thanks for your effort, Walter. I was also trying to imply that there are other similar languages. I don't know if any of them have been considered for public use and users to type in!
--
GrantBow - 25 Jan 2003
Some conditional text is now also possible with the latest
SpreadSheetPlugin, based on the
$IF(condition, value if truw, value if false) formula.
--
PeterThoeny - 19 Apr 2003
It occurs to me that one use of this plugin is to limit what gets viewed according to user.
Something along the lines of:
%IF{ user in twikiadmingroup OR user in webadmingroup }%
display stuff about preferences, site and web maintenance
%ENDIF%
Right now it seems that would strain the syntax.
--
AntonAylward - 30 Apr 2003
Perhaps users of this plugin would like to contribute examples to make up a cook-book.
--
AntonAylward - 03 May 2003
I made a small change (beginning from the original plugin with Walter Mundt's nested conditionals patch applied)
to the code to allow for arbitrary strings (rather than just scalars) to be tested. The old syntax will still be accepted,
but instead of a scalar, you may now use any string enclosed in double quotes.
The nested conditionals patch made the
$prefixPattern superflous, so I removed it. I also do not see a reason
for
$postfixPattern, so I removed that one too (this has the side effect, that you no longer need to add a whitespace
or other separator character behind the
%ENDIF%.
The new (cummulative) patch is
here.
--
JohannesMartin - 14 May 2003
How to add text based on group membership:
I tried the following, with both the
ConditionalPlugin and
TopicVarsPlugin installed (and the latest patches to each):
Main.TWikiAdminGroup
%IF{ "%Main.TWikiAdminGroup.GROUP%" =~ "%USERNAME%" }% DOES %ELSE% does NOT %ENDIF%
contain %USERNAME%
...but it didn't work until I changed added "TWiki.TopicVarsPlugin, TWiki.ConditionalPlugin"
in that order to the INSTALLEDPLUGINS variable in the
TWikiPreferences topic.
--
MichaelHensley - 20 Jun 2003
I loaded the plugin, but it doesn't work with "." in the compared strings...
%IF{ Main.BryanRev eq Main.BryanRev }% Yes %ELSE% No %ENDIF%
Doesn't work, but if I take out the "Main." part, it does work. Any answers?
--
BryanRev - 16 Sep 2003
As soon as there are non word-characters in the strings you are testing (such as periods), you need to apply my
patch and enclose the strings in quotes. The plugin is coded not to allow non word-characters in unquoted strings (and quoted strings are only supported with my patch).
-
JohannesMartin - 08 Oct 2003
I just tried to combine the syntax with the URLPARAM variable, but it doesn't work. Two problems:
- If no URL parameter with the specified name is given, the complete syntax is being shown.
- If a URL parameter with the specified name is given, always the else part is being used.
Example:
- IF{ eq="1" testview="1" }: Empty expression
This is the test view. %ELSE% This is a regular view %ENDIF%
Here the result:
IF{ eq="1" testview="1" }: Empty expression
This is the test view. %ELSE% This is a regular view %ENDIF%
Could that be related to the patch that was proposed above?
--
MartinWolters - 12 Nov 2003
The problem in Martin's case is that the regular expression that handles the IF statement takes
URLPARAM 's closing brace as the closing brace of the
IF condition. I think if you quote the
URLPARAM, you will get what you want:
=
IF{ "'%URLPARAM{\"test\"" }: Syntax error in ''%URLPARAM{"test"' at ''%URLPARAM{"test"'
' eq 'testview' }%=...
--
JohannesMartin - 14 Nov 2003
No, still doesn't seem to work. Unfortunately I have no access to the TWiki directory itself and I hate to ask the sysadmin each time we have a new idea for source code changes. Otherwise I would try to debug the implementation ...
--
MartinWolters - 14 Nov 2003
Make sure you installed my patch. As my suggestion depends on =
IF{ }: Empty expression
= interpreting quotes right, it will not work without my patch applied.
You can view a working example at:
--
JohannesMartin - 20 Nov 2003
I have Greek topic names and \w does not recognise them. It could be a locale settings problem, but how about the more general \S anyway? Or, maybe, something like [^\s><=!~].
--
AntoniosChristofides - 01 Dec 2003
I have updated my Twiki Installation with the patch given by
JohannesMartin . I want to evaluate a URLPARAM variable using the IF condition. But I some how do not seem to get it right. I have tried the same example as given in
( equals %ELSE% does not equal %ENDIF% )
the output i got is as below.
!!IF{ 'test' eq 'test' }% equals %ELSE% does not equal %ENDIF%
However, normal examples like
Good evening folks!! %ELSE%
Good day folks!! %ENDIF%
are evaluated correctly. I use Cygwin on Apache running on Win 2000. I used the patch utility provided by Cygwin. Can anyone help me?
--
HarishSethuraman - 05 Jan 2004
I'm using conditionals within some customised templates (actually themes of
KoalaSkin templates). Since some of the conditionally included text is large, I've split the if/else/endif directives onto separate lines (for maintenance readability), rather than running them all together as most of the examples show. In places, the result is that I get unwanted spacing on the rendered page due to the lines that used to contain the directive being made blank; other TWiki rendering turns this into a <p> tag. I have made changes to the plugin on my system (which has both the patches applied) to fix this. In case it's considered useful for addition to the "official" plugin, here are the details. The changes are to the pattern variables, adding "\n?" just after each directive ...
$condPattern_ifonly = '(%IF{('.$word.$ops.$word.')}%\n?(.*?)%ENDIF%\n?)';
$condPattern_ifelse = '(%IF{('.$word.$ops.$word.')}%\n?(.*?)%ELSE%\n?(.*?)%ENDIF%\n?)';
I have tested both if/endif and if/else/endif variants and in both cases of all-on-one-line and directive-per-line. It seems to work, but I wouldn't call my testing exhaustive; just enough to get done what I wanted to do.
On another matter, I made another change that slightly improves performance (my system's response is fairly slow, so I want to eke out any improvements possible). On a test of 500k iterations (in a test bed) on a small piece of text, I got about 1.3% improvement (avg 18.74 sec -> 18.49). Not much, but I'll take it. The change is illustrated by this part of the diff output ...
< $endText =~ s/^$condPattern_ifelse/&handleConditional($2, $4, $5)/geos;
---
> substr($$text, $ifIndex) =~ s/^$condPattern_ifelse/&handleConditional($2, $4, $5)/geos;
In addition, variables $startText and $endText are no longer needed, nor the lines that set them and later concat them back into the text variable.
--
DavidHugill - 31 Jan 2004
Because this plugin is used, but does not appear to be maintained, I have switched the
CVS modification policy. If you have a problem with this, switch it back. If you want to check in patches or updates, go for it.
--
CrawfordCurrie - 03 Apr 2004
I'm trying to get this
ConditionalPlugin to evaluate using a
TWikiForm field. But I'm having trouble using the %FORMFIELD% variable to determine the value of the form field. I have applied the latest patch, and here is what I'm currently trying to use:
%IF{ '%FORMFIELD{Type}%' eq 'Subject' }% %INCLUDE{%TWIKIWEB%.Forum}% %ENDIF%
But the rendered output shows this in the view results:
!!IF{'Subject' eq 'Subject'}%
...INCLUDED TOPIC IS HERE...
%ENDIF%
So it seems that the IF/ENDIF is being mangled and ignored.
--
AdamTheo - 17 Jul 2004
Remember, you have to use doublequotes (") to separate the statements: "Subject" eq "Subject"
In Perl 5.8 we discovered some problems with
Opcode
. Maybe the behaviour gets changed? We now commented out $sandbox->permit_only(qw(:base_core)); in
ConditionalPlugin.pm to make it work again.
--
AndreUlrich - 26 Aug 2004
The same at our site: the plugin works for the example but fails for most other cases.
Expanding opcode with :base_orig solves problem:
$sandbox->permit_only(qw(:base_core :base_orig));
--
AndrasSzell - 14 Oct 2004
I notice that the original unpatched version breaks when reserved Perl words are used as text, since the code passes text as barewords, which is nasty. For example,
%IF{ yes eq yes }% foo %ENDIF%
works, because
yes is a valid bareword, but
%IF{ no eq no }% foo %ENDIF%
breaks, because
no is a reserved Perl word. For this reason I would strongly recommend use of the patch which allows quoting.
--
AdamSpiers - 19 Jan 2005
Just noticed another issue, this time with the NestedConditionalsWithArbitraryStrings.patch. AFAICS, it only allows use of double-quotes, but the contents of the string inside double-quotes is not protected against interpolation by
Safe::reval(). Therefore if you have something like
* Set BROADCASTMESSAGE = <span class="myclass">Look mum, here's an announcement!</span>
and you want to use a conditional somewhere, e.g. (in this example it would be in your templates):
%TMPL:DEF{"announcement"}%%IF{ "%BROADCASTMESSAGE%" ne "" }%<div class="announcement">
<h3>%BROADCASTTITLE%</h3>
<p>%BROADCASTMESSAGE%</p>
</div>%TMPL:END%
then the quoting in the code passed to
Safe::reval goes wrong because of the double-quotes in the value
BROADCASTMESSAGE is set to.
I've rewritten the parsing code and attached my latest version.
Beware! - only minimal testing has been performed. Changes from NestedConditionalsWithArbitraryStrings.patch version:
- Fix issue with stuff inside quotes interpolating, and support single-quotes too
- single/double quotes are treated identically - the outer quotes are stripped, any remaining single quotes are escaped, then the expression is wrapped in single quotes again, ready for passing as part of the raw Perl code to
Safe::reval(). I'm guessing that this should also fix $foo type stuff being accidentally interpolated.
- Remove unnecessary globals
- Check for compile errors etc. from
Safe::reval()
--
AdamSpiers - 10 Oct 2005
Recent changes (in 4.0.2, anyway) conflict with this plugin. lib/TWiki/If.pm supports =
IF{ "..." }: Missing operator in '...'
and seems to make the IF parts of most expressions disappear.
The built-in %IF syntax makes it more difficult to have large conditional blocks (AFAICT, anyway).
I've modified my personal copy so that the
ConditionalPlugin no longer uses
IF{ "..." }: Missing operator in '...'
but uses %IFTRUE{ ... }% instead. I've attached it to this topic as IFTRUE_ConditionalPlugin.
--
ChristopherRued - 05 Apr 2006
I tried IFTRUE (2006-04-05) from
ChristopherRued but got some errors. After testing a while I found that it is a problem of the security settings from the inner sandbox. I changed following code an now it works. It would be nice if someone could give an info if this setting is good or is a (high) security risc
100c9100c99,100
< $sandbox->permit_only(qw(:base_core));
>
$sandbox->permit_only(qw(:default));
>
$sandbox->deny(qw(:base_io));
Thanx, Tom
--
ThomasFreudenberg - 09 Jul 2006
What's happened to this? There's apparently been no work for over a year and I see lots of errors on the
ConditionalPlugin page. The idea looks so promising. It should be part of
SpreadSheet! :-(
--
VickiBrown - 22 Jul 2007