Forum OpenACS Development: New template tags - switch statement

I have implemented new templating tags to create a switch statement in openacs templates. The new tags are called <switch>, <case>, and <default>, and they are used as follows:

<switch @switch_var@>
    <case value="foo">
        You selected Foo
    </case>
    <case value="bar">
        You selected bar
    </case>
    <case value="baz">
        You selected baz
    </case>
    <default>
        Your selection was invalid
    </default>
</switch>

The switch tag also supports the exact, glob, and regexp flags supported by the tcl switch statement.


<switch flag="glob" @switch_var@>
    <case value="foo*">
        You selected Foo
    </case>
    .
    .
    .
    <default>
        Your selection was invalid
    </default>
</switch>

I've played around with other forms for the switch statement, but I think the previous form is the best. Variations include explicitly naming the switch condition:


<switch condition="switch_var">

or changing the case statements to pass the case value directly:


<case "foo">

Anyway, I'm open to suggestions, if people think it would be better to use a different form for the switch tags.

Collapse
Posted by Ola Hansson on
Way to go, Dan.

Can I ask for a feature? 😉

Do you think it could be made to work something like this (if it doesn't already):

<switch @switch_var@>
    <case value="foo" value="bar" value="baz">
        You selected Foo or Bar or Baz
    </case>
    <case value="blargh">
        You selected blargh
    </case>
    <default>
        Your selection was invalid
    </default>
</switch>
I am sure your <switch> tag will come in handy in many places.

/Ola

Collapse
Posted by Tilmann Singer on
That's great - no more need for nested tags like this:

<if>

</if>
<else>
  <if>

  </if>
  ...
</else>

Especially since mistakes in these constructs produce such obscure error messages. Thanks!

I also like Ola's suggestion for improvement.

Collapse
Posted by Ola Hansson on
Perhaps "<case value in foo bar baz ...>" is cleaner.
Collapse
Posted by Dan Wickstrom on
Ola, Your feature request is easy enough to implement, but it's already supported via the regexp flag:

<switch flag=regexp @switch_var@>
    <case value="foo|bar|baz">
        You selected foo bar or baz
    </case>
   .
   .
   .
</switch>

Of course regexps are kind of obscure to non-programmers, so your feature might be useful to make it more accessible to graphics designers...

Collapse
Posted by Roberto Mello on
This a great feature. Will sure come in handy.

I like the <case in foo bar baz> better. Using regexp's work, but if we don't necessarily have to use them (which seems to be this case), it's probably better since using the regexp engine is much more expensive.

Thanks Dan!

-Roberto

Collapse
Posted by Dan Wickstrom on
My only objection to the <case value in "foo" "bar" "baz"> format is that it isn't consistent with the rest of the tags in the templating system - not that the templating system is 100% consistent in it's use of tag formatting. Something like <case value="foo bar baz"> or <case value_in="foo bar baz"> or even Ola's original proposal would be more consistent with the templating system's overall style where paramters use the parameter="some value" format.
Collapse
Posted by Ola Hansson on
Dan,

<if @z@ in "Greta" "Fred" "Sam">True</if>

is taken from the templating tag reference for "if" page (https://openacs.org/doc/acs-templating/tagref/if.html).

It seems to be in line with the above...

Collapse
Posted by Dan Wickstrom on
I forgot about that one. I guess we could have <case in "foo" "bar" "baz"> just to be consistent with the <if> tag, which makes sense, since switch is just a specialized form of if/elseif/else.
Collapse
Posted by Don Baccus on
Yes, this last suggestion seems best ... switch statement ... cool!
Collapse
Posted by Dan Wickstrom on
Okay, I've modified the case statement to allow <case in ...> and the <case value=...> forms.
Collapse
Posted by Roberto Mello on
Excellent, Dan.

Did you add it to acs-templating's documentation? If not, I can do it.

-Roberto

Collapse
Posted by Roberto Mello on
I've just added Dan's recent addition to my forms tar ball for OpenACS 4.6 (because I want to use it in my 4.6. sites).

It's at the same place: http://www.brasileiro.net/code/

-Roberto

Collapse
Posted by Robert Locke on
<blockquote> It's at the same place: http://www.brasileiro.net/code/
</blockquote>

Hi Roberto,

I assume your cool tarball will not be included in the 4.6 release and that it is a separate download?  Will you be linking to it from the OACS site or documentation, or perhaps be transferring the tarball itself to the OACS site?

In any case, it seems very useful and should be prominently highlighted.  But, as much as possible, I think we should avoid having to download these things from other sites.

Thanks...

Collapse
Posted by Roberto Mello on
Robert,

It's a separate download because I did it for my own use, in my 4.6 sites. I made it available so those developing on 4.6 could use the form additions _now_, instead of when 4.6.1 is released.

I'm sure all these changes will go into 4.6.1 (and in that case, my tar ball could still be used to add the changes to 4.6.1, since I'm getting rid of the i18n calls that were put into HEAD).

But I don't know what are the CVS procedures to 4.6.1 yet, so nothing has gone back into CVS yet. Jeff is also planning to backport a bunch of stuff into 4.6.x, and we haven't discussed how this is going to be done yet.

I don't know how this could be prominently highlighted. It's not something required for 4.6 usage. I thought about putting it into file-storage, but it'd be more trouble for me and the URL would be ugly and hard to remember.

-Roberto

Collapse
Posted by Lars Pind on
Dan,

This is beautiful, thanks.

I only have one suggestion, which would be to move the condition entirely into the <case> par, for improved readability of the templates, like this:

<switch>
  <case @foobar@ true>
    ...
  </case>
  <case @baz@ eq "greble">
    ...
  </case>
  ...
  <case default>
    ...
  </case>
</switch>

That would make it easier to read the template, because you don't have to read both the <switch> statement and the <case> statement to find out what's going on.

/Lars

Collapse
Posted by Jeff Davis on
Lars, shouldn't your construct be
<if @foobar@ true>
    ...
</if>
<elseif @baz@ eq "greble">
  ...
</elseif>
...
<else>
  ...
</else>
(and we probably should add an elseif tag).
Collapse
Posted by Dan Wickstrom on
Looking in tag-init.tcl, I see that an elseif tag already exists, but I'm not sure why nobody ever uses it.  I sorta of recall a discussion in the past where it was mentioned that there were some problems with elseif, but looking at they code I don't see anything wrong with it.... and giving it a short test, I find that it does indeed work.
Collapse
Posted by Jeff Davis on
It looks like this was in the original import but never got documented.  That will teach me to use the templating documentation to check which tags exist :)
Collapse
Posted by Malte Sussdorff on
This addition is great and makes templates considerably more readable for non programmers. Though I disagree with Lars concerning his idea for storing the variable as well in the case statement for the following reasons:
  • You have to mention the variable in every case statement. Despite the fact that this allows a switch for multi variable combinations it does add more code and you have to doublecheck every case statement whether the variable is the same as in the above case statement.
  • As a grafik designer I'd see the switch statement, see what variable it concerns and decide quickly whether I'd want to change the code in between. That wouldn't work otherwise.
