Дефолтных условий видимости блока часто не хватает. PHP filter выручает, но это не друпалвэй. Решение — hook_block_list_alter()
.
Пример вывода блока только для пользователей зарегистрированных меньше 5 минут назад:
/**
* Implements hook_block_list_alter().
*/
function MODULENAME_block_list_alter(&$blocks) {
$bid = 123;
// Минимально-необходимые проверки
if (!isset($blocks[$bid]) || !isset($blocks[$bid]->theme) || !isset($blocks[$bid]->status) || $blocks[$bid]->theme != $GLOBALS['theme_key'] || $blocks[$bid]->status != 1) {
return;
}
// Наше условие видимости
$user = $GLOBALS['user'];
if (!($user->uid && REQUEST_TIME - $user->created < 60*5)) {
unset($blocks[$bid]); // Удаляем блок из списка
}
}
123
— это bid блока. Посмотреть можно в таблице block
или в dsm($blocks);
.
Если блоков будет много, то можно пойти дальше и вынести проверку видимости в callback:
/**
* Implements hook_block_list_alter().
*/
function MODULENAME_block_list_alter(&$blocks) {
foreach ($blocks as $key => $block) {
if (!isset($block->theme) || !isset($block->status) || $block->theme != $GLOBALS['theme_key'] || $block->status != 1) {
continue;
}
$function = 'MODULENAME_block_visible_' . $block->module . '_' . str_replace('-', '_', $block->delta);
if (function_exists($function) && !$function($block)) {
unset($blocks[$key]);
}
}
}
Использовать так:
/**
* Block visibility callback.
*/
function MODULENAME_block_visible_MODULE_DELTA($block) {
$user = $GLOBALS['user'];
return $user->uid && REQUEST_TIME - $user->created < 60*5;
}
MODULE
— имя модуля в котором создан блок
DELTA
— делта блока
Как отметили в комментариях, на основе этого способа даже есть модуль — Extended block visibility.
Написанное актуально для
Drupal 7
Комментарии
Есть еще
https://drupal.org/project/extended_block_visibility
здорово, буду знать
Самый Drupalway - это Context :)
"PHP filter выручает, но это не друпалвэй. "
А почему это не друпалвэй? Что вообще считается друпалвэй и не друпалвэй?
Разработкой сайтов на друпал занимаюсь не так давно и в таких тонкостях еще не очень разбираюсь. Но если уж функционал php фильтров заложен по дефолту, то почему же это не друпалвэй?
кода в базе быть не должно
Почему? Что криминального в коде в базе?
1. тяжело писать
2. тяжело отлаживать
3. тяжело искать
4. тяжело деплоить
5. невозможно использовать систему контроля версий
6. выполняется дольше
7. проблемы с безопасностью
8. проблемы с кэшированием
ок... А если например я создаю некий блок программно (просто пишу файл php, в котором обращаюсь к БД, делаю нужные выборки и прочее), то как лучше всего подключить этот блок на нужные страницы? На данный момент я использую два варианта: 1. php-фильтр в блоках, где просто инклужу свой файл. 2. в файлах .page.tpl где задаю php-условие для показа блока.
Первый вараинт - не "друпалвэй", по описанным вами причинам. Второй - "говнокод", потому что мешает php-код и верстку в шаблоне.
Наверное, существуют куда как более оптимальные варианты?
Как программно ограничить видимость блока написано в посте выше
Это если блок - именно блок в структуре друпала. То есть, есть в списке блоков. А если это просто php-файл?
не понимаю вопроса
ну вот вы пишите:
if (!isset($blocks[$bid])....
где $bid - id блока.
То есть этот блок был создан в "структура - блоки". Так? Имеет свой id и к нему можно добраться через массив $blocks.
а я говорю, не о блоке, а о просто php-файле, результат работы которого мне нужно подключать на моих страницах по аналогии с тем, как мы подключаем блоки - на этой странице виден, а на этой нет. Вопрос в том, как в друпале лучше подключать подобные файлы? Можно же создать блок ("структура - блоки"), включить PHP и написать include myfile.php, после чего указать на каких страницах этот блок будет отображаться, использую стандартный интерфейс блоков. А можно вообще с блоками не связываться, а указать в файле node.tpl.php
if (node - > type == 'news') include myfile.php;
Но оба варианта, как я понимаю, не фонтан. так как же правильнее поступать в таких случаях?
создайте блок самостоятельно http://xandeadx.ru/blog/drupal/255
о, спасибо! :)
А есть в друпале функция программной реализации видимости блока по пути?
Например, как программно сказать, что блок должен отображаться только на страницах blog/* к примеру
https://api.drupal.org/api/drupal/modules%21block%21block.api.php/funct…
параметр pages
Немного не то. Мне необходимо чтобы блок отображался при наличии сессии $_SESSION['city'] и скажем на всех страницах blog/*
Вот как программно реализовать проверку пути по маске blog/*
https://api.drupal.org/api/drupal/includes!path.inc/function/drupal_mat…
Крут, именно то что нужна.
Большое спасибо, полезное дело делаете!
Здравствуйте, а подскажите пожалуйста как прописать, чтобы на главной блок не выводился для администратора.
Можно запретить для администратора, но тогда не будет исполнятся условие выводить только на главной, и блок выводится просто везде.
А если надо вывести view(тип page) по сложному условию?
Добавить комментарий