Drupal. Хитрости таксономии

Умолчально предлагаемый друпалом способ выдачи нод принадлежащих термину таксономии прост, но все-таки достаточно убог. Формируем адрес taxonomy/term/N (N - номер термина) и получаем список нод принадлежащих ему.

Но подобная плоская иерархия редко бывает востребована. Поэтому сразу начинаешь искать некоторые дополнительные возможности, вроде Vocablary Index, Taxonomy Menu и прочие.
Правда, многие возможности уже заложены в сам модуль таксономии, хотя и редко упоминаются.

Используются эти возможности специально сформированным адресом страницы после term

Все ноды из нескольких категорий

По адресу taxonomy/term/N1+N2 мы получим все ноды принадлежащие сразу двум терминам таксономии за номерами N1 и N2. Число терминов таксономии в адресе может быть любым. Знак "плюс" выступает в качестве оператора "ИЛИ". В качестве разделителя также срабатывает и "пробел", но я думаю, что это не лучший символ для использования в адресах веб-страниц.

Только ноды находящиеся сразу в нескольких категориях

Адрес taxonomy/term/N1,N2 отображает только те ноды, которые одновременно принадлежат и термину за номером N1, и термину за номером N2. Как и выше, число терминов таксономии может быть любым. Знак "запятая" выполняет роль оператора "И".

Все ноды из подчиненных категорий

Пусть наш словарь таксономии содержит иерархический список с категориями и подкатегориями. Ноды прикрепляются к подкатегориям. Но здесь сразу встает задача показать в категориях все ноды из принадлежащих им подкатегорий. Такая возможность также предусмотрена в Drupal.

Адрес taxonomy/term/N/1 говорит модулю таксономии, что надо показать все ноды находящиеся в иерархии термина N на глубине 1. Адрес taxonomy/term/N/2 покажет все ноды принадлежащие терминам, подчиненным термину за номером N до глубины 2 включительно. И наконец, taxonomy/term/N/all выдаст ноды принадлежащие всем подчиненным терминам таксономии предком которых является N. Также во всех случаях будут показаны ноды принадлежащие самому термину N.

Комбинации нескольких терминов и глубины иерархии.

Оба вышеуказанных способа можно комбинировать. Примерно так:

taxonomy/term/N1+N2/2
taxonomy/term/N1+N2+N3/all
taxonomy/term/N1,N2,N3/2
taxonomy/term/N1,N2/all

Надеюсь уже понятно, что вы увидите по таким адресам.

Примечание.

Есть ограничение - применять в списке терминов таксономии можно только один из операторов, либо "плюс", либо "запятая". Сложное логическое выражение составить не получится. Скобки тоже не работают.

И не забудьте, что N, N1, N2 и N3 - это номера (идентификаторы) терминов таксономии, а не буквы с индексами.

Изменяем оператор И

Выше я уже говорил, что использование пробела в качестве разделителя терминов таксономии в адресе - это не самая лучшая идея. Данный символ в URL-адресах преобразуется в кодовую последовательность со знаком процента %20.
Вряд ли адрес вида taxonomy/term/25%2011%203/all можно назвать "чистым". Но поскольку есть альтернатива в виде знака "плюс", то эту проблему можно считать снятой.

С запятой происходит та же история. В адресах она преобразуется в %2C, что тоже плохо выглядит: taxonomy/term/25%2C11%2C3/all. И тут как назло, альтернативы не имеется.

Желающим исправить данную неприятность предлагаю небольшой хак модуля Taxonomy.

Разбор аргумента с номерами терминов таксономии производится в функцией taxonomy_terms_parse_string () которая находится в файле modules/taxonomy/taxonomy.module.
Выглядит она следующим образом (Drupal 6):

function taxonomy_terms_parse_string($str_tids) {
  $terms = array('operator' => '', 'tids' => array());
  if (preg_match('/^([0-9]+[+ ])+[0-9]+$/', $str_tids)) {
    $terms['operator'] = 'or';
    // The '+' character in a query string may be parsed as ' '.
    $terms['tids'] = preg_split('/[+ ]/', $str_tids);
  }
  else if (preg_match('/^([0-9]+,)*[0-9]+$/', $str_tids)) {
    $terms['operator'] = 'and';
    $terms['tids'] = explode(',', $str_tids);
  }
  return $terms;
}

Нас интересуют седьмая и девятая строчки. Добавим туда еще один знак "минус" и заменим функцию разбивающую строку на элементы.

function taxonomy_terms_parse_string($str_tids) {
  $terms = array('operator' => '', 'tids' => array());
  if (preg_match('/^([0-9]+[+ ])+[0-9]+$/', $str_tids)) {
    $terms['operator'] = 'or';
    // The '+' character in a query string may be parsed as ' '.
    $terms['tids'] = preg_split('/[+ ]/', $str_tids);
  }
  else if (preg_match('/^([0-9]+[-,])*[0-9]+$/', $str_tids)) {
    $terms['operator'] = 'and';
    $terms['tids'] = preg_split('/[-,]/', $str_tids);
  }
  return $terms;
}

Теперь для формирования страницы на которой узлы принадлежат нескольким терминам таксономии мы можем использовать адреса вида:
taxonomy/term/N1-N2-N3/all
<!--

Изменяем глубину просмотра иерархии по умолчанию

