• статья
  • pantey

10 функций Drupal 7, облегчающие работу с таксономией

09.09.2014

Многие из вас наверняка, при создании сайта не раз использовали таксономию. С помощью таксономии можно организовать не только связку по категориям материалов, но и также реализовать сложнейшую иерархию. Но не многие знаю (не используют) функции, которые Drupal предоставляет из коробки для работы с таксономией. Как вы можете заметить следующая информация в большей степени касается разработчиков. Итак, по традиции будем разбираться на конкретных примерах, допустим у нас есть некая структура таксономии:

Иерархия созданная с помощью таксономии

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

Созданная нода, с привязанным термином таксономии

С исходными данными разобрались, теперь переходим непосредственно к самим функциям.

Список разбираемых функций для работы с таксономией: Обновление: 13.07.2015

Хочу заметить, что я для примера буду использовать непосредственно файл node.tpl.php текущей темы, я же вам не рекомендую делать этого, а все необходимые вам действия производить либо в файле template.php или же в своем модуле.

Функция taxonomy_get_parents($tid) – возвращает массив родительского термина, где:

  • $tid – id текущего термина (обязательный параметр)
Пример:
  1. <?php
  2. $tid = $node->field_hierarchy['und'][0]['tid']; // получили текущий термин ноды
  3. $parent = taxonomy_get_parents($tid); // получили массив с родительским термином
  4. ?>
Результат: Получили объект родительского термина

Если вы сравните с нашей иерархией, то можете увидеть, что родительским термином термина «More children 2» является «Children 3».

Функция taxonomy_get_parents_all($tid) – возвращает массив со всеми родительскими терминами, включая текущий термин, где

  • $tid – id текущего термина (обязательный параметр)
Пример:
  1. <?php
  2. $tid = $node->field_hierarchy['und'][0]['tid']; // получили текущий термин ноды
  3. $parent = taxonomy_get_parents_all($tid); // получили массив со всеми родительскими терминами
  4. ?>
Результат: Получили массив со всеми родительскими терминами текущего термина таксономии

Функция taxonomy_get_children($tid, $vid) – возвращает массив с дочерними терминами таксономии, где

  • $tid – id текущего термина (обязательный параметр)
  • $vid – id словаря, для ограничения поиска (не обязательный параметр)

Хочу заметить, что данная функция возвращает лишь первый уровень иерархии, т.е. дочерние термины дочерних терминов не попадут в массив

Пример:
  1. <?php
  2. $tid = $node->field_hierarchy['und'][0]['tid']; // получили текущий термин ноды
  3. $parent = taxonomy_get_children($tid, $vid = 2); // получили массив с дочерними терминами таксономии
  4. ?>
Результат: Получили массив с дочерними терминами таксономии (возвращает только первый уровень иерархии)

Функция taxonomy_get_tree($vid, $parent, $max_depth, $load_entities) – возвращает массив с иерархией указанного словаря, где:

  • $vid – id словаря таксономии (обязательный параметр)
  • $parent – id термина таксономии, именного для данного термина и будет построена иерархия (не обязательный параметр), по умолчанию равно 0, что выводит всю иерархию таксономии указанного словаря
  • $max_depth – указывает на число уровней иерархии, по умолчанию принимает NULL, что соответствует не ограниченному уровню иерархии (не обязательный параметр)
  • $load_entities – булевское значение, по умолчанию FALSE, значения забираются из таблицы taxonomy_term_date, для экономии памяти и время выполнения (не обязательный параметр)
Пример:
  1. <?php
  2. $vid = 2; // id словаря таксономии
  3. $parent = 7; //id термина таксономии, для которого необходимо построить иерархию
  4. $max_depth = 1; // уровень для формирования иерархии
  5. $parent = taxonomy_get_tree($vid, $parent, $max_depth);
  6. ?>
Результат: Получили массив с иерархией указанного словаря, с начала указанного термина таксономии и уровнем иерархии 1

Функция taxonomy_term_load($tid) – возвращает объект указанного термина таксономии, где:

  • $tid – id термина таксономии (обязательный параметр)
