I found a couple of ways to handle recursion in Smarty, mostly based on including templates into themselves, which seems like ridiculous waste of resources. I found one solu
"In order to understand recursion, you must first understand recursion..."
Just kidding. This should do what you want:
<?php
/*
* Smarty plugin
* ————————————————————-
* File: function.recurse_array.php
* Type: function
* Name: recurse_array
* Purpose: prints out elements of an array recursively
* ————————————————————-
*/
function smarty_function_recurse_array($params, &$smarty)
{
if (is_array($params['array']) && count($params['array']) > 0) {
$markup = '';
$markup .= '<ul>';
foreach ($params['array'] as $element) {
$markup .= '<li>';
$markup .= '<h1>' . $element['headline'] . '</h1>';
$markup .= '<p>' . $element['body'] . '</p>';
if (isset($element['children'])) {
$markup .= smarty_function_recurse_array(array('array' => $element['children']), $smarty);
}
$markup .= '</li>';
}
$markup.= '</ul>';
return $markup;
} else {
return 'not array';
}
}
Place the file into your smarty/plugins folder. Assign your array to Smarty then call it in your template like so:
{recurse_array array=$data}
Here's nice tutorial for making custom Smarty functions:
Creating Custom Smarty Functions
Be aware of the dependency that this example has on your underlying data structure. Also, keep in mind that an unusually long or deeply nested set of data could be really slow. Manage your complexity, keep things well documented, and you should be fine. Good luck!
The best way is not to do it.
Smarty is supposed to be simple. This deesn't sound it.
With Smarty 3, this can be done using {function}. The following code will produce the required ouput.
{function name=printList}
<ul>
{foreach $items as $item}
<li>
<h1>{$item['headline']}</h1>
<p>{$item['body']}</p>
{if $item['children']}
{call name=printList items=$item['children']}
{/if}
</li>
{/foreach}
</ul>
{/function}
{call name=printList items=$comments}
More information can be found at the docs.
Side note: Just because something is complex or recursive it doesn't mean that it can't be inside a template. For God's sake the HTML ul-li structure is naturally recursive and by hiding it away or moving it somewhere else (just because it is too complex for a template) you are introducing an extra complexity into the application.
You might want to consider creating custom function/modifier/plugin for smarty. Pass the array to the custom function along with defining what is the template the function should use. If it is that simple, only to insert a text to certain place, load the template within function and in PHP work with the template using regexes/str_replace/...
Or do it directly in PHP without using smarty templates, because all you need is h1, ul, li and p tags and to change the layout use CSS.
Or if your concern is the overhead with opening and closing files in Smarty, estimate what is the amount of levels in 90% of cases and create template which will cover those 90%. For the rest use recursion by including the template itself...