Smarty Forum Index Smarty
The discussions here are for Smarty, a template engine for the PHP programming language.

ADVANCED: Recursion with Smarty
Goto page Previous  1, 2, 3, 4 ... 9, 10, 11  Next
 
Post new topic   Reply to topic    Smarty Forum Index -> Tips and Tricks
View previous topic :: View next topic  
Author Message
boots
Administrator


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

PostPosted: Fri Jun 13, 2003 2:14 am    Post subject: Reply with quote

Hi jewdogg.

Can you give a more specific idea or example of what your are trying to do?
Back to top
View user's profile Send private message
sweatje
Smarty Regular


Joined: 17 Apr 2003
Posts: 70
Location: Bettendorf, Iowa, USA

PostPosted: Fri Jun 13, 2003 3:05 am    Post subject: Reply with quote

I just recently implemented a script that renders a hierarchy. I was able to construct a single array to send to Smarty to accomplish the rendering.

The structure looked like this:
[php:1:bf0888d50c]<?php
$a = array(
'1' => array('desc' => 'key 1 value', 'children' => array('2', '4')),
'2' => array('desc' => 'key 2 value', 'children' => array(),
//...and so on
);
?>[/php:1:bf0888d50c]

Then in the template, I would pass the root node key and the array, I would render the recusive template passing the root node key as a variable, and the the recursive template would loop over the children array and call the template with the appropriate keys.

HTH

[edit:] incidentally, I have a static copy of what I was doing here. Kind of some cool js based navigation if you want to play a little Very Happy
_________________
Jason
jsweat_php AT yahoo DOT com
Back to top
View user's profile Send private message
boots
Administrator


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

PostPosted: Wed Aug 27, 2003 6:17 am    Post subject: Reply with quote

messju wrote:
@Transistor: your numbers make me feel, i should support my defun-hack a little more. Smile

i think we still need some better function-names for it.
"call-template" instead of "fun" is not good, because of the "-".
"template" is not good for the "defun". a "template" is almost always a file in smarty nomenclature.

i'd vote for calling our functions inside templates "sub-templates".

instead of "defun" for declaring a sub-template we could say:
{sub name="sub-template-name"}...{/sub} to define a sub-template
instead of "fun" for calling such a sub-template we could say:
{include_sub name="sub-template-name"}
"include_sub" since it behaves a bit like {include} or {include_php} template, especially regarding variable's scope.

what do you think?

i would also like to convert the "fun"-compiler-function to a normal plugin-function. this will imply a little performance hit, but the plugin becomes simpler and cleaner. overall it's easiest to do as little as necessary at compiler-level and the rest at "normal" plugin-level IMHO.

Is there any chance that something like this might actually end up in the distribution? Asides from speeding certain looping types, I like the fact that it allows one to group several sub-templates into a single template. That way, if you know that several related templates are always used together, you can define them in a single template file thereby reducing the overall number of needed includes. Overall, this thread hosts some of my favourite of the various unofficial "features" Smile (another: compile-time assign plugin)
Back to top
View user's profile Send private message
messju
Administrator


Joined: 16 Apr 2003
Posts: 3336
Location: Oldenburg, Germany

PostPosted: Wed Aug 27, 2003 3:24 pm    Post subject: Reply with quote

boots wrote:
Is there any chance that something like this might actually end up in the distribution?


i think not. i think smarty's feature catalog has already reached a critical mass. another con: i refuse to port the defun-hack to php5. in php5 you cannot call your function-parameters "$this" (something essential why defun was so easy to implement).

hmm, if i get more of these lovely 25hour-days i can add them to the wiki (with documentation and a download-link for a tarball).
Back to top
View user's profile Send private message Send e-mail Visit poster's website
boots
Administrator


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

PostPosted: Wed Aug 27, 2003 8:30 pm    Post subject: Reply with quote

messju wrote:
boots wrote:
Is there any chance that something like this might actually end up in the distribution?

i think not. i think smarty's feature catalog has already reached a critical mass.

Yeah, I figured Sad I guess I was just thinking that sometime features are added (2.6.0 is a good example) and that this one was quite powerful. Well, no need to cry about it I guess--my favourite parts are already in plugin form and they seem to work with 2.6.0 Smile

By-the-way, I see that on the lists sometimes but I'm not sure what it means that "Smarty's feature set is at critical mass". Does that allude to performance or maintenance?

cheers.
Back to top
View user's profile Send private message
messju
Administrator


Joined: 16 Apr 2003
Posts: 3336
Location: Oldenburg, Germany

PostPosted: Wed Aug 27, 2003 9:09 pm    Post subject: Reply with quote

boots wrote:
"Smarty's feature set is at critical mass". Does that allude to performance or maintenance?


of course maintenance is an issue to me. not being able to raise performance because of the duty to keep backwards compatibility to obscure features maybe another one here and there, but not that big.

to me it's mostly not to make it easier to exploit smarty's template language as it is already. smarty is so tempting to put too much into the templates and each feature that affects the template-language makes it more dangerous.

smarty was always meant to be lean and mean. it's hard (i'm afraid sometimes impossible) not to loose that focus when trying to improve it.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Transistor
Smarty Rookie