Если вы хотите при ссылке на термин таксономии всегда видеть все ноды как из него, так и из всех подчиненных ему нод, то сделать это достаточно просто.
-->

Убираем выделенный термин таксономии из ноды

Подача материалов (нод) на страницах таксономии раздражает одним моментом. Термин таксономии из заголовка повторяется в каждой ноде да еще и с гиперссылкой на эту же страницу.

Просмотрим код нашей веб-странице и попробуем выяснить цепочку классов, которые однозначно укажут в отображении ноды, на данный термин таксономии. В моем блоге это .terms .links .active и теперь можно убрать выделенный термин простое правило в файле CSS активной темы сайта.

.terms .links .active {
  display: none;
}

Правда, чтобы при этом не появлялось пустых мест стоит убрать поле вверху списка терминов.

.terms .links {
  margin-top: 0;
}

Если не секрет,

Если не секрет, какой визивиг или комбинацию визивигов использовали для подсетки кода в статье?

Это GeSHi

http://shaman.asiadata.ru/node/85
Для Drupal-сайтов есть модуль GeSHi Filter

Спасибо! А

Спасибо!

А почему бы Вам реализовать это не в виде хака, а в виде дополнительного модуля, в котором переопределяется функция? Так можно было бы не вмешиваться в базовый код, сохранив функциональность, которую вы даёте своим хаком.

А как?

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

Вы, разумеется,

Вы, разумеется, правы. Извините за глупый вопрос...

Тогда переформулирую его так: Почему бы Вам не предложить разработчикам ядра Друпала пересмотреть свою позицию в вопросе УРЛов таксономии? Возможно, они и сами задумывались о том, что нынешний вариант не слишком хорош, но не было импульса к тому, чтобы переделать реализацию функции.

Подумывал об этом. Но...

Подумывал об этом. Но...
Языковой барьер. Я неплохо знаю английский, чтобы читать любые доки, но вот выразить на нем что-то сложнее My name is Valia смогу с трудом.

Да, понимаю Вас.

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

Пришёл мне ещё в голову вариант модуля, который будет парсить УРЛы на предмет, есть ли там аргументы с терминами таксономии в виде 1-2-3, а потом применять к ним стандартный taxonomy_select_nodes Повторюсь, что я полный профан в Друпал и пхп, может быть я опять глупости говорю, но мне кажется, что это могло бы стать выходом и помогло бы использовать и стандартное представление условий, и то, которое хотели бы реализовать Вы.

Я на www.drupal.ru эту тему поднимал

Вот тут http://drupal.ru/node/14643
Пару подсказок дали, плюс есть еще функции custom_url_rewrite_inbound () и custom_url_rewrite_outbound (), которые можно разместить в settings.php, но мне пока лень этим заниматься.

Полностью с

Полностью с вами согласна. И не только я, таких людей много. Все приходит с опытом.

Если честно, то очень сложно

Если честно, то очень сложно рзобраться самостоятельно в этом

Заведите хорошую привычку,

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

Thank you very much for the

Thank you very much for the excellent and useful subject.

не раскрывается меню если ссылка содержит \all

Итак, сделал несколько словарей таксономии.
В каждом словаре настроена иерархия до 3- уровня.

Пример
Новости
-Вложение1
-Вложение2
--подвложение1
--подвложение2

Хочу создать на это все ссылки через стандартный модуль menu.
Так как при нажатии на ссылку новости мне необходимо видеть все новости из всех вложенных категорий то ставлю \all
Прописываю остальные пункты меню и где надо тоже ставлю \all
и вот тут начинается полная засада. Меню вроде как существует. Все пункты в нем прописаны правильно. Но если нажать на первую ссылку новости то вложенные ссылки не показываются. Если \all убрать то вложенные ссылки будут отображаться нормально.
Если поставить Расширенное то вложенные ссылки будут отображаться хоть с \all хоть без него.
Что и где надо поправить что бы все заработало как надо?

Пробовал настраивать модуль taxonomy_treemenu и другие похожие модули, но мне не подошло. Так же не подошли модули типа dhtml_menu потому как они добавляют ненужную визуализацию.

Попробуйте модуль Taxonomy Menu

Попробуйте модуль Taxonomy Menu

Пробовал, оно не настолько

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

такая же проблема

"Хочу создать на это все ссылки через стандартный модуль menu.
Так как при нажатии на ссылку новости мне необходимо видеть все новости из всех вложенных категорий то ставлю \all
Прописываю остальные пункты меню и где надо тоже ставлю \all
и вот тут начинается полная засада. Меню вроде как существует. Все пункты в нем прописаны правильно. Но если нажать на первую ссылку новости то вложенные ссылки не показываются. Если \all убрать то вложенные ссылки будут отображаться нормально.
Если поставить Расширенное то вложенные ссылки будут отображаться хоть с \all хоть без него.
Что и где надо поправить что бы все заработало как надо?"

такая же задача!
пробывал искать решение здесь http://www.drupal.ru/node/49415 - пока безрезультатно

Вряд ли адрес вида

Вряд ли адрес вида taxonomy/term/25%2011%203/all можно назвать "чистым".

Как на счет Pathauto? можно же применить синонимы... к примеру вместо taxonomy/term/25%2011%203/all прменить taxonomy/term/blabla/all или вообще taxonomy/blablaall и т.д.