Список терминов определённого словаря (с иерархией) + количество документов

<?php
$vid
= 3// Номер словаря
$pole = array();
$items = array();
$terms = taxonomy_get_tree($vid);
foreach (
$terms as $term ) {
 
$count = db_result(db_query("SELECT COUNT(nid) FROM {term_node} WHERE tid = %d", $term->tid));
 
$pole[]=Array (l($term->name, "taxonomy/term/$term->tid") . " ($count)", $term->depth, $count, $term->tid)  ;
}
 
$depth =-1;
  foreach (
$pole as $list) {
    if (
$list[1] > $depth) echo "\n<ul>";
    if (
$list[1] < $depth) echo "\n</li>\n</ul>\n</li>";
    if (
$list[1] == $depth) echo "</li>";
   
$poc++;
    echo
"\n<li>$list[0]";
if (
$list[2]>0) {
      echo
"\n<ul>";
     
$result = db_query("SELECT * FROM {term_node} WHERE tid=$list[3]");
      while(
$zaznam = db_fetch_array($result)) {
       
$node = db_result(db_query("SELECT title FROM {node} WHERE nid=$zaznam[nid]"));
       
$node_link = l($node, "node/$zaznam[nid]");
        echo
"\n<li>$node_link</li>";
      }
      echo
"\n</ul>";
  }
   
$depth=$list[1];
}
echo
"</li>\n</ul>";
?>

Метки:

Комментарии

Sergey1917's picture
На сайте
2 года 41 нед

Уважаемый setegnom! А в этом сниппете как можно вывести документы термина по алфавиту.

По аналогии с другим, где вы мне подсказали, не получается. И сами термины тоже желательно по алфавиту расположить.

Sergey1917's picture
На сайте
2 года 41 нед

К большому сожалению, никто ответить не может.

Sergey1917's picture
На сайте
2 года 41 нед

Уважаемый setegnom! кроме вас никто ответить не может. Может поможите. Уж больно интересный сниппет. С ним можно очень многое делать на сайте.

Sergey1917's picture
На сайте
2 года 41 нед

Добрые люди мне подсказали как это сделать, может еще кому-нибудь пригодится.

Сортировка терминов по алфавиту.
После строки :

$terms = taxonomy_get_tree($vid);

(5-я строка в вашем исходном файле), добавляем строку:

usort($terms,create_function('$a,$b','return strcasecmp ($a->name,$b->name);'));

Для сортировки списка документов в алфавитном порядке, заменить:

  $result = db_query("SELECT * FROM {term_node} WHERE tid=$list[3]");
      while($zaznam = db_fetch_array($result)) {
        $node = db_result(db_query("SELECT title FROM {node} WHERE nid=$zaznam[nid]"));
        $node_link = l($node, "node/$zaznam[nid]");
        echo "\n<li>$node_link</li>";
      }

на

$result = db_query("SELECT n.title, n.nid FROM {term_node} t INNER JOIN {node} n ON t.nid=n.nid WHERE t.tid=$list[3] ORDER BY n.title ASC");
      while($zaznam = db_fetch_array($result)) {
        $node_link = l($zaznam[title], "node/$zaznam[nid]");
        echo "\n<li>$node_link</li>";
      } 

Заодно избавляемся от запросов в цикле while, должно работать пошустрее.

Влад Савицкий's picture

Попробовал этот сниппет на словаре с большой и разной глубиной вложенности... Он не работает.
Он будет работать отлично в том случае, если разница между глубинами элементов не больше 1.
В моём случае после глубины 4 могла идти глубина 2 или 0.
И изменил скрипт для своих нужд - поэтому в нём нет вывода документов, которые принадлежат термину. При желании это можно добавить...
Вот код:

<?php
$vid
= 13// Номер словаря
$pole = array();
$items = array();
$terms = taxonomy_get_tree($vid);

foreach (
$terms as $term ) {
 
$count = db_result(db_query("SELECT COUNT(nid) FROM {term_node} WHERE tid = %d", $term->tid));
 
$pole[]=Array (l($term->name, "taxonomy/term/$term->tid") . (($count) ? " (".$count.")": ""). "[".$term->depth."]", $term->depth, $count, $term->tid)  ;
}
$depth =-1;
foreach (
$pole as $list) {
 
//$depth- глубина предыдущего уровня
  //$list[1] - глубина текущего элемента
 
while ($list[1] != $depth) {
    if (
$list[1] > $depth) {
     
$depth++;
      echo
"\n<ul>";
    }
    if (
$list[1] < $depth) {
     
$depth--;
      echo
"\n</li>\n</ul>\n</li>";
    }
  }
  if (
$list[1] == $depth) echo "</li>";
  echo
"\n<li>$list[0]";
 
$depth=$list[1];
}
  echo
