2009-01-13 88 views
7

我发现了几种方法来处理Smarty中的递归,主要基于将模板包含到自身中,这看起来像是荒谬的资源浪费。我发现了一个解决方案,通过Messju了在Smarty的,似乎是恰到好处 - 但它不支持在智者:(最新版本失败在smarty中处理递归的最佳方式是什么?

对于人们在问:我想智者打印出什么是讨论线程是由条目的阵列限定的。如果一个条目具有一个或多个答案,那些被列为到所述阵列中的条目的孩子,等等。

array(
    array(
     'id'=>0, 
     'headline'=>"My parent headline", 
     'body' =>"My parent body", 
     'children'=>array(
      array(
       'id'=>1, 
       'headline'=>"My firstChild headline", 
       'body' =>"My firstChild body", 
       'children'=>array() 
      ), 
      array(
       'id'=>2, 
       'headline'=>"My secondChild headline", 
       'body' =>"My secondChild body", 
       'children'=>array() 
      ) 
     ) 
    ), 
); 

嵌套阵列具有任意深度,每个条目都有一个任意数量的孩子,对我来说,这是我想在模板范围内做的事情,因为我认为它是纯粹的显示逻辑,我不想处理HTML或某种类型的HTML占位符以外的占位符模板。

我想智者打印此嵌套的列表:

<ul> 
    <li> 
     <h1>My parent headline</h1> 
     <p>My parent body</p> 
     <ul> 
      <li> 
       <h1>My firstChild headline</h1> 
       <p>My firstChild body</p> 
      </li> 
      <li> 
       <h1>My secondChild headline</h1> 
       <p>My secondChild body</p> 
      </li> 
     </ul> 
    </li> 
</ul> 

我开始意识到这可能是一个非常逐案的问题,所以我想我会只写一个智者插件来处理这个具体问题,尽管我宁愿有一个全面的解决方案。

有没有办法?

回答

6

其余使用递归“为了了解递归,你必须先了解递归......”

只是开个玩笑。这应该做你想做的:

<?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'; 
} 
} 

把文件放到你的smarty/plugins文件夹中。将您的数组的Smarty然后调用它在你的模板,像这样:

{recurse_array array=$data} 

这里有很好的教程制作自定义Smarty的功能:

Creating Custom Smarty Functions

注意,这个例子对依赖你基础数据结构。另外,请记住,一个不同寻常的长或深度嵌套组数据可能是非常缓慢的。管理你的复杂性,把事情记录好,你应该没问题。祝你好运!

-3

最好的方法是不要这样做。

Smarty应该很简单。这听起来没有声音。

+3

想想这样,应用程序需要显示一个任意嵌套的东西列表。那里有复杂性。你需要管理复杂性。在模板中放置基本显示逻辑(循环遍历数组并放出标记)是有意义的。只是递归不会使它变得邪恶。 – GloryFish 2009-03-16 20:58:46

+0

不够公平,但与使用一次性函数进行递归相比,聪明的解决方案会变得复杂。 – 2009-03-17 04:17:40

0

您可能需要考虑为smarty创建自定义函数/修饰符/插件。 将数组传递给自定义函数,并定义函数应该使用的模板。如果是这样简单,只需要将文本插入到某个地方,在模板中加载模板,并使用正则表达式/ str_replace/...

或者直接在PHP中使用不使用smarty模板,因为所有你需要的是h1,ul,li和p标签,并且改变布局使用CSS。

或者,如果你关心的是在Smarty的打开和关闭文件的开销,估计是什么的情况下的90%的水平的量,并创建模板,也将覆盖这些90%。通过包括模板本身...

14

对于Smarty 3,可以使用{function}来完成。以下代码将生成所需的输出。

{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} 

更多信息可在docs找到。

备注:只是因为某些东西是复杂的或递归的,并不意味着它不在模板内。为了上帝的缘故,HTML ul-li结构是自然递归的,通过隐藏它或将它移动到其他地方(仅仅因为它对于模板来说太复杂),会给应用程序带来额外的复杂性。

相关问题