Рекурсивное заполнение шаблона из дерева

Yurik

/dev/null
Рекурсивное заполнение шаблона из дерева

Есть простейший шаблон (для пример php-templates)

<tmpl:list>
<ul>

<tmpl:item><li>{title}</li></tmpl:item>

{subtree}
</ul>
</tmpl:list>


Есть простейшее дерево в БД
id | ref | title

Как вывести (оптимально) всё дерево в шаблон, т.е. чтобы в /list/subtree вставился /list но уже дочерних элементов и т.д. рекурсивно

-~{}~ 27.07.04 14:49:

PHP:
$sql="SELECT * FROM table ORDER BY ref, id";
$result=mysql_query($sql);
while ($row=mysql_fetch_assoc($result)){
 $tree[$row['ref']][$row['id']]=$row['title'];
}
И как теперь по этому $tree[ref][id] пройтись и пихнуть в шаблон?

-~{}~ 27.07.04 15:37:

Короче по ходу получается что все современные движки (php-templates, Smarty) не поддерживают рекурсивного заполнения, т.к. смена/итерация контекста безвозвратна.

Надо для каждого вложенного узла делать tmpl_load/open и плодить instance шаблона а это изврат редкий.
 

tony2001

TeaM PHPClub
сделать 1 шаблон для "ветки" и в цикле рекурсивно делать {include}'ить его.
 

iliah

Новичок
я извиняюсь. если туплю, но разве запрос "SELECT * FROM table ORDER BY ref, id" дает корректное представление дерева, если id - это id, а ref - предок

я выводил подобное дерево примерно так
PHP:
$GLOBALS['tree'] = '';

function tree($table, $parent) {
$result = mysql_query("SELECT id, title FROM $table WHERE parent = $parent");

//up
$GLOBALS['tree'] .= '<ul>';

while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) { 
        $GLOBALS['tree'] .= '<li>'.$row['title'].'</li>';
		tree($table, $row['id']);
        }

//down
$GLOBALS['tree'] .= '</ul>';
return;
}

$tree = tree('_pub', 0);
в шаблоне останется вывести только полученную строку,
плохо то, что представление мешается с данными, можно в таком случае не конкатенировать строку, а формировать массив, а вместо ul'ов размещать некие флаги начало и конца ветки, аналогично с представлением "<li>" -
и тогда foreach проходить по массиву и заменять флаги

если совсем криво, поправьте, с шаблонизаторами еще не работал, просто задачка показалась интересной
 

Yurik

/dev/null
iliah: суть не так в проходе по дереву а именно в заполнении шаблона
У тебя никакого шаблона нету, ты просто в PHP-коде генерируешь html разметку, это делается очень просто тем самым тупым аппендом строковой переменной $GLOBALS['tree']

tony2001 видать с php-templates не судьба...
 

iliah

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


а про "тупой аппенд" - так я это и указал
 

Yurik

/dev/null
iliah: однозначно рекурсия в бизнес логике. Но у тебя и представление - там же, а я хочу реализовать VIEW через шаблоны. Говорят что или xml-xslt или Смарти {include}
 

iliah

Новичок
гугль на "recursion in template" как раз выдает в основном примеры на xml-xslt, жаль я там ничего не понял
 

Yurik

/dev/null
<tmpl:item>
<tmpl:inside><ul>{empty}</tmpl:inside>
<li>{title}</li>
<tmpl:eek:utside></ul>{empty}</tmpl:eek:utside>
</tmpl:item>

PHP:
 $sql="SELECT * FROM table ORDER BY ref, id";
 $result=mysql_query($sql); 
while ($row=mysql_fetch_assoc($result)){ 
 $tree[$row['ref']][$row['id']]=$row['title']; 
}

function showNode($ref=0){
 foreach ($tree[$ref] as $key=>$value){
 tmpl_iterate($t, 'item');
 tmpl_set('title', $value);
  if (isset($tree[$key]) {
   tmpl_iterate($t, 'inside');
   tmpl_set($t, 'empty', '');
   showNode($key);
   tmpl_iterate($t, 'outside');
   tmpl_set($t, 'empty', '');
  }
 }
}

$t=tmpl_load($string);
showNode();
 

su1d

Старожил PHPClubа
когда в контексте нет ни одного тэга, ты не сможешь в нём сделать более одной итерации.
поэтому нужно будет его сделать где-то так:

PHP:
<tmpl:inside><ul>{empty}</tmpl:inside>
и в коде:

PHP:
tmpl_set('inside', array(array('empty' => '')) );
showNode($current);
tmpl_set('outside', array(array('empty' => '')) );
 
Сверху