"</li>\n</ul>";
?>

Влад Савицкий's picture

Предыдущий код был с ошибкой.
1. Забыл расскомментировать код, который закрывает все открытые теги в конце.
2. Оставил вывод отладочной информации

<?php
$vid
= 13// Номер словаря
$pole = array();
$items = array();
$terms = taxonomy_get_tree($vid);
//var_dump($terms);

foreach ( $terms as $term ) {
 
$count = db_result(db_query("SELECT COUNT(nid) FROM {term_node} WHERE tid = %d", $term->tid));
 
$pole[]=Array ("[".$term->depth."]" .l($term->name, "taxonomy/term/$term->tid") . (($count) ? " (".$count.")": ""), $term->depth, $count, $term->tid)  ;
}
$depth =-1;
foreach (
$pole as $list) {
 
//$depth- глубина предыдущего уровня
  //$list[1] - глубина текущего элемента
 
if ($list[1] == $depth) {
    echo
"</li>";
   
next;
  }
  while (
$list[1] != $depth) {
    if (
$list[1] > $depth) {
     
$depth++;
      echo
"\n<ul>";
     
next;
    }
    if (
$list[1] < $depth) {
     
$depth--;
      echo
"\n</li>\n</ul>";
    }
  }

  echo

"\n<li>$list[0]";
 
$depth=$list[1];
}

//Закрываем все открытые теги до нулевого уровня:
$depth=0;
while (
$list[1] != $depth) {
  if (
$list[1] > $depth) {
   
$depth++;
    echo
"</li>\n</ul>";
  }
}
?>
NeuZeitgeist's picture
На сайте
2 года 44 нед

Вопрос к Владу Савицкому.
Что нужно исправить в вашем коде, чтобы в списке не выводилась глубина термина. Перед каждым термином в квадратных скобках идет 1,2, и так далее. Как это убрать?
Спасибо.

Влад Савицкий's picture

Изменить

$pole[]=Array ("[".$term->depth."]" .l($term->name, "taxonomy/term/$term->tid") . (($count) ? " (".$count.")": ""), $term->depth, $count, $term->tid)  ;

на

$pole[]=Array (l($term->name, "taxonomy/term/$term->tid") . (($count) ? " (".$count.")": ""), $term->depth, $count, $term->tid)  ;

Извините, забыл убрать - торопился.

NeuZeitgeist's picture
На сайте
2 года 44 нед

Cпасибо большое, очень полезный сниппет.

NeuZeitgeist's picture
На сайте
2 года 44 нед

Сейчас этот сниппет выводит термины всех типов документов, связанных с определенным словарем. У меня к одному словарю прикреплено два типа документа. Что нужно исправить в сниппете, чтобы в каталоге выводились документы только одного типа?
Спасибо.

Николай Мурашкин's picture
На сайте
2 года 8 нед

Влад Савицкий, скажите, пожалуйста, можно ли изменить этот сниппет так, чтобы решить следующий вопрос:

Мне нужно выводить в блоке термины (категории) и подтермины (подкатегории) определённого словаря (как и выводит Ваш сниппет), но только не в виде развёрнутого списка всех категорий и подкатегорий.

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

Борис's picture

а как подсчитать количество элементов родителя... и сразу следующий вопрос как вывести родителя вместе со всеми элементами таксономии в ноде

sadmin's picture

Влад, спасибо. Очень пригодилось

waqwaq's picture

Влад Савицкий, огромное спасибо за Ваш код, то что искал!

Святослав's picture

Спасибо, Владислав!

Алексей's picture

Извиняюсь, не нашел ответ на аналогичный вопрос.
Сейчас этот сниппет выводит термины всех типов документов, связанных с определенным словарем. У меня к одному словарю прикреплено два типа документа. Что нужно исправить в сниппете, чтобы в каталоге выводились документы только одного типа?
Спасибо.

Андрей's picture

подскажите пожалуйста как изменить этот сниппет что выводились только родительские термины с подсчетом нод ?

Iphonaft's picture

убрать строчку

echo "\n<li>$node_link</li>"

Дархан's picture

Добрый день! Спасибо за сниппет!
у меня словарь получился такой структуры

термин1
-подтермин1
-нода
-нода
-нода
-подтермин2
-нода
-нода
-нода

термин2
-нода
-нода
-нода

т.е. во втором термине нет подтерминов, а сразу ноды идут.
дерево строится нормально, но где-то в конце он не выводит закрывающего

. в общем буду разбираться

Комментировать

CAPTCHA
Тест, который позволяет исключить автоматическую отправку сообщений. Эта мера направлена против спама.
Image CAPTCHA
Введите числа, которые показаны на картинке.