Views оказался настолько популярным модулем, что его даже включили в 8-ю версию Drupal. Он может формировать разделы сайта, блоки, быть источником списков и т.п. Но передача внешних параметров многообразием не отличается. Не хватает очень важного обработчика — контекста публикации.
С этой проблемой можно справится программно. Я покажу как переопределить фильтры views.
Для начала нужно создать представление, задав параметры фильтров, какими то дефолтовыми значениями.
Представленный код написан для Drupal 7.x, views 3.x.
Случай прямого вызова views
Если вызывать представление программно, то код начинается с получения объекта views. Более подробно можно посмотреть вот тут.
В данном примере я меняю параметры фильтра, исходя из контекста текущей публикации.
Конструкция сайта при этом следующая: на странице типа «каталог» нужно показать список публикаций типа «товар», соответствующих терминам, выбранным для данной публикации «каталог».
Каталогов может быть много на сайте, каждый со своим набором терминов, которые используются как фильтр товаров. Таким образом, мы получаем разные выборки товаров для каждой каталожной страницы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
//получим код текущей публикации if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == '') { $nid = arg(1) + 0; $node = node_load($nid); //если мы на странице каталога if ($node && $node->type == 'catalog') { //получим представление и его подвид $view = views_get_view('cat_goods'); $view->set_display('block'); // загрузим фильтры. $filters = $view->display_handler->get_option('filters'); // теперь мы можете поменять значения фильтров // их структура зависит от представления, которое // вы используете, структуры публикаций и т.п. // для это нужно будет исследовать полученный массив фильтров ... //установим измененные значения фильтров $view->display_handler->set_option('filters', $filters); //выполним запрос $view->execute(); //рендеринг $output = $view->render(); } } |
Для моего практического случая код, изменяющий значения в фильтрах, выглядел вот так:
1 2 3 4 5 6 7 8 9 10 11 |
//проверяем поле с терминами в публикации каталога if (empty($node->field_cats)) { //если значения не заданы, то можно вообще удалить фильтр unset($filters['taxonomy_catalog_tid']); } else { //если значения терминов заданы, перепишем их в фильтр, //имя которого соответствует названию поля в публикации "товар" $filters['taxonomy_catalog_tid']['value'] = array(); foreach ($node->field_cats[LANGUAGE_NONE] as $v) $filters['taxonomy_catalog_tid']['value'][$v['tid']] = $v['tid']; } |
Используем зацепку к views
Когда вы хотите поправить представление где то на полпути, то можно зацепиться через hook_views_pre_execute и поменять значение фильтров как раз перед выполнением views.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function YOURMODULE_views_pre_execute(&$view) { //здесь нужно проверить к какому объекту представления //вы получили доступ //для моего случая это выглядело бы так if ($view->name == 'cat_goods' && $view->current_display == 'block') { //грузим фильтры $filters = $view->display_handler->get_option('filters'); //меняем их ... //установим фильтры назад $view->display_handler->set_option('filters', $filters); } } |