One suggestion would be to have the default behaviour as it is defined right now and add a flag "multiple" to the switch statement with no variable following. This would say that the variables are contained within the case tags as suggested by Lars. We'd just have to encourage people (either by code or by documentation), not to use the multiple functionality if the flag is not set correctly, otherwise you really don't know what might be happening :).
Collapse
Posted by Tom Jackson on

Lars,

That looks more like elseif which would also be nice to have.

I remember suggesting the which/case combination a few years back, but aD wasn't too interested in expanding the number of tags at that time. This sounds like a great addition to the mix.

Collapse
Posted by Lars Pind on
I realize that this isn't how Tcl's switch statement works.

Anyway, consensus seems to be against it. Never mind :)

/Lars

Collapse
Posted by Walter McGinnis on
Thanks Dan!

You have perfect timing.  I'm working on a site that uses a backported version of ATS.  I was having a bugger of time with a huge batch of nested if/elses in a master template.  I grabbed the switch code (and another supporting proc) and things cleaned up nicely.

Walter

Collapse
Posted by Don Baccus on
Roberto ... for a good time ...

Did you make the -cancel_url etc switches work with the "-confirm_template" feature of ad_form?

This (as yet) little known, even more rarely used feature partially automates the generation of "confirm"-style pages.  A chief benefit is that you can still use a single add/edit script and can associate it with a separate "confirm" template that formats and displayes the content (which might be, for instance, a bboard post or the like).

I also have a bunch of widgets from Greenpeace that folks might find interesting.  I've been hoping to find time to straighten them out for use with standard OpenACS and ad_form but if you're interested in playing more with form templating and widgets let me know and I can drop the GP widgets in your lap.

Also ... why don't we make your CSS'd lars-standard form template the OpenACS standard form template in HEAD and rename the current one "ugly-blue" ???

Anyone object to this?

Collapse
Posted by Roberto Mello on
Don,

Hmm, good point. I did not. But I'll look into it. Thanks for the tip.

I'd like to take a look at the GP widgets btw. Perhaps I can help getting them into the tree.

I can commit my CSS version to HEAD, but I'm not super at CSS and most likely there are things that can be improved, so it'd be good if someone better at CSS would look at it.

I think Jeff had done some work on a proposal to standardize CSS usage on the toolkit. Perhaps this could be the start of it.

-Roberto

Collapse
Posted by Don Baccus on
Yes, I'd asked Jeff to look into standardizing some basic CSS stuff for OpenACS, in part motivated by the fact that Sloan had slightly forked some code in order to include Sloan-specific CSS stuff for SloanSpace.  Forking we and they want to avoid so we do want to regularize this stuff and get back to common sources.

Anyway ... Jeff would be an ideal person for you to talk to if you want your template CSS stuff checked for correctness.

Collapse
Posted by Jeff Davis on
I am happy to look at it.  I also have css friendly
versions of the calendar widget and the old standard template.
Collapse
Posted by Andrei Popov on
Am I the only one for whom the great forms-latest breaks things?  I don't get a single element rendered -- only labels.  Don't get any errors either -- just blanks instead of text ans selects and only pictures (and no way to change values) for radio/check boxes.

It's as if formwidget fails to return the widget...

Collapse
Posted by Roberto Mello on
Andrei,

On HEAD?

-Roberto

Collapse
Posted by Andrei Popov on
Roberto,

On 4.6-final (as found in download section of openacs.org/4).  I understand that your 'replacements' are against a 4.6, right?  Had it been HEAD (head it been had? ;^)), I would be less surprised, so to speak...