Пример:
  1. <?php
  2. $tid = 8; // id термина таксономии
  3. $parent = taxonomy_term_load($tid);
  4. ?>
Результат: Получили объект указанного термина таксономии

Функция taxonomy_get_term_by_name($name, $vocabulary) – возвращает массив с указанным именем термина таксономии, где:

  • $name - имя термина таксономии (обязательный параметр)
  • $vocabulary – имя словаря таксономии для ограничения поиска, по умолчанию NULL (не обязательный параметр)
Пример:
  1. <?php
  2. $name = 'Children 2'; // имя термина таксономии
  3. $vocabulary = 'hierarchy'; // имя словаря таксономии
  4. $parent = taxonomy_get_term_by_name($name, $vocabulary);
  5. ?>
Результат: Получили массив термина таксономии исходя из его имени

Функция taxonomy_vocabulary_get_names() – возвращает массив со списком всех словарей таксономии, где в качестве ключей передаются следующие параметры:

  • name –имя словаря таксономии
  • machine_name – машинное имя словаря таксономии
  • vid – id словаря таксономии
Пример:
  1. <?php
  2. $parent = taxonomy_vocabulary_get_names();
  3. ?>
Результат: Получили массив со списком словарей таксономии

Функция taxonomy_vocabulary_machine_name_load($name) – возвращает объект со всеми метаданными указанного словаря таксономии, где:

  • $name – машинное имя словаря таксономии (обязательный параметр)
Пример:
  1. <?php
  2. $name = 'hierarchy'; // машинное имя словаря таксономии
  3. $parent = taxonomy_vocabulary_machine_name_load($name);
  4. ?>
Результат: Получили объект со всеми метаданными указанного словаря таксономии

Функция taxonomy_vocabulary_load($vid) – возвращает объект со всеми метаданными указанного словаря, где:

  • $vid – id словаря таксономии (обязательный параметр)
Пример:
  1. <?php
  2. $vid = 2;
  3. $parent = taxonomy_vocabulary_load($vid);
  4. ?>
Результат: Получили объект со всеми метаданными указанного словаря таксономии

Функция taxonomy_get_vocabularies() – возвращает массив объектов словарей таксономии.

Пример:
  1. <?php
  2. $parent = taxonomy_get_vocabularies();
  3. ?>
Результат: Возвращает массив объектов словарей таксономии

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

P.S - подсчитать количество нод для термина
  1. /**
  2.  * @param tid
  3.  * Term ID
  4.  * @param child_count
  5.  * TRUE - Also count all nodes in child terms (if they exists) - Default
  6.  * FALSE - Count only nodes related to Term ID
  7.  */
  8. function term_nc($tid, $child_count = TRUE) {
  9. $tids = array($tid);
  10.  
  11. if ($child_count) {
  12. $tids = array_merge($tids, term_get_children_ids($tid));
  13. }
  14.  
  15. global $language;
  16. $langs = array($language->language);
  17. $langs[] = 'und';
  18.  
  19. $query = db_select('taxonomy_index', 't');
  20. $query->condition('tid', $tids, 'IN');
  21. $query->join('node', 'n', 't.nid = n.nid');
  22. $query->condition('n.status', 1, '=');
  23. $query->condition('n.language', $langs, 'IN');
  24.  
  25. $count = $query->countQuery()->execute()->fetchField();
  26. return $count;
  27. }
  28.  
  29. /**
  30.  * Retrieve ids of term children .
  31.  *
  32.  * @param $tid
  33.  * The term's ID.
  34.  * @param $tids
  35.  * An array where ids of term children will be added
  36.  */
  37. function term_get_children_ids($tid) {
  38. $children = taxonomy_get_children($tid);
  39. $tids=array();
  40.  
  41. if (!empty($children)) {
  42. foreach($children as $child) {
  43. $tids[] = $child->tid;
  44. $tids = array_merge($tids, term_get_children_ids($child->tid));
  45. }
  46. }
  47. return $tids;
  48. }

