Каков наилучший способ обработки рекурсии в smarty?
Я нашел несколько способов обработки рекурсии в 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>
Я начинаю поймите, что это может быть очень случайная проблема, поэтому я думаю, что просто напишу плагин smarty, чтобы справиться с этим конкретно, хотя я предпочел бы иметь всестороннее решение.
есть ли способ?
4 ответов
"чтобы понять рекурсию, нужно сперва понять рекурсию..."
шучу. Это должно делать то, что вы хотите:
<?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
имейте в виду зависимость, что это пример имеет базовую структуру данных. Кроме того, имейте в виду, что необычно длинный или глубоко вложенный набор данных может быть очень медленным. Управляйте своей сложностью, держите вещи хорошо документированными, и вы должны быть в порядке. Удачи!
С помощью 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 естественно рекурсивна, и, скрывая ее или перемещая в другое место (просто потому, что она слишком сложна для шаблона), вы введение дополнительной сложности в приложение.
возможно, вы захотите создать пользовательскую функцию / модификатор / плагин для smarty. Передайте массив пользовательской функции вместе с определением шаблона, который должна использовать функция. Если это так просто, только для вставки текста в определенное место, загрузите шаблон внутри функции и в PHP работайте с шаблоном, используя regexes/str_replace/...
или сделать это непосредственно в PHP без использования шаблонов smarty, потому что все, что вам нужно, это H1, ul, li и P теги и изменить макета использовать CSS.
или если ваша забота накладные расходы с открытием и закрытием файлов в Smarty, оценить, какое количество уровней в 90% случаев и создать шаблон, который будет охватывать эти 90%. Для остальных используйте рекурсию, включив сам шаблон...