Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

Switch statements

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Feature Requests
View previous topic :: View next topic  
Author Message
Dasher
Smarty Pro


Joined: 16 May 2007
Posts: 124
Location: Italy

PostPosted: Fri May 18, 2007 7:56 pm    Post subject: Switch statements Reply with quote

I was thinking about exploring the idea of implementing a switch/case method for Smarty. I miss the simplicity of this approach and I've never been a fan of nested IF statements.

I haven't yet looked at compiler plugins but I was thinking of doing it via an include to the client application to PHP.

Something along the lines of:

Application developed in PHP using the Smarty Template Engine:

Application implements in common.php (or some such):
require_once("smarty_switch.php")
initSmartySwitch($smartyObj);

This then registers some functions with smarty which could then be used in templates.

In the Smarty templates themselves you would use syntax along the lines of:

Code:
{switch eval=$something}
  {switch case="this"}
    do something
  {switch x=end}
  {switch case="other"}
    do something else
  {switch x=end}
{switch end=eval}


The syntax is a little cumbersome because you can't have functions with anonymous variables - Smarty complains when using:

Code:
{case "this"}


or

Code:
{switch end}



Any thoughts?

Regards,

Dasher
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
boots
Administrator


Joined: 16 Apr 2003
Posts: 5611
Location: Toronto, Canada

PostPosted: Sat May 19, 2007 3:42 am    Post subject: Reply with quote

http://www.phpinsider.com/smarty-forum/viewtopic.php?p=7069#7069
Back to top
View user's profile Send private message
Dasher
Smarty Pro


Joined: 16 May 2007
Posts: 124
Location: Italy

PostPosted: Sat May 19, 2007 4:26 am    Post subject: Reply with quote

/me mutters something about poor search criteria

Wow. Exactly what I need Smile
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Dasher
Smarty Pro


Joined: 16 May 2007
Posts: 124
Location: Italy

PostPosted: Sat May 19, 2007 7:20 am    Post subject: Reply with quote

Taking the example provided by messju from boots' reference - I've modified it slightly. Full credit to messju - I just mangled his code to suit my needs.

block.switch.php

Code:

<?php

/**
* Smarty {switch}{/switch} block plugin
*
* Type: block function<br>
* Name: switch<br>
* Purpose: container for {page}...{/page} blocks
* author: messju mohr <messju@lammfellpuschen.de>
* very slightly modified: dasher <dasher@inspiredthinking.co.uk>
* @param array
* Params: expr: string|numeric to be tested
* @param string contents of the block
* @param Smarty
* @return string
*/
function smarty_block_switch($params, $content, &$smarty, &$pages) {

   if (is_null($content) && !array_key_exists('expr', $params)) {
      $smarty->trigger_error("{switch}: parameter 'expr' not given");
   }
   return $content;
}


?>



block.case.php

Code:

<?php

/*
* Smarty {case}{/case} block plugin
*
* Type: block function<br>
* Name: case<br>
* Purpose: element inside {switch}...{/switch} block
* author: messju mohr <messju@lammfellpuschen.de>
* slightly Modified & expanded by: dasher <dasher@inspiredthinking.co.uk>
* @param array
* Params: expr: string|numeric to be tested
* @param string contents of the block
* @param Smarty
* @return string
*/
function smarty_block_case($params, $content, &$smarty, &$repeat) {

   if (is_null($content)) {
      /* handle block open tag */

      /* find corresponding {switch}-block */
      for ($i=count($smarty->_tag_stack)-1; $i>=0; $i--) {
         list($tag_name, $tag_params) = $smarty->_tag_stack[$i];
         if ($tag_name=='switch') break;
      }

      if ($i<0) {
         /* {switch} not found */
         $smarty->tigger_error("{case}: block not inside switch}-context");
         return;
      }

      if (isset($tag_params['_done']) && $tag_params['_done']) {
         /* another {case} was already found */
         $repeat = false;
         return;
      }
      
      // $tab_params['expr'] & $params['expr'] needs to be evaluated
      // For now - only worry about the expression passed by the case statement
      
      $testExpression = smarty_block_case_eval($params['expr']);

      if (isset($params['expr']) && ($testExpression!=$tag_params['expr'])) {
         /* page doesn't match */
         $repeat = false;
         return;
      }

      /* page found */
      $smarty->_tag_stack[$i][1]['_done'] = true;
      return;

   } else {
         /* handle block close tag */
         return $content;
   }

}


function smarty_block_case_eval($expression='') {
   // Evaluates the expression
   
   $wrapper = "echo {expression} ;";
   $testExpression = str_ireplace("{expression}", $expression, $wrapper);

   ob_start();
   eval(trim($testExpression));
   $content = ob_get_contents();
   ob_end_clean();
   return $content;
   
}