Оригинал на github

где:

  • $tid - tid термина
  • $child_count - булевское значение. Определяет подсчитывать или нет ноды дочерних терминов. По умолчанию TRUE

Обновление: 25.07.2015

Функция taxonomy_select_nodes() – возвращает массив с именем термина и привязанных к нему NID нод.

  1. <?php
  2. taxonomy_select_nodes($tid, $pager = TRUE, $limit = FALSE, $order = array('t.sticky' => 'DESC', 't.created' => 'DESC'));
  3. ?>

где:

  • $tid - tid термина
  • $pager - булевское значение. Определяет использовать ли пейджер.
  • $limit - булевское значение. Определяет лимит NID нод. Если не указать выберет 10 NID.
  • $order - задает критерии сортировки для NID
Узнавай о новых статьях сайта - первым. Просто подпишись на рассылку.

Комментарии (20)

Profile picture for user Юрий
Mist
30.04.2015

А подобный список функций будет для материала и пользователей?

Profile picture for user Юрий
Psyh
17.08.2015

Не могу обратиться к [i] элементу.
В views делаю хлебные крошки.
И вот с получением родительского термина запнулся.
Кусок моего кода:

$term = taxonomy_term_load(arg(2));
$tid = $term->tid;
settype($tid, integer);
$parent = taxonomy_get_parents($tid); 

print_r($parent);

Выдается следующее:

