вывод дерева в smarty

DinDim

Новичок
вывод дерева в smarty

Здравствуйте. Храню дерево в базе по принципу http://phpclub.ru/detail/article/db_tree . Строю запрос для вывода всей структуры дерева

$query="SELECT * FROM ".$table." ORDER BY cleft ASC";
$result=$dbh->query($query);

в выборке массив

Первый уровень - название1

подчиненный элемент 1- второй уровень
подчиненный элемент 2- второй уровень

Первый уровень - название2

подчиненный элемент 1- второй уровень
подчиненный элемент 2- второй уровень

скажите как можно такое выести в smarty

<a hre="#">Первый уровень - название1</a>
<div>

<a>подчиненный элемент 1- второй уровень</a>
<a>подчиненный элемент 2- второй уровень</a>

</div>

<a hre="#">Первый уровень - название2</a>
<div>

<a>подчиненный элемент 1- второй уровень</a>
<a>подчиненный элемент 2- второй уровень</a>

</div>

чтобы элементы все элементы подчиненного уровня, какого-либо узла были в одной группе <div>...</div>
 

Alexandre

PHPПенсионер
обычно:
поочередно выбираешь,
сперва <a hre="#">Первый уровень - название1</a>
<div>
Потом строишь массив для вывода:
<a>подчиненный элемент 1- второй уровень</a>
<a>подчиненный элемент 2- второй уровень</a>
Потом закрываешь </div>

потом снова выбираешь:
<a hre="#">Первый уровень - название2</a>

используй циклы {FOREACH /} и т.д....

если сформулировать:
как это вывести, используя один запрос, то тут два ответа:
если хочется просто, то - никак...
если помучиться, то - выводишь все одним запросом отсортированным по num,
потом анализируешь данные - в какой логический уровень они входят и соответственно пихаишь их в иерархический массив на тот уровень (в ту ветку), которому они должны принадлежать соответственно логике дерева.
 

jonjonson

Охренеть
DinDim, если дерево основано на вложенных множествах, то проще ещё дополнительно хранить уровень вложенности.

Тогда выбирается одним запросом всё дерево в массив отсортированное по левому весу.
Проходишь по всему списку в подряд. Если левел меньше предыдущего элемента, то закрываешь див. Если у элемента есть потомки (право минус лево больше 1), то открываешь див и выводишь потомка с той же проверкой.
 

HraKK

Мудак
Команда форума
jonjonson
Это работает только если Нестед сет. А если классика надо выбирать Рекурсией которая даст тот же результат.
 

Alexandre

PHPПенсионер
А если классика надо выбирать Рекурсией которая даст тот же результат.
HraKK если покопаться на форуме, то один спец предложил решение этой задачки без рекурсии и главное - работает.
 

HraKK

Мудак
Команда форума
Alexandre
Зачем копаться? кажется в стаьях это есть, но имхо - не нужно.
 

DinDim

Новичок
jonjonson
Спасибо, дельное предложение, я так и делаю - выбираю все дерево, отсортированное по левому весу. Уровень вложенности есно хранится в базе. Не понятно только как построить логику для открытия и закрытия div
 

HraKK

Мудак
Команда форума
Проходишь по всему списку в подряд. Если левел меньше предыдущего элемента, то закрываешь див. Если у элемента есть потомки (право минус лево больше 1), то открываешь див и выводишь потомка с той же проверкой.
 

DinDim

Новичок
Спасибо, вопрос закрыт

-~{}~ 14.04.08 01:32:

Извините, но поспешил тему закрыть, насчет

>> Проходишь по всему списку в подряд. Если левел меньше предыдущего элемента, то закрываешь див. Если у элемента есть потомки (право минус лево больше 1), то открываешь див и выводишь потомка с той же проверкой. <<

Нашел такие грабли, если у элемента есть потомки (право минус лево...) выключить их в панели управления нельзя т.е. если логически есть выключенные элементы, они все равно считаются живыми потомками, и вся логика в цикле летит напрочь

Вот последнее что на ум пришло, но в связи с предидущим уже не актуально

<div id="menutop">
<ul class="menulist" id="listMenuRoot">

{foreach key=key item=i from=$punktmenu name=cu}

{assign var=level value=$key-1}

{if $punktmenu[$key][clevel] < $punktmenu[$level][clevel] }
</ul></li>
{/if}

<li><a href="index-7.html">{$punktmenu[$key][name]|htmlspecialchars|stripslashes}</a>


{if ($punktmenu[$key]
- $punktmenu[$key]
) > 1}
<ul class="menulist1">
{else}
</li>
{/if}



{if ($smarty.foreach.cu.last) and ($punktmenu[$key][clevel] > 1)}
</ul></li>
{/if}


{/foreach}

</ul>
</div>

Вообще прихожу к мысли о необходимости хранения в базе родителя записи, без нее очень тяжело работать с вложенным набором​
 
Сверху