xandeadx.ru Блог музицирующего веб-девелопера

Drupal → Как на странице материала вывести в блоке ноды из этой же категории

Распространённая задача — в блоке на странице материала, вывести ноды из категории, к которой принадлежит просматриваемый материал (под категорией понимается термин таксономии).

Способ 1

1. Создаём представление.

2. Добавляем дисплей Блок.

3. Добавляем фильтры (по типу материала, статусу и т.п.), меняем настройки по вкусу.

4. Добавляем контекстный фильтр по полю, в котором прописана категория материала (в примере это field_category).

5. В настройках контекстного фильтра отмечаем опцию Provide default value, в качестве типа выбираем PHP Code и в поле PHP contextual filter code пишем код, который вернёт значение поля у открытого материала, например:

return node_load(arg(1))->field_category['und'][0]['tid'];

6. Идём на страницу управления блоками, открываем настройки нового блока и устанавливаем видимость только для материалов определённого типа.

Способ 2

Всё тоже самое, только в настройках контекстного фильтра, в Provide default value, вместо PHP Code выбираем Taxonomy term ID from URL, отмечаем появившуюся опцию Load default filter from node page, that's good for related taxonomy blocks и выбираем нужный словарь в поле Vocabularies:

Спасибо kalabro за наводку.

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

Комментарии RSS

Если поле term reference одно, можно ещё так: http://www.drupal.ru/node/67295#comment-379233
Если не одно, тоже наверно можно, но у меня на Postgres работает некорректно.

совсем не очевидно =) добавил вторым вариантом. спасибо за наводку

field_category['und'][0]['tid']

und я бы заменил на LANGUAGE_NONE

А как исключить из вьюшки материал, на странице которого мы находимся?

Владимир, http://www.drupal.ru/node/67295#comment-379233

Content: Nid → Content ID from URL → и поставить галочку Exclude в MORE.

По поводу первого способа:
return node_load(arg(1))->field_category['und'][0]['tid'];
Если у данной ноды нет такого поля или оно пустое то ошибка ведь будет? Наверно, надо проверку прикрутить.

блок ведь показывается только на страницах определённого типа нод

Ну это частный случай, хотя даже если так, категория может быть просто не указана в конкретной ноде. Тогда получим Notice: Undefined index: und.
В этом случае нужно еще в настройках данного типа указать обязательность для field_category и убедится что у всех уже существующих нод данное поле имеет значение.

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

if ($node = menu_get_object()) {
  $items = field_get_items('node', $node, 'field_project');
  return isset($items[0]['nid']) ? $items[0]['nid'] : FALSE;
}

Кстати, может есть способ сделать это без PHP?

Добрый день.

Решение отличное, но вот как быть когда у ноды несколько терминов сохраненных линейно (HS) и в блоке нужно показать ноды только из самой последней категории?

Допустим:
Сантехника -> Смесители -> THG
Сантехника -> Смесители -> Hansgrohe -> Коллекция PuraVida
Сантехника -> Смесители -> Hansgrohe -> Коллекция Metropol

и находясь в ноде которая принадлежит категории "Коллекция PuraVida" в блоке нужно показать только ноды с Коллекция PuraVida...

при использовании 2 способа - показываются ноды и из другой категории Коллекция Metropol относящейся к Hansgrohe

а находясь в ноде которая принадлежит категории "THG" в блоке нужно показать только ноды с THG...

т.е. имеется разная глубина вложенности категорий

пользуйтесь первым способом

Спасибо, но и первый способ не подходит...

Если вставляем просто php код return node_load(arg(1))->field_category['und'][0]['tid'];

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

если изменить в коде 0 на максимальную глубину терминов (в приведенном пример это будет равно 3), то на страницах какой-либо коллекции Hansgrohe, будут показывать материалы только этой коллекции, что в принципе и надо... НО

на странице THG - блока не будет... т.к. тут глубина получается равна 2... :(

Вот такая незадача... :) В общем все сводится к тому как узнать самый последний термин, у текущего материала и отфильтровать вывод по нему.

$last_term = end(node_load(arg(1))->field_category['und']);
return $last_term['tid'];

Спасибо большое.
Работает как часы!

А как быть если нужно вывести еще и ноды верхнего термина?

Во втором способе следует отметить флажок настройках контекстного фильтра напротив
Limit terms by vocabulary
Иначе у меня не выводит список.

А если два аргумента?
Первый вывожу через PHP-код как return node_load(arg(1))->field_category['und'][0]['tid'];
И второй так же... Первый срабатывает, а второй нет... что делаю не так?

