Вход в систему



banner

Задать видимость блока с помощью View (сниплет)

 
Lynx аватар

Самый популярный способ использования Представлений (Видов, Views) – это формирование списка материалов. Так, например, довольно часто, на главной странице многих проектов мы можем увидеть блок «Последние новости», который состоит из списка ссылок на конкретные материалы. Генерируется такой блок модулем Views и размещается, как правило: 1) на главной странице и 2) каждой новостной странице. Видимость такого новостного блока задается сниплетом в его настройках (в разделе «Блоки»). Если Представление, генерирующее этот блок, в своей работе руководствуется элементарными условиями отбора, например, такими как тип материала или номер категории, то описать сниплетом условия появления такого блока довольно просто, в первом случае это будет сниплет:


  if ((arg(0) == 'node') && is_numeric(arg(1))) {
    $node = node_load(arg(1));
    return $node->type == 'News';
  }

где «News» – название типа материалов для новостей.
Во втором случае мы воспользуемся сниплетом:


  if ((arg(0) == 'node') && is_numeric(arg(1))) {
    $node = node_load(arg(1));
    foreach ($node->taxonomy as $tid_obj) {
      $tids[] = $tid_obj->tid;
    }
    return in_array('2', $tids);
  }

где «2»– это номер категории с которой мы проводим проверку (данный сниплет проводит проверку, «относиться ли текущий материал к определенной категории / термину» и если он относиться, сниплет возвращает положительный результат, означающий, что на данной странице блок может отображаться).

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


  if (drupal_is_front_page()) {return TRUE;}
  // --------------------------
  if ((arg(0) == 'node') && is_numeric(arg(1))) {
    $view_for_cond = views_get_view('News_announcement_view');
    $view_for_cond->build('default');
    $view_for_cond->execute('default');
    foreach ($view_for_cond->result as $node) {
      $view_nids[] = $node->nid;
    }
    return in_array(arg(1), $view_nids);
  }

Данный сниплет показывает новостной блок: 1) на главной странице; 2) на всех новостных страницах, удовлетворяющих условиям самого Представления. Это довольно простой сниплет, который будет работать на Представлениях, генерирующих списки. Данный сниплет работает следующим образом: мы производим запуск Представления и на выходе получаем массив объектов с nid всех материалов, вошедших в выборку, далее мы проверяем не входит ли nid текущего материала в этот массив и если входит, то возвращаем TRUE, иначе – FALSE. Особенностью данного сниплета является то, что вся «сверка» производиться на стороне сниплета, а не Представления. При необходимости вы можете создать более сложный сниплет с аргументами («$my_content_view->set_arguments(array($arg1, $arg2 ... $argN))»), при этом, в самом Представлении, для этих целей вы можете создать новую реализацию (типа Блок или Страница), принимающую эти аргументы и выводящую список из одного поля (аналог TRUE) или пустой список (аналог FALSE). В этом случае вся «сверка» будет производиться на стороне представления, а сниплет получит информацию о том, произошла ли выборка или нет (сниплет проанализирует количество записей и если это количество равняется нулю, тогда сниплет вернет FALSE, если единице, тогда TRUE).

Теперь о «скорости» такого решения. Не секрет, что Представления – это ресурсоемкий элемент, поэтому ими не стоит злоупотреблять. Для примера, среднее время формирования вышеописанного сниплета – 0,05 сек. (если проводить тестирование на домашнем ПК с процессором P4?3400MHz 2Mb cache Sock775, 2Gb DDR2; на производительном веб-сервере этот показатель может дойти до 0,01-0,005 сек.). Показанный здесь пример будет исполняться только на страницах с материалами – такое решение частично снизит нагрузку, но не стоить также забывать и о кешировании.

Идея: Lynxlab.net

 

Комментарии

planeta аватар

интересно

Спасибо, все ясно и дохотчиво, хороший сайт



Рейтинг@Mail.ru Rambler's Top100