integerArray
(
    [85] => stdClass Object
        (
            [tid] => 85
            [vid] => 2
            [name] => Лампы, источники света
            [description] => 
            [format] => full_html
            [weight] => 0
            [vocabulary_machine_name] => catalog
            [field_pic] => Array
                (
                )

Получается чтобы добраться до name, мне надо обратиться так:

print_r($parent[85]->name);

но [85] меняется и равняется $tid. И если я пишу так:

print_r($parent[$tid]->name);

то ничего не выводится.
Как правильно вписать туда $tid?

Profile picture for user pantey
pantey
17.08.2015

пропустить через foreach

foreach($parent as $row){
$name = $row->name;
}
Profile picture for user Юрий
Psyh
17.08.2015

Спасибо большое. Такой способ работает, погуглил, нашел еще пару способов. Но не буду изощряться.

Profile picture for user Юрий
Алексей
23.08.2015

Подскажите как реализовать следующее:
Арбузы:
-красные
-желтые
Персики
-красные
-желтые
Как при нажатии на термин красные показывались и арбузы и персики.
Может быть есть какая то сложная таксономия, где можно указывать взаимосвязь терминов не по иерархии. Надеюсь понятно написал

Profile picture for user Юрий
Psyh
23.08.2015

Легкого способа нет. Я с подобной задачей тоже сталкивался. Очень долго ломал голову. Вот здесь http://www.drupal.ru/node/111072 обсуждал свою проблему. И худо-бедно решил.

Profile picture for user Юрий
Psyh
23.08.2015

Подумал еще, может у тебя и проще задача, и решить можно просто связав термины через Entity reference/

Profile picture for user Юрий
Алексей
24.08.2015

Прочитал тему. Именно это мне и нужно было. Спасибо большое, буду делать.

Profile picture for user Юрий
Алексей
24.08.2015

Нашел один модуль пока лопатил интернет Term Relations попробую его.

Profile picture for user Юрий
Psyh
23.09.2015

Переопределяю хлебные крошки в template.php
Как получить id термина в template.php?

Profile picture for user pantey
pantey
23.09.2015

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

Profile picture for user Юрий
Psyh
23.09.2015

Я хочу на странице ноды переопределить хлебные крошки, передать туда родительские термины.

Profile picture for user pantey
pantey
23.09.2015
<?php
/**
 * Implements hook_preprocess_node
 */
function hook_preprocess_node(&$variables) {
  
  if ($variables['view_mode'] == 'full'){
    $array_tid = array();
    $array_tid = $variables['your_field_name']['und'];
    dsm($array_tid);
  }
  
}
Profile picture for user Юрий
Psyh
23.09.2015

Спасибо. Но не получается.
$array_tid это объект? Не чистый id?
Если пишу dsm($array_tid); страница не открывается.
Без него ошибка "Notice: Undefined index: field_type в функции at_universal_preprocess_page()"
Хотя мое поле с термином называется field_type.

Что все-таки передавать сюда:

$term = taxonomy_term_load(5);
Profile picture for user pantey
pantey
23.09.2015

покажите ваш код.

Profile picture for user Юрий
Psyh
23.09.2015

Страшновато выглядит конечно, но работает.
Для проверки подставил в качестве аргумента - 5.

function at_universal_preprocess_page(&$variables) {
    $term = taxonomy_term_load(5);
    $tid = $term->tid;
    $parent = 0;
    $parent1 = 0;
    $parent2 = 0;
    $parent3 = 0;
    $parent2_tid = 0;
    $parent3_tid = 0;
    $parent = $term->name;
    $parent1 = taxonomy_get_parents($tid); 
    if ($parent1):
      foreach($parent1 as $row){
        $parent1_name = $row->name;
        $parent1_tid = $row->tid;
      }
    endif;

    $parent2 = taxonomy_get_parents($parent1_tid); 
    if ($parent2):
      foreach($parent2 as $row){
        $parent2_name = $row->name;
        $parent2_tid = $row->tid;
      }
    endif;
    $parent3 = taxonomy_get_parents($parent2_tid); 
    if ($parent3):
      foreach($parent3 as $row){
        $parent3_name = $row->name;
        $parent3_tid = $row->tid;
      }
    endif;

    $breadcrumbs = array();
    $breadcrumbs[] = l(t('Home'), '');
    if ($parent3):
      $breadcrumbs[] = l($parent3_name, 'taxonomy/term/'.$parent3_tid);
    endif;
    if ($parent2):
      $breadcrumbs[] = l($parent2_name, 'taxonomy/term/'.$parent2_tid);
    endif;
    if ($parent1):
      $breadcrumbs[] = l($parent1_name, 'taxonomy/term/'.$parent1_tid);
    endif;
    if ($parent):
      $breadcrumbs[] = l($parent, 'taxonomy/term/'.$tid);
    endif;
    drupal_set_breadcrumb($breadcrumbs);
}

?>
Profile picture for user pantey
pantey
23.09.2015

жесть...
в примере я вам написал какой использовать хук... сравните с вашим.
Через него получаете TID термина таксономии и далее через ф-ю

taxonomy_get_parents_all($tid);

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

Profile picture for user Юрий
Psyh
23.09.2015

Спасибо.
Но используя хук hook_preprocess_node, не устанавливаются хлебные крошки:

function at_universal_preprocess_node(&$variables) {
     $breadcrumbs = array();
    $breadcrumbs[] = l(t('Home'), '');
    $breadcrumbs[] = l(t('TEST'), '');
    drupal_set_breadcrumb($breadcrumbs);
 }

Если заменить его на hook_preprocess_page, то крошки устанавливаются. Зато при этом не работает этот кусок:

$array_tid = array();
$array_tid = $variables['field_type']['und'];
Profile picture for user pantey
pantey
23.09.2015
<?php
/**
 * Implements hook_preprocess_page
 */
function hook_preprocess_page(&$variables){
  if(isset($variables['node'])){
    $obj_page = menu_get_object();
    $tid = $obj_page->your_field['und'][0]['tid'];
    
    $array_term = taxonomy_get_parents_all($tid);
    $array_term = array_reverse($array_term);
    
    $breadcrumbs = array();
    $breadcrumbs[] = l(t('Home'), '<front>');
    
    foreach($array_term as $term){
      $breadcrumbs[] = l(t($term->name), 'taxonomy/term/' .$term->tid);
    }

    drupal_set_breadcrumb($breadcrumbs);
  }
}
Profile picture for user Юрий
Psyh
23.09.2015

Спасибо большое.
Не рассчитывал на полностью готовое решение. Огромное спасибо.