Ничего не выводит ;(

запрос вьюхи получается такой:

SELECT node.title AS node_title, node.nid AS nid
FROM 
{node} node
LEFT JOIN {field_data_field_pr_brend} field_data_field_pr_brend ON node.nid = field_data_field_pr_brend.entity_id AND (field_data_field_pr_brend.entity_type = 'node' AND field_data_field_pr_brend.deleted = '0')
WHERE (( (field_data_field_pr_brend.field_pr_brend_tid = '5' ) ))

При использовании обеих вариантов список нод формируется, но при этом появляется сообщение Notice: Undefined variable: tid в функции eval() (строка 3 в файле /,,/public_html/modules/php/php.module(80) : eval()'d code). Подскажите, пожалуйста, в чем может быть причина

Добрый день. При выводе материалов объединенных одним термином всегда пользовался вторым способом ибо не программист. Но вот возникла необходимость вывести термины помеченные другим термином (т.е. в одном словаре есть термины при создании которых заполняется поле термина из другого словаря). Необходимо вывести на странице термина список терминов его же словаря помеченных термином из другого словаря. В теории мне кажется что разницы не должно быть. Добавляем контекстный фильтр по TID для исключения ссылок термина на самого себя и контекстный фильтр по нужному полю со сторонним термином и задаем значение по умолчанию. Но... не работает, не выводит нужный результат.
Не подскажете какое программное решение?
p.s. Словарь, термины которого нужно выводить, двухуровневый

покажите скрин настроек views

Здесь два последовательных скрина http://yadi.sk/d/66ZOUtwZG4KNH, Во втором из за ограниченности окна не видно помеченный чекбокс с нужным словарем. А в остальном это представление по терминам с выводом одного поля "имя термина", являющегося ссылкой на сам термин. Других настроек нет.

Отсутствие ответа, как понимаю, следствие малой информативности скринов. Ну да, это так. А что там еще может быть желаемым видеть? Вот на всякий случай скрин общей страницы настроек представления http://yadi.sk/d/LNvtOM00GCCv6 .

Перепробовал массу вариантов с отношениями "без кода" но не работает. Единственно что я пока могу вывести это на странице родительского термина дочерние по контекстному фильтру "родительский термин". Но задача такова, что бы и на дочерних выводился родительский и смежные ему дочерние.

Приветствую!

Народ, может кто тут подскажет, уже голову сломал, задача в чем-то схожая. Надо вывести блок в зависимости от того, к какому термину принадлежит нода, причем с учетом родителей. Для 6 друпала я такой код нашел http://www.drupal.ru/node/66872, а для семерки не увидел таких наработок нигде...

<?php
 
 
// Vocabulary term ID for which to display the block:
$displayTermID =1;
 
// This will show on the index page for that term
  if ((arg(0) == 'taxonomy') && (arg(1) == 'term') && (arg(2) == $displayTermID)) {
    return TRUE;
  }
 
// Get all taxonomy terms for current node:
$currNodeTerms = taxonomy_node_get_terms(node_load(arg(1)));
 
// If there are no terms, fail-fast:
 
if (is_null($currNodeTerms) || 0 == count($currNodeTerms)) {
    return FALSE;
}
 
// For each term of the current node, get all the ancestor terms:
foreach($currNodeTerms as $term) {
 
    $ancestors = taxonomy_get_parents_all($term->tid);
 
    // Check for each ancestor term whether it is the term we are looking for.
    // If it is, return TRUE immediately:
    if (!is_null($ancestors) && 0 < count($ancestors)) {
        foreach($ancestors as $ancestor) {
            if ($displayTermID == $ancestor->tid) {
                return TRUE;
            }
        }
    }
}
 
// If we didn't find our term of interest, return FALSE:
return FALSE;
?>

Может кто решал такую задачу уже?

Если в урл материала передаются id материала, то почему выбирается в фильтре id термина таксономии из url?

Все делаю как написано по второму способу. В самой вьюхе материалы выводятся если в поле вписываю id термина. Но на странице материала в url не id термина ведь... Материалы в блоке не выводятся.

опция "Load default filter from node page, that's good for related taxonomy blocks" как бы намекает

Спасибо за такой быстрый ответ! :)
Так или иначе в моем случае работает только по первому методу. По второму - никак.

Да и первый на поверку не идеален. У меня у каждого материала несколько категорий. Вывод в блок идет только по одному термину, который [0]. Возможно ли как-то передать несколько значений? Скажем я могу собрать их в строку или массив... Но как передать?

включите опцию "Allow multiple values"

А где ее включить, если я php-кодом данные формирую? И в каком формате эти данные передавать?

Где включается нашел.
Осталось разобраться с данными.

не хочет работать. Не могу понять как настроить. Нужно, чтобы система собирала все категории просматриваемого материала, далее шла в БД, искала все материлы принадлежащие хотя бы одной из данных категорий, затем выбирала последние из этих материалов по дате публикации. И показывала в блоке.
В контекстных фильтрах уже все настройки перебрал...ничего не выходит. Видимо придется заморачиваться и писать собственный код :(

xandeadx, у меня поле типа float, хочу вывести на странице ноды с тем же значением.
В аргументах ставлю Поле (field_overalls) -> PHP ->

$node = node_load(arg(1));
 return $node->field_overalls['und'][0]['value'];)

Выдаёт пустой запрос. Как думаешь, в чём дело?
(на сайте есть ноды с одинаковыми значениями полей)

это баг mysql https://www.drupal.org/node/1940852#comment-7169688
думаю без альтера запроса не обойтись

А можно ли как-то вывести блок с "похожими" терминами на странице термина. К примеру - есть словарь "Магазины" и словарь "Категории". Термин словаря "Магазины" связан с терминоами словаря "Категории". Можно ли как-то на странице термина "Магазины" вывести блок с похожими магазинами, имеющими такой же термин категорий как и у него?

Прошу прощения, что не по теме. Но близко.

Задача следующая, есть страница через views вывод тип Вакансии, нужно чтобы когда вакансий не было, то выводился текст. Не могу понять как настроить этот текст.

справа откройте Расширенные или Advanced
ПОВЕДЕНИЕ ПРИ ОТСУТСТВИИ РЕЗУЛЬТАТОВ
добавьте действие Глобальный - Текстовое поле

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании