Каков наилучший способ справиться с рекурсией в Smarty? - PullRequest
7 голосов
/ 13 января 2009

Я нашел пару способов обработки рекурсии в Smarty, в основном основанных на включении шаблонов в себя, что выглядит как нелепая трата ресурсов. Я нашел одно решение от Messju в Smarty, которое, казалось бы, было правильным - но оно не поддерживается и не работает в последней версии 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-заполнителей вне шаблона.

Я хочу, чтобы smarty печатал это как вложенные списки:

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

Я начинаю понимать, что это может быть очень индивидуальной проблемой, поэтому я полагаю, что просто напишу умный плагин, чтобы справиться с этим конкретно, хотя я бы предпочел всеобъемлющее решение

Есть ли способ?

Ответы [ 4 ]

17 голосов
/ 21 октября 2012

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

Дополнительную информацию можно найти в документах .

Примечание: если что-то является сложным или рекурсивным, это не значит, что оно не может быть внутри шаблона. Ради бога, HTML ul-li структура естественно рекурсивна, и, скрывая ее или перемещая в другое место (только потому, что она слишком сложна для шаблона), вы вносите дополнительную сложность в приложение.

6 голосов
/ 16 марта 2009

«Чтобы понять рекурсию, вы должны сначала понять рекурсию ...»

Шучу. Это должно делать то, что вы хотите:

<?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:

Создание пользовательских функций Smarty

Помните о зависимости этого примера от вашей базовой структуры данных. Кроме того, имейте в виду, что необычно длинный или глубоко вложенный набор данных может быть очень медленным. Управляйте своей сложностью, сохраняйте вещи хорошо документированными, и у вас все должно быть хорошо. Удачи!

0 голосов
/ 16 марта 2009

Возможно, вы захотите создать собственную функцию / модификатор / плагин для smarty. Передайте массив пользовательской функции вместе с определением шаблона, который должна использовать функция. Если это так просто, только для вставки текста в определенное место, загрузите шаблон внутри функции и в PHP работайте с шаблоном с помощью регулярных выражений / str_replace / ...

Или сделать это напрямую в PHP без использования шаблонов smarty, потому что все, что вам нужно, это теги h1, ul, li и p, а для изменения макета используйте CSS.

Или, если вас беспокоит открытие и закрытие файлов в Smarty, оцените количество уровней в 90% случаев и создайте шаблон, который охватит эти 90%. В остальном используйте рекурсию, включив сам шаблон ...

0 голосов
/ 13 января 2009

Лучший способ не сделать это.

Smarty должен быть простым. Это не звучит.

...