::: PHP.com.ua - учимся вместе. ::: ::: PHP.com.ua - учимся вместе. :::



 
   - Разработка CRM для туристического бизнес...
  - тестування по прив"язці до часу...
  - СРОЧНО! Требуется талантливый PHP програ...
  - Оплачу FLASH-сайт под ключ.
  - выборка одним запросом нескольких похожи...
  - функции верификации строк.
  - Помогите вытянуть скрипт отправки почты ...


Главная
Новости
Статьи
Шпаргалки
Файлы
О проекте
Форум
Футболки


FREEhost.com.ua - купил хостинг 10 у.е. на Begun в подарок.

iName.com.ua - регистрация доменных имен и хороший хостинг.

Библиотека программиста - нужный вам исходник или документация по необходимому для вас языку программирования.

Designclub - Клуб дизайнеров Украины.

Регистрация доменов
Хостинг

 HowtoForge.ORG.UA - Это первый Украинский ресурс развития open source программного обеспечения


Путь: Шпаргалки

Шпаргалки

Автор: - Yurik
Дата публикации - 02.07.2005
Просмотров: - 7675

Отрисовка дерева (tree) с помощью Smarty


Можно красиво сделать используя рекурсивный шаблон, например если есть массив:
[php]
<?php
$foo 
= array(
  
'1' => array(
    
'1.1' => null,
    
'1.2' => null
  
),
  
'2' => null,
  
'3' => array(
    
'3.1' => array(
      
'3.1.1' => null
    
),
    
'3.2' => null
  
)
);
?>[

/php]
Шаблон tree.tpl будет выглядеть так:
[php]
{if $tree}
<ul>
{foreach from=$tree key="name" item="subtree"}
  <li>
    {$name} {include file="tree.tpl" tree=$subtree}
  </li>
{/foreach}
</ul>
{/if}[

/php]
И включайте шаблон в главный master.tpl:
[php]
<h1>Моё дерево</h1>
{include file="tree.tpl" tree=$foo}
[

/php]Если у вас исходный формат массива $foo другой, то можно написать плагин который будет преобразовывать в формат указанный выше

[p]Формат массива[/p]
Как вы могли заметить формат массива который нужно передавать не совсем естественный для деревьев. Это вложенный массив, где названия являются индексами, а значениями - массивы дочерних элементов или [b]null[/b] если таковых нет.
Получаемый из релиционной БД формат дерева - обычно многомерный массив. Конвертация его в нужный формат задача не тривиальная. Допустим есть массив $a[$id]=Array($parentID, $value) и его надо преобразовать
[php]
<?php
$arr
[1]=Array(0'1'); 
$arr[2]=Array(1'1.1'); 
$arr[3]=Array(1'1.2'); 
$arr[4]=Array(0'2'); 
$arr[5]=Array(0'3'); 
$arr[6]=Array(5'3.1'); 
$arr[7]=Array(6'3.1.1'); 
$arr[8]=Array(5'3.2'); 

// в такой вот формат

$foo = array(
  
'1' => array(
    
'1.1' => null,
    
'1.2' => null
  
),
  
'2' => null,
  
'3' => array(
    
'3.1' => array(
      
'3.1.1' => null
    
),
    
'3.2' => null
  
)
);
?>
[

/php]

Поскольку рисование дерева мы положили на шаблоны Smarty, то логично и необходимые преобразования реализовать как плагин, который можно вызывать из любого места.
Особая благодарность [url=http://phpclub.ru/talk/member.php?s=&action=getinfo&userid=8]su1d[/url] за помощь в создании алгоритма преобразования

[php]
<?php
/*
 * Smarty plugin
 * -------------------------------------------------------------
 * File:     function.treeconvert.php
 * Type:     function
 * Name:     treeconvert
 * Purpose:  Converts array from dimensional to nested format
 * -------------------------------------------------------------
 */

function arrSorter($a$b) { 
    return 
$a[0] < $b[0] ? -: ($a[0] > $b[0] ? strcmp($a[1], $b[1])); 


function 
smarty_function_treeconvert($params, &$smarty) {
    
$_arr=$smarty->_tpl_vars[$params['var']];

    
uasort($_arr"arrSorter"); 
    
$_res = array(); 
    
$_parents = array(&$_res); 
    
$_values=Array();
    foreach(
$_arr as $_id => $_pid) { 
     
$_parents[$_pid[0]][$_id] = null;
     
$_parents[$_id] =& $_parents[$_pid[0]][$_id]; 
     
$_values[$_id]=$_pid[1];
    } 
    unset(
$_parents);
    unset(
$_arr);
    
$_arr['tree']=$_res;
    
$_arr['value']=$_values;
    unset (
$_res);
    
$smarty->_tpl_vars[$params['var']]=$_arr;
    return; 
 }

?>
[

/php]

И сохранить его в папку $smarty->plugins_dir или в основную plugins папку дистрибутива Smarty.
Шаблоны для вызова этого кода несколько видоизменились:

[b]master.tpl[/b]
[php]
<h1>Моё дерево</h1>

{* передаем в плагин название переменной
 которую мы присволили через $s->assign *}
{treeconvert var="foo"}


{include file="tree.tpl" tree=$foo.tree}
[

/php]

[b]tree.tpl[/b]
[php]
{if $tree}
<ul>
{foreach from=$tree key="id" item="subtree"}
  <li>
    {$foo.value.$id} {include file="tree.tpl" tree=$subtree}
  </li>
{/foreach}
</ul>
{/if}
[

/php]


[p]TODO[/p]
Как вы уже заметили, вторая реализация шаблона пока кривовата. Получить сразу массив где в качестве индекса были значения узлов нам не удалось. Поэтому мы передали массив с двумя индексами.
[php]
<?php
    $_arr
['tree']=$_res// тут id
    
$_arr['value']=$_values// тут привязка ID -> Value
?>
[

/php]

Поскольку к такому массиву напрямую неприменим {foreach}, мы вынуждены в рекурсивном шаблоне обращаться к {$foo.value.$id} чтобы получить знаение соответствующего ID, что есть неправильно.
Так как мы должны указывать имя переменной во вложенном шаблоне такое же как в [b]master.tpl[/b], что делает шаблон не универсальным и не портабельным.




Обсудить в ФОРУМе - комментариев ()


Путь: Шпаргалки

Если вы заметили орфографическую, стилистическую или другую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Контакты Design by webFaction Ukrainian PHP Group 2004-2005