Drupal → Выводим список терминов из плоского словаря с помощью сниппета

05.12.2009

Список терминов

Решил отказаться от модуля Taxonomy Block, выводящий список разделов блога, в пользу сниппета (что такое сниппет и как им пользоваться). Причина — уж больно много запросов он (Taxonomy Block) делает для вывода простого списка.

Собственно код сниппета:

Drupal 6:

<?php
$terms = db_query("
  SELECT tid, name, (
    SELECT COUNT(*)
    FROM {term_node} tn
    LEFT JOIN {node} n ON tn.nid = n.nid
    WHERE tn.tid = td.tid AND n.status = 1
  ) node_count
  FROM {term_data} td
  WHERE vid = %d
  ORDER BY weight
", ID_СЛОВАРЯ);

$items = array();
while ($term = db_fetch_array($terms)) {
  $items[] = l($term['name'], 'taxonomy/term/' . $term['tid']) . ' (' . $term['node_count'] . ')';
}

echo theme('item_list', $items);
?>

Drupal 7:

$terms = db_query("
  SELECT tid, name, (
    SELECT COUNT(*)
    FROM {taxonomy_index} ti
    LEFT JOIN {node} n ON ti.nid = n.nid
    WHERE ti.tid = td.tid AND n.status = 1
  ) node_count
  FROM {taxonomy_term_data} td
  WHERE vid = :vid
  ORDER BY weight
", array(':vid' => ID_СЛОВАРЯ));

$items = array();
foreach ($terms as $term) {
  $items[] = l($term->name, 'taxonomy/term/' . $term->tid) . ' (' . $term->node_count . ')';
}

echo theme('item_list', array('items' => $items));

Вместо ID_СЛОВАРЯ нужно указать номер словаря в котором находится список разделов.

В Drupal 7 это же можно сделать и с помощью Views — Как с помощью Views 3 вывести список терминов с количеством помеченных ими нод.
Похожий способ для вывода иерархического списка — Программно вывести термины словаря в виде дерева с подсчётом количества материалов.

Написанное актуально для
Drupal 6, Drupal 7
Похожие записи

Комментарии

AlexStyle
01.10.2010, 10:38

Спосибо, интересно а можно все снипером! Вывести список Всех дочерних и под дочерних терминов, находясь на странице родительского термина? ну конечно с подсчетом нод в терминах, просто в taxonomy_get_tree подсчета количества нод нету хотя есть глубина вложености

xandeadx

Спасибо, у Вас очень полезный блог! А не могли бы Вы переписать этот снипет под 7-й Друпал?

И еще вопрос:

Причина — уж больно много запросов он (Taxonomy Block) делает для вывода простого списка.

Если список терминов статический (и не очень большой), может быть, имеет смысл все-таки ручками формировать меню? То есть использовать 1-й способ. Ручной вариант, наверное, более экономичный?

Хотя и там, по видимому, все равно запросы будут (при выводе списка меню). Какой вариант производительнее (ручной или снипетом)? Ведь у Вас тут запрос с JOIN-ом. Такие запросы вроде как не очень легкие?!

sql для семёрки:

    SELECT tid, name, (
        SELECT COUNT(*) FROM {taxonomy_index} ti
        LEFT JOIN {node} n ON ti.nid = n.nid
        WHERE ti.tid = td.tid AND n.status = 1
    ) node_count FROM {taxonomy_term_data} td
    WHERE vid = :vid
    ORDER BY weight
Ручной вариант, наверное, более экономичный?

конечно!

Ведь у Вас тут запрос с JOIN-ом. Такие запросы вроде как не очень легкие?!

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

Подскажите, пожалуйста, как в Drupal 7 вывести список дочерних терминов находясь на странице термина родителя?

Алекс Шут
05.10.2011, 21:23

Отлично работает))) В отличии от испробованных уже вариантов)

Rootical V.
08.02.2012, 14:34

У меня возникла проблема с использованием данного сниппета, быть может поможете с решением? После того, как в каком-либо из терминов удаляются ноды, $term['node_count'] возвращает неверное количество материалов (грубо говоря столько, сколько было до удаления).
Спасибо!