?>


The code can be a little tighter in the smarty_block_case_eval function - but I prefer something a little more expressive for testing and debugging.

This allows usage in the .tpl such as:

Code:


<br/><b>Switch/case Test</b><br/>

<br/><b>Example 1</b><br/>
<!-- Setup a variable to test with -->
{assign var=toTest value="word"}

<!-- Start the Switch Statement -->
{switch expr=$toTest}
   {case expr="The"}
      case "The"<br/>
   {/case}
   {case expr="word"}
      case word<br/>
   {/case}
    {case}
      Default used as nothing found.  Humm - maybe an alias should be defined for default - to allow for the default keyword.<br/>
   {/case}
{/switch}

<br/><b>Example 2</b><br/>
<!-- Setup a variable to test with -->
{assign var=toTest value=5}

<!-- Start the Switch Statement -->
{switch expr=$toTest}
   {case expr="The"}
      case "The"<br/>
   {/case}
   {case expr=1}
      case 1(numeric)<br/>
   {/case}
   {case expr=2+3}
      case an evaluated expression<br/>
   {/case}
    {case}
      Default used as nothing found.  Humm - maybe an alias should be defined for default - to allow for the default keyword.<br/>
   {/case}
{/switch}

<br/><b>Example 3</b><br/>
<!-- Setup a variable to test with -->
{assign var=toTest value=5}

<!-- Start the Switch Statement -->
{switch expr=$toTest}
   {case expr=1}
      case 1<br/>
   {/case}
   {case expr=2}
      case 2<br/>
   {/case}
   {case expr=3}
      case 3<br/>
   {/case}
    {case}
      Default used as nothing found.  Humm - maybe an alias should be defined for default - to allow for the default keyword.<br/>
   {/case}
{/switch}

<br/><b>Example 4</b><br/>
<!-- Setup a variable to test with -->
{assign var=toTest value="word"}

<!-- Start the Switch Statement -->
{switch expr=$toTest}
   {case expr="The"}
      case "The"<br/>
   {/case}
   {case expr="WORD"|lower}
      case Modifier("WORD"|lower)<br/>
   {/case}
    {case}
      Default used as nothing found.  Humm - maybe an alias should be defined for default - to allow for the default keyword.<br/>
   {/case}
{/switch}


Some things to note:
1) Anything between a {/case} and {case} will always appear. Such as

Code:
   {case expr=1}
      case 1<br/>
   {/case}
                    This will always be displayed.
   {case expr=2}
      case 2<br/>
   {/case}


Personally I prefer it this way - it's very handy when debugging.

2) The code has only been lightly tested and I've not looked much as error conditions and error recovery yet. I'll be implementing an error handler for the eval code using set_error_handler.

Quote:
3) I haven't looked at the effect of modifiers yet - and I don't know the order of execution. If the block handler tags get called before the modifier is applied - then the eval will fail.


[edit]
Tested modifiers and updated the example - happily modifiers work without any changes needed.
[/edit]
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
kienpham2000
Smarty n00b


Joined: 13 Oct 2007
Posts: 1

PostPosted: Sat Oct 13, 2007 8:42 pm    Post subject: Thank you! Reply with quote

Thank you Dasher for your switch plugin. It ran so fine Smile
Back to top
View user's profile Send private message
zoizo
Smarty n00b


Joined: 17 Mar 2009
Posts: 1

PostPosted: Wed Mar 18, 2009 4:15 pm    Post subject: Reply with quote

[16-Mar-2009 22:34:46] PHP Parse error: syntax error, unexpected ';' in /home/****/public_html/libs/plugins/block.case.php(55) : eval()'d code on line 1

How do I fix this error?
Back to top
View user's profile Send private message
BloodDragon
Smarty n00b


Joined: 25 Jan 2010
Posts: 3

PostPosted: Mon Jan 25, 2010 10:09 am    Post subject: Reply with quote

Please check this topic for a new switch plugin by me, for Smarty 3: http://www.smarty.net/forums/viewtopic.php?p=62308#62308
Back to top
View user's profile Send private message
pynej
Smarty Rookie


Joined: 07 Mar 2008
Posts: 8

PostPosted: Tue Feb 09, 2010 5:05 pm    Post subject: Reply with quote

My original switch plugin is available for Smarty 2 and Smarty 3.

It supports shorthand syntax, nesting statements, and complex variable processing.

Example:
Code:

{switch $myvar}
  {case 1}
  {case $var}
  {break}
  {case $myvar|my_modifyer break}
  {default}
{/switch}
Back to top
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Feature Requests All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP