[РЕШЕНО] Красивый вывод терминов таксономии для отдельно взятого словаря

Главные вкладки

Аватар пользователя Nodachi Nodachi 31 мая 2009 в 16:54

Всем доброго времени суток!
Есть у меня на сайте страничка, которая выводит все термины определенного словаря. Для этих целей используется данный код:

<?php
$vid 
1;  // Номер словаря
$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 (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>";
  }
}
?>

Но так как мой словарь очень велик, то терминов на странице очень много... Не подскажете, как мне изменить данный код чтобы термины, у которых нет нод, не выводились?

Заранее спасибо за ответы!

Комментарии

Аватар пользователя sas@drupal.org sas@drupal.org 31 мая 2009 в 18:49

Текст запрос для терминов у которых есть ноды:

<?php
...
$sql 'SELECT DISTINCT(tn.tid) from {tern_node} tn 
INNER JOIN {node} n ON n.nid = tn.nid
INNER JOIN {term_data} td ON td.tid = tn.tid 
WHERE n.status = 1 AND td.vid = %d'
;
$result db_query($sql,$vid);
...
?>
Аватар пользователя Guide Guide 31 мая 2009 в 18:59

Вот запрос:

SELECT t.* , h.parent, COUNT( n.nid ) AS nodes
FROM {term_data} t
INNER JOIN {term_hierarchy} h ON t.tid = h.tid
INNER JOIN {term_node} n ON t.tid = n.tid
WHERE t.vid =1
GROUP BY t.tid
ORDER BY t.tid ASC

Попробуйте получить из неё нужные вам данные.

Добавлено: Хехе, пока писал - опередили. Smile

Аватар пользователя вOFFка вOFFка 31 мая 2009 в 21:14

Юзаю такой код:

<?php
$max_fontsize = 17;  // Размер шрифта для тэга с максимальным весом
$min_fontsize = 8;   // Размер шрифта для тэга с минимальным весом
$metrics = 'pt';     // в чем измеряется размер px,pt,em, (с установкой в процентном отношении Flash  облоко глючит )
$voc = array(1);     // массив (vid) словарей
$max_tags = 1000;      // максимальное количество показываемых тэгов
$vocs = implode(',',$voc);
$class_voc = implode('-',$voc);
$result = db_query(db_rewrite_sql("SELECT max(cnt) AS maxcnt,min(cnt) AS mincnt
FROM {term_data} td  INNER JOIN
(SELECT tn.tid,COUNT(tn.nid) as cnt  FROM {term_node} tn
INNER JOIN {node} n ON n.nid=tn.nid GROUP BY tn.tid) n
ON n.tid=td.tid AND td.vid IN ("
.$vocs.")"));
$term = db_fetch_object($result);
$min_weight = $term->mincnt;
$max_weight = $term->maxcnt;
// вычислим коэффициент для размера шрифт
if ($min_weight == $max_weight ) {
    $font_metric_koof = 0;
}
else {
    $font_metric_koof = ($max_fontsize - $min_fontsize) / ($max_weight - $min_weight);
}
$result = db_query_range(db_rewrite_sql("SELECT td.tid,td.name,n.cnt
FROM {term_data} td  INNER JOIN
(SELECT tn.tid,COUNT(tn.nid) as cnt,MAX(n.created) as created  FROM {term_node} tn
INNER JOIN {node} n ON n.nid=tn.nid GROUP BY tn.tid) n
ON n.tid=td.tid AND td.vid IN ("
.$vocs.") ORDER BY td.name,n.created DESC"),0,$max_tags);
$tags = '';
while($term = db_fetch_object($result)) {
 $size  = $min_fontsize + ($term->cnt - $min_weight) * $font_metric_koof;
 $style = 'font-size: '.$size.$metrics.';';
 $tags .= l($term->name,'taxonomy/term/'.$term->tid,
  array('attributes' => array('style' => $style,'class' => 'tags-voc-'.$class_voc))).' ';
}
if (!empty($tags)) {
$output = '<tags class="voc-'.$class_voc.'">'.$tags.'</tags>';
echo $output;
}
?>
Аватар пользователя Guide Guide 31 мая 2009 в 21:56

"Nodachi" wrote:
А применительно к моему коду? Я не шарю просто, куда вставлять строчки?

Попробуйте заменить:

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

на:

if($count) {
  $pole[] = Array (l($term->name, "taxonomy/term/$term->tid") . " (".$count.")"), $term->depth, $count, $term->tid);
}
Аватар пользователя Guide Guide 1 июня 2009 в 16:26

"Nodachi" wrote:
Parse error: syntax error, unexpected '(', expecting ')' in .....\includes\common.inc(1645) : eval()'d code on line 14

Забыл скобку убрать... пардон...

if($count) {
  $pole[] = Array (l($term->name, "taxonomy/term/$term->tid") . " (".$count.")", $term->depth, $count, $term->tid);
}
Аватар пользователя Nodachi Nodachi 2 июня 2009 в 13:13

Так, чем дальше - тем красивее... Граждане, решил тут добавить немного красивостей и выложить тут решение.

Итак, ставим модуль taxonomy_image, в нем есть такая функция: taxonomy_image_display(). Добавляем ее в наш с вами общий код в таком виде: taxonomy_image_display($term->tid) и получаем красивый вывод терминов со значками. Надеюсь вам пригодится. Вот полный код:

<?php
$vid 
1;  // Номер словаря
$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));
  
if(
$count) {
  
$pole[] = Array (taxonomy_image_display($term->tid) . l($term->name"taxonomy/term/$term->tid") . " (".$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>";
  }
}
?>

P. S.
Кстати, после того, как загрузите картинки для терминов и будете причесывать страничку, можете спокойно создать при помощи модуля image_cache пресет для данных картинок. Ибо функция taxonomy_image_display($term->tid) использует их без проблем. Всем удачи!

Аватар пользователя fishtravel fishtravel 8 февраля 2010 в 22:49

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

Аватар пользователя zviryatko zviryatko 19 июля 2011 в 8:08

abarmot wrote:
Я так понимаю, что никому теперь в интернете w3c валидация не нужна :).

В моем случае чем больше пхп - тем меньше верстки, так что хороший прогер != хороший верстальщик. Wink

Аватар пользователя 1xXx1 1xXx1 14 июня 2012 в 3:06

Создаете блок и вставляете этот код. В пункте Формат текста выбираете php фильтр. Если у вас нет этого фильтра в списке, то значит у вас выключен модуль PHP Filter. Включите его он идет в стандартной комплектации.

Аватар пользователя Sadchenko Sadchenko 31 января 2013 в 3:11

А для Drupal 7 кто нить подскажет такой же сниппет, чтоб выводил 3 уровнял вложенности, кроме пустых терминов?
Пробовал вот этот http://www.drupal.ru/node/91119 но не работает, либо я чтото делаю не так. Склоняюсь ко второму варианту)