Гость
26.07.2012, 10:21

Здравствуйте!
Столкнулся со следующей проблемой:
необходимо создать древовидное меню из таксономии, при этом материалы размещаются только в последних дочерних терминах.т.е. если термин имеет хотя бы один дочерний, то ноды к нему не могут быть привязаны.
Древовидное меню необходимо сформировать таким образом,чтобы родительские термины при клике на них разворачивались и показывали список дочерних. дочерние же, формировали ссылку с tid, но если дочерний имеет свои дочерние,то снова нужно разворачивать его.

Очень прошу помочь Вас , как наиболее знающего специалиста по Drupal, если можете.
Заранее спасибо.

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

при помощи вьюс я собрал навигацию для каталога, которая, принимая из url в качестве аргумента id субтермина, выводит ноды с этим субтермином.
если в аргумент по ссылке передастся id родителя, то показанный набор будет "кашей".
поэтому и нужно чтобы в выводимом меню термины-родители не имели ссылок вообще.

перепробовал кучу сниппетов,что нашел, но они или выводят полное дерево с ссылками как на родительских так и дочерних терминах, или имеют ограничение по уровню вложенности.

php только начал изучать.такое пока еще не напишу сам.
p.s. drupal 6

Спасибо! Два этих модуля в связке сделали именно то,что нужно.

По поводу таксономии, а возможно ли вывести ещё например картинки прикреплёные к термину таксономии???

Присоединяюсь к вопросу о выводе поля имиджа прикрепленному к термину таксономии - для Drupal 7.

//Загрузка термина таксономии по его тид
$term=taxonomy_term_load($tid);
if(!empty($term)) {
//Выбор поля рисунок термина 
$uri= $term->field_image['und'][0]['uri'];
//var_dump($term);
}
//Вывод рисунка
if(isset($uri)){	
$style = 'large';
echo "<img src=".image_style_url($style, $uri).">";
}
kitonarios
29.04.2013, 17:27

Здравствуйте.... подскажите пожалуйста как вывести счетчик количества нод в для словаря.
<?php
$tid = 10;
$items = array();
$terms = taxonomy_get_children($tid);
foreach ( $terms as $term ) {
$items[] = l($term->name, 'taxonomy/term/' . $term->tid);
}
print theme('item_list', array('items' => $items));
?>

xandeadx, что-то мне подсказывает, что Вы - добрый друпал-маг волшебник.
Спасибо Вам большое.

Михаил
02.11.2016, 20:35

У меня такой вопрос - как сделать родительский термин НЕАКТИВНЫМ?
drupal 7.
И, если знаете, то сделать так, чтобы этот термин был неактивным, но счетчик имеющихся материалов в child-терминах складывался и показывался около родительского термина?

Подскажите пожалуйста, какой код сниппета для Drupal7 с выводом меню на основе плоского списка из терминов таксономии с прикрепленными иконками (field_image)?

Для Д8+ будет примерно так:

$query = \Drupal::database()->select('taxonomy_term_field_data', 'terms');
$query->leftJoin('node__field_tags', 'node_tags', 'node_tags.field_tags_target_id = terms.tid');
$query->leftJoin('node_field_data', 'node_data', 'node_data.nid = node_tags.entity_id');
$query->condition('terms.vid', 'ID_СЛОВАРЯ');
$query->condition('terms.status', '1');
$query->addExpression('COUNT(node_data.nid)', 'count');
$query->groupBy('terms.tid');
$query->orderBy('count', 'DESC');
$query->fields('terms', ['tid']);
$result = $query->execute()->fetchAllAssoc('tid');

Но надо подкорректировать ID_СЛОВАРЯ и поле (field_tags в примере), которое в ноде используется для связи.

Результатом будет массив из объектов:

 30 => {
    +"tid": "30"
    +"count": "133"
  }
  55 => {
    +"tid": "55"
    +"count": "75"
  }
...

Добавить комментарий