View previous topic :: View next topic |
Author |
Message |
Dasher Smarty Pro
Joined: 16 May 2007 Posts: 124 Location: Italy
|
Posted: Fri May 18, 2007 7:56 pm Post subject: Switch statements |
|
|
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:
or
Any thoughts?
Regards,
Dasher |
|
Back to top |
|
boots Administrator
Joined: 16 Apr 2003 Posts: 5611 Location: Toronto, Canada
|
|
Back to top |
|
Dasher Smarty Pro
Joined: 16 May 2007 Posts: 124 Location: Italy
|
Posted: Sat May 19, 2007 4:26 am Post subject: |
|
|
/me mutters something about poor search criteria
Wow. Exactly what I need |
|
Back to top |
|
Dasher Smarty Pro
Joined: 16 May 2007 Posts: 124 Location: Italy
|
Posted: Sat May 19, 2007 7:20 am Post subject: |
|
|
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 |
|
kienpham2000 Smarty n00b
Joined: 13 Oct 2007 Posts: 1
|
Posted: Sat Oct 13, 2007 8:42 pm Post subject: Thank you! |
|
|
Thank you Dasher for your switch plugin. It ran so fine |
|
Back to top |
|
zoizo Smarty n00b
Joined: 17 Mar 2009 Posts: 1
|
Posted: Wed Mar 18, 2009 4:15 pm Post subject: |
|
|
[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 |
|
BloodDragon Smarty n00b
Joined: 25 Jan 2010 Posts: 3
|
|
Back to top |
|
pynej Smarty Rookie
Joined: 07 Mar 2008 Posts: 8
|
Posted: Tue Feb 09, 2010 5:05 pm Post subject: |
|
|
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 |
|
|