Joined: 20 May 2003
Posts: 9

PostPosted: Wed Aug 27, 2003 9:51 pm    Post subject: Reply with quote

messju wrote:

i think not. i think smarty's feature catalog has already reached a critical mass. another con: i refuse to port the defun-hack to php5. in php5 you cannot call your function-parameters "$this" (something essential why defun was so easy to implement).


Because of this line?

Code:
return "if (!function_exists('$_func')) { function $_func(&\$this, \$params) { \$_fun_tpl_vars = \$this->_tpl_vars; \$this->assign(\$params); ";


Why does it has to be called $this?
Isn't
Code:
function $_func(&\$abc, \$params) { \$_fun_tpl_vars = \$abc->_tpl_vars; \$abc->assign(\$params);

the same?
As far as i know the $this problem with php5 is only a naming problem, but i don't know to much about php5 or smarty so far:)

Transistor


Last edited by Transistor on Sat Aug 30, 2003 1:25 pm; edited 1 time in total
Back to top
View user's profile Send private message
eis_os
Smarty Rookie


Joined: 06 Aug 2003
Posts: 8

PostPosted: Fri Aug 29, 2003 10:57 am    Post subject: Reply with quote

Hi

I am using defun with 2.5.0 + defun currently,
but I have havy problems with safemode and not finding the right pluging dir. ( "." doesn't work as include_dir) so I want to updata to 2.6.0 RC1.

Is there any better version of fun now with the new block function,
currently I can't figure out how to use block Crying or Very sad

Here is my current defun code block:

Code:

{defun name="navirecursion" list=$categorietree callerkey=0}
{foreach from=$list key=mkey item=element}
{if $element}
<tr><td colspan="2">&<A HREF="{$baseurl}act=list&cid={$mkey}">{$categories.$mkey.category_name}</A> -&</td></tr>
<tr><td width="15">&</td><td><table width="100%" cellpadding="0" cellspacing="0">
{fun name="navirecursion" list=$element callerkey=$mkey}
</table></td></tr>
{else}
<tr><td colspan="2">&<A HREF="{$baseurl}act=list&cid={$mkey}">{$categories.$mkey.category_name}</A></td></tr>
{/if}
{/foreach}
{/defun}


& nbsp; tags has been screwed by the board...
Back to top
View user's profile Send private message
boots
Administrator


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

PostPosted: Sat Aug 30, 2003 12:11 am    Post subject: Reply with quote

@eis_os: I'm not sure I follow the issue with the block function. Can compiler functions now be block functions in 2.6.0?

Otherwise, the plugins are working great for me as is under 2.6.0RC1 and smarty-cvs. I've chosen to call the functions macro and macro-call instead of defun et al.

Was there ever a a consensus on the names?
Back to top
View user's profile Send private message
metheorn
Smarty Rookie


Joined: 22 Aug 2003
Posts: 14

PostPosted: Tue Oct 14, 2003 11:48 am    Post subject: Reply with quote

sweatje wrote:
I just recently implemented a script that renders a hierarchy. I was able to construct a single array to send to Smarty to accomplish the rendering.

The structure looked like this:
[php:1:322f031776]<?php
$a = array(
'1' => array('desc' => 'key 1 value', 'children' => array('2', '4')),
'2' => array('desc' => 'key 2 value', 'children' => array(),
//...and so on
);
?>[/php:1:322f031776]

Then in the template, I would pass the root node key and the array, I would render the recusive template passing the root node key as a variable, and the the recursive template would loop over the children array and call the template with the appropriate keys.

HTH

[edit:] incidentally, I have a static copy of what I was doing here. Kind of some cool js based navigation if you want to play a little Very Happy


Where can i found your script and template with this type of array.

Thanks
Back to top
View user's profile Send private message
stalker
Smarty Rookie


Joined: 28 Aug 2003
Posts: 15

PostPosted: Wed Jan 28, 2004 1:26 pm    Post subject: Reply with quote

Please guys help me out with this recursion thing...

I have read through the sticky topic multiple times, but somehow the examples don't work for me.

what I did so far is:

I made a new file called compiler.defun.php in the plugins directory.

Then i filled that file with following code:

Code:
<?php
function smarty_compiler_defun($tag_args, &$smarty) {
    $_attrs = $smarty->_parse_attrs($tag_args);
    $smarty->_tag_stack[] = array('defun', $_attrs, $tag_args);
    if (!isset($_attrs['name'])) $smary->syntax_error("defun: missing name parameter");

    $_func_name = $smarty->_dequote($_attrs['name']);
    $_func = 'smarty_fun_'.$_func_name;
    return "if (!function_exists('$_func')) { function $_func(&\$this, \$params) { \$_fun_tpl_vars = \$this->_tpl_vars; \$this->assign(\$params); ";

}
   

function smarty_compiler_defun_close($tag_args, &$smarty) {
    list($_name, $_attrs, $_open_tag_args) = array_pop($smarty->_tag_stack);
    if ($_name!='defun') $smarty->_syntax_error("unexpected {/defun}");
    return " \$this->_tpl_vars = \$_fun_tpl_vars; }} ".smarty_compiler_fun($_open_tag_args, $smarty);
}


function smarty_compiler_fun($tag_args, &$smarty) {
    $_attrs = $smarty->_parse_attrs($tag_args);

    if (!isset($_attrs['name'])) $smarty->_syntax_error("fun: missing name parameter");
    $_func_name = $smarty->_dequote($_attrs['name']);
    $_func = 'smarty_fun_'.$_func_name;
    $_params = 'array(';
    $_sep = '';
    unset($_attrs['name']);
    foreach ($_attrs as $_key=>$_value) {
        $_params .= "$_sep'$_key'=>$_value";
        $_sep = ',';
    }
    $_params .= ')';
    return "$_func(\$this, $_params); ";

}


$this->register_compiler_function('/defun', 'smarty_compiler_defun_close');
$this->register_compiler_function('fun', 'smarty_compiler_fun');

?>


In my PHP script i made an array and assigned it to a template var:

Code:

$tpl->assign("tree",array("element"=>array(array("name"    => "test1",
                                                       "element" => array(array("name"  => "test1.1"),
                                                                          array("name"  => "test1.2",
                                                                                "element" => array(array("name"  => "test1.2.1"),
                                                                                                   array("name"  => "test1.2.2"))))))));


In my template i added this:

Code:

<ul>
<%defun name="testrecursion" list=$tree%>
<%foreach from=$list item=element%>
<li><%$element.name%></li>
   <%if $element.element%>
   <ul><%fun name="testrecursion" list=$element.element%></ul>
   <%/if%>
<%/foreach%>
<%/defun%>
</ul>


In the debug console i can see the template var has all the data in it, but the template renders an empty <ul></ul>

WHAT am i missing.. I am really thankful for any help.

note: I use other delimiters, but that shouldn't be a problem, right?
Back to top
View user's profile Send private message
messju
Administrator


Joined: 16 Apr 2003
Posts: 3336
Location: Oldenburg, Germany

PostPosted: Wed Jan 28, 2004 1:50 pm    Post subject: Reply with quote

i think you want to pass:
<%defun name="testrecursion" list=$tree.element%>
instead of:
<%defun name="testrecursion" list=$tree%>
Back to top
View user's profile Send private message Send e-mail Visit poster's website
stalker
Smarty Rookie


Joined: 28 Aug 2003
Posts: 15

PostPosted: Wed Jan 28, 2004 1:58 pm    Post subject: Reply with quote

That actually worked...
I was so stuck in finding the mistake in the plugin or the rest of my code that I didnt check the template itself Embarassed

Thanks for the quick answer messju.

At least I summed it up again for any new people looking for how to do it Very Happy
Back to top
View user's profile Send private message
Doublehead
Smarty n00b


Joined: 29 Jan 2004
Posts: 2

PostPosted: Thu Jan 29, 2004 5:25 pm    Post subject: Reply with quote

I'm trying to do the same thing as stalker is doing, but with no success.
I'm using Smarty 2.6.1, does that matter?

Here's the compiler.defun.php file:
Code:

<?php
function smarty_compiler_defun($tag_args, &$smarty) {
    $_attrs = $smarty->_parse_attrs($tag_args);
    $smarty->_tag_stack[] = array('defun', $_attrs, $tag_args);
    if (!isset($_attrs['name'])) $smary->syntax_error("defun: missing name parameter");

    $_func_name = $smarty->_dequote($_attrs['name']);
    $_func = 'smarty_fun_'.$_func_name;
    return "if (!function_exists('$_func')) { function $_func(&\$this, \$params) { \$_fun_tpl_vars = \$this->_tpl_vars; \$this->assign(\$params); ";

}
   

function smarty_compiler_defun_close($tag_args, &$smarty) {
    list($_name, $_attrs, $_open_tag_args) = array_pop($smarty->_tag_stack);
    if ($_name!='defun') $smarty->_syntax_error("unexpected {/defun}");
    return " \$this->_tpl_vars = \$_fun_tpl_vars; }} ".smarty_compiler_fun($_open_tag_args, $smarty);
}


function smarty_compiler_fun($tag_args, &$smarty) {
    $_attrs = $smarty->_parse_attrs($tag_args);

    if (!isset($_attrs['name'])) $smarty->_syntax_error("fun: missing name parameter");
    $_func_name = $smarty->_dequote($_attrs['name']);
    $_func = 'smarty_fun_'.$_func_name;
    $_params = 'array(';
    $_sep = '';
    unset($_attrs['name']);
    foreach ($_attrs as $_key=>$_value) {
        $_params .= "$_sep'$_key'=>$_value";
        $_sep = ',';
    }
    $_params .= ')';
    return "$_func(\$this, $_params); ";

}


$this->register_compiler_function('/defun', 'smarty_compiler_defun_close');
$this->register_compiler_function('fun', 'smarty_compiler_fun');
?>


I'm using the same array as stalker:
Code:

$smarty->assign("tree",array("element"=>array(array("name"    => "test1",
                                                       "element" => array(array("name"  => "test1.1"),
                                                                          array("name"  => "test1.2",
                                                                                "element" => array(array("name"  => "test1.2.1"),
                                                                                                   array("name"  => "test1.2.2"))))))));


But when it comes to the template, why do you use <% %> in the template, and not { }?
Anyway, using <% %> doesn't work for me. So I changed it to { }.
The template is like this:
Code:

{* Smarty *}
<ul>
{defun name="testrecursion" list=$tree}
{foreach from=$list item=element}
<li>{$element.name}</li>
   {if $element.element}
   <ul>{fun name="testrecursion" list=$element.element}</ul>
   {/if}
{/foreach}
{/defun}
</ul>


When I execute the script, I get this error:
Code:

Fatal error: Using $this when not in object context in F:\htdocs\smarty\templates_c\%%183\%%1836865061\test.tpl.php on line 4


And here's the compiled template, so you can actually see the error:
Code:

<?php /* Smarty version 2.6.1, created on 2004-01-29 17:13:11
         compiled from test.tpl */ ?>
<ul>
<?php if (!function_exists('smarty_fun_testrecursion')) { function smarty_fun_testrecursion(&$this, $params) { $_fun_tpl_vars = $this->_tpl_vars; $this->assign($params);  ?>
<?php if (count($_from = (array)$this->_tpl_vars['list'])):
    foreach ($_from as $this->_tpl_vars['element']):
?>
<li><?php echo $this->_tpl_vars['element']['name']; ?>
</li>
   <?php if ($this->_tpl_vars['element']['element']): ?>
   <ul><?php smarty_fun_testrecursion($this, array('list'=>$this->_tpl_vars['element']['element']));  ?></ul>
   <?php endif; ?>
<?php endforeach; unset($_from); endif; ?>
<?php  $this->_tpl_vars = $_fun_tpl_vars; }} smarty_fun_testrecursion($this, array('list'=>$this->_tpl_vars['tree']));  ?>
</ul>


Hope you can solve this, I'm not good enough in PHP/Smarty to solve it myself!
Back to top
View user's profile Send private message Visit poster's website
messju
Administrator


Joined: 16 Apr 2003
Posts: 3336
Location: Oldenburg, Germany

PostPosted: Thu Jan 29, 2004 5:49 pm    Post subject: Reply with quote

Doublehead: it seems you are using php5. compiler.defun.php doesn't work with php5.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Smarty Forum Index -> Tips and Tricks All times are GMT
Goto page Previous  1, 2, 3, 4 ... 9, 10, 11  Next
Page 3 of 11

 
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