1 of 2
1
Plugin: Switchee
Posted: 15 February 2010 11:41 AM   [ Ignore ]  
Lab Assistant
Avatar
RankRank
Total Posts:  251
Joined  10-08-2002

A very simple plugin that allows you to create switch/case control logic in your templates.

With EEs if/else conditionals, each condition is parsed before being removed at the end of the parsing process. This means if you wrap if/else tags around lots of other tags then your template will be running many unnecessary queries and functions.

As Switchee is a tag we can use parse=“inward” to ensure that unmatched conditions are not parsed before being removed from the template.

Switchee can only be used for simple conditional logic. Like PHPs switch/case, it supports a default value.

Example:

{exp:switchee variable "{variable_to_test}" parse="inward"}
    
    {case value
="value1|value2"}
        Content to show
    {
/case}
    
    {case value
="value3" default="Yes"}
        Content to show
    {
/case}
    
    {case value
="#^P(\d+)$#|''"}
        
Use regular expressions enclosed by hashes #regex#
        
Be careful to encode the following reserved characters as follows:
        
= & #123;
        
| = & #124;
        
= & #125;
        
Use '' to represent an empty string
    {
/case}
    
{
/exp:switchee} 

Note that ‘default’ can also be used on it’s own:

{case default="Yes"

In some of my templates I’ve seen a 30% decrease in queries by using Switchee in preference to if/else.


17 Feb 2010 - updated to version 1.1

* Now allows multiple case values separated by pipe ‘|’.


19 Feb 2010 - updated to version 1.2

* Now supports regular expression matching like so: #regex#
* Supports empty string matches represesnted by ‘’ or “”


22 Feb 2010 - updated to version 1.3

* Added support for reserved characters in regular expressions
* Multiple regular expressions separated by | can now be used safely for one case value


24 Feb 2010 - updated to version 1.4

* fixed a minor bug

Still to do: Enable Switchee to be nested inside itself.

File Attachments
pi.switchee.zip  (File Size: 2KB - Downloads: 246)
Profile
 
 
Posted: 16 February 2010 01:05 PM   [ Ignore ]   [ # 1 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  2522
Joined  02-28-2008

Interesting….but isn’t ‘case’ the same load as the condition of ‘if’?
Can you set variables value to be = weblog fields?
and can it hold multiple values?
{variable_to_test}= apples, oranges,plums
or
{variable_to_test} = 1,7,23,69

Thanks for sharing!

 Signature 

Defeat is a state of mind; no one is ever defeated until defeat has been accepted as a reality.

Profile
 
 
Posted: 16 February 2010 01:50 PM   [ Ignore ]   [ # 2 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  251
Joined  10-08-2002

Interesting….but isn’t ‘case’ the same load as the condition of ‘if’?

No - {if} is parsed AFTER the various conditions contained within it have been parsed. So if you have 5 if:elseif conditions, all 5 will be parsed, before the 4 non-matching conditons are removed.

With my plugin set with parse=“inward”, only the matching condition will be parsed.

Can you set variables value to be = weblog fields?

Yes, if you are using it inside the exp:weblog tag.

{exp:weblog:entries}
{exp
:switchee variable "{my_custom_field}" parse="inward"}
    
    {case value
="value1"}
        Content to show
    {
/case}
    
    {case value
="value2" default="Yes"}
        Content to show
    {
/case}
    
    {case value
="value3"}
        Content to show
    {
/case}
    
{
/exp:switchee} 
{
/exp:weblog:entries} 

and can it hold multiple values?
{variable_to_test}= apples, oranges,plums
or
{variable_to_test} = 1,7,23,69

No - since we’re testing if each condition matches the variable - but I will be adding multiple case values very shortly:
{case value=“apples|oranges”}

Which makes more sense if you think about it smile

Profile
 
 
Posted: 16 February 2010 02:08 PM   [ Ignore ]   [ # 3 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  2522
Joined  02-28-2008

Right right…in that case my hat of to you.wink
This can be very handy for those wanting the extra boost in performance {if} they are riding on lot of conditions such as extra large menu-navigation etc.

I wonder how it matches up to {if:else}:

{if field =='apple'}
Ummm apple pie
...
{if:else}
D
'ouh! Apply doughnut patch.
{/if} 

Do tell!

Good stuff!

 Signature 

Defeat is a state of mind; no one is ever defeated until defeat has been accepted as a reality.

Profile
 
 
Posted: 16 February 2010 04:22 PM   [ Ignore ]   [ # 4 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  272
Joined  11-06-2007

Great work.  I really need this to support multiple case values as you noted would be coming soon.

Any chance you have this working yet?

{case value="apples|oranges"
Profile
 
 
Posted: 17 February 2010 05:23 AM   [ Ignore ]   [ # 5 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  251
Joined  10-08-2002

Done - download the latest version from the first post, it now supports multiple case values.

Profile
 
 
Posted: 17 February 2010 12:02 PM   [ Ignore ]   [ # 6 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  277
Joined  10-10-2004

Hey Mark, this sounds great but the tag pairs you are using, “case,” are a little confusing to me. Would you mind drawing up a real world example showing how this works?

 Signature 

Twitter: @RobQuigley

Profile
 
 
Posted: 17 February 2010 12:46 PM   [ Ignore ]   [ # 7 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  251
Joined  10-08-2002

Switch/case, like if/else, is a common programming control statement; see for example:
http://php.net/manual/en/control-structures.switch.php

Here’s a simple example. What I’m doing is showing either a list of headlines or a single story, depending on whether segment_2 exists. So my uris might look like:

Headlines view:
mywebsite.com/news

Single story view:
mywebsite.com/news/my-news-story

Switchee will check the value of {segment_2} to choose which case to show.

The first case is for when {segment_2} is equivalent to “” (an emtpy string)

The second case is the default case that will be shown if the first case doesn’t match.

{exp:switchee variable="{segment_2}" parse="inward"}
            
            {
!-- Homepage view --}
            {case value
=""}

                
<!-- 10 headlines -->
                
{exp:weblog:entries weblog="news" orderby="date" sort="desc" limit="10" disable="member_data|trackbacks|pagination|categories"}
                        
<h4><a href="{title_permalink=news/index}">{title}</a></h4>
                        <
p>{summary}</p>
                
{/exp:weblog:entries}
                
<!-- /10 headlines -->
                
            
{/case}
            {
!-- /Homepage view --}

            {
!-- Single story view --}        
            {case 
default="Yes"}

                
<!-- story -->
                    
{exp:weblog:entries weblog="news" orderby="date" sort="desc" limit="1" disable="member_data|trackbacks|pagination"}

                        
<h3><a href="{title_permalink=news/index}">{title}</a></h3>
                        
                        <
class="intro">{summary}</p>
                        
                        
{body}

                        
<dl class="metadata">
                            <
dt>Posted by:</dt>
                            <
dd><a href="{path=member/{author_id}}">{author}</aon {entry_date format="%D, %F %d, %Y at %g:%i:%s %A"}</dd>
                            
                            <
dt>Categories:</dt>
                            <
dd>                    
                                
{categories backspace="1"}
                                
<a href="{path=news}">{category_name}</a>,
                                
{/categories}
                            
</dd>
                
                        </
dl>
                    
{/exp:weblog:entries}
                
<!-- /story -->
                
            
{/case}
            {
!-- /Single story view --}
            
            {
/exp:switchee} 
Profile
 
 
Posted: 17 February 2010 01:05 PM   [ Ignore ]   [ # 8 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  277
Joined  10-10-2004

Ahhh - I get it now. Thanks so much for drafting that! Great work on this plugin. I will use it for sure!

I’ve been using some php conditionals for URL segments and parsing on input so that the template doesn’t process those EE tags that are in the php conditional blocks that evaluate false.

But, occasionally, I need parsing on ouput or have conditional situations that only EE variables will work.

Hats off on this work!

 Signature 

Twitter: @RobQuigley

Profile
 
 
Posted: 19 February 2010 02:56 PM   [ Ignore ]   [ # 9 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  251
Joined  10-08-2002

Updated to version 1.2, which now supports regular expression matches within #hashes# and empty strings represented by ‘’ or “”.

Profile
 
 
Posted: 22 February 2010 01:43 PM   [ Ignore ]   [ # 10 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  251
Joined  10-08-2002

Updated to version 1.3.

* Added support for reserved characters in regular expressions
* Multiple regular expressions separated by | can now be used safely for one case value

Profile
 
 
Posted: 24 February 2010 01:20 PM   [ Ignore ]   [ # 11 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  251
Joined  10-08-2002

Updated to version 1.4

* fixed a minor bug

Profile
 
 
Posted: 24 February 2010 02:20 PM   [ Ignore ]   [ # 12 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  272
Joined  11-06-2007

Mark,

I really like your plugin and your example for including page and entry views.  What do you think is the best way to handle pagination in the case that the “home-page” view includes pagination?  The pagination links would be directed into the story view.

Profile
 
 
Posted: 25 February 2010 04:57 AM   [ Ignore ]   [ # 13 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  251
Joined  10-08-2002

Hi Joe, glad you like it!

to account for pagination (P0, P1, P3 etc) is actually pretty easy.

Let’s say you have a template viewable at www.my_site.com/template_group/template

A paginated page might look like www.my_site.com/template_group/template/P2

So the patterns we need to match in segment 3 are #^P(\d+)$# and ‘’ (nothing)

We can use a pipe | to separate these patterns, so:

{exp:switchee variable="{segment_3}" parse="inward"}
            
    {
!-- Index pageMatch empty string or pagination --}
    {case value
="#^P(\d+)$#|''"}
        Index page
    {
/case}
                
    {
!-- Single entry --}
    {case 
default="yes"}
        Single entry
    {
/case}
                
{
/exp:switchee} 

if you also wanted to filter your index page entries by date, so that your urls look like:

www.my_site.com/template_group/template/2010/02

Or when paginated:

www.my_site.com/template_group/template/2010/02/P2

You could instead use this as your first case value:

{case value="#^P(\d+)$#|''|#^(\d& #123;4& #125;)$#"

(remove the spaces between the & and the # in the pattern)

Profile
 
 
Posted: 25 February 2010 10:53 AM   [ Ignore ]   [ # 14 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  272
Joined  11-06-2007

perfect…  thanks Mark!

Profile
 
 
Posted: 25 February 2010 11:26 AM   [ Ignore ]   [ # 15 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1753
Joined  03-26-2006

This looks like a nice alternative to MD Detect Page Type. The logic might be a little cleaner using Switchee. Think I’ll give it a try on my current project.

 Signature 

ryan masuga
—————
Masuga Design | devot:ee
@masuga | @masugadesign | @devot_ee

Profile
 
 
Posted: 25 February 2010 12:01 PM   [ Ignore ]   [ # 16 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  251
Joined  10-08-2002

Great stuff, let me know how you get on.

You will also get a very significant reduction in page load over using MD Detect Page Type, as the non-matching cases are removed by Switchee before they get parsed by EE.

Profile
 
 
Posted: 25 February 2010 12:02 PM   [ Ignore ]   [ # 17 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1753
Joined  03-26-2006

Right. Nice work, Mark!

 Signature 

ryan masuga
—————
Masuga Design | devot:ee
@masuga | @masugadesign | @devot_ee

Profile
 
 
Posted: 26 February 2010 09:39 AM   [ Ignore ]   [ # 18 ]  
Summer Student
Avatar
Total Posts:  8
Joined  04-18-2006

Can {member_group} be used as the variable to test against? I’ve got the following in an embedded template but doesn’t seem to work. Is it a parsing order problem / that it’s within an embed?:

{exp:switchee variable="{member_group}" parse="inward"}
    {case value
="1|6"}
        admin content
    {
/case}
    {case 
default="Yes"}
        non
-admin content
    {
/case}
{
/exp:switchee} 
Profile
 
 
   
1 of 2
1