В Drupal 7, как мне получить список всех блоков, используемых на странице? - PullRequest
2 голосов
/ 30 декабря 2011

Я создаю модуль, который управляет рекламными блоками в виде блоков, которые должны знать друг друга и передавать информацию.

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

Я пробовал hook_block_list_alter (), но, похоже, он возвращает ВЕСЬ список блоков, существующих в моей установке Drupal, без указания того, какие блоки на самом деле будут отображаться или нет на этой странице.

Итак, что мне теперь делать?

Ответы [ 3 ]

5 голосов
/ 30 декабря 2011

Я думаю, что это как-то связано с заказом hook_block_list_alter(), но я не совсем уверен.В любом случае следующий код даст вам список всех блоков в контексте текущей страницы.Не включайте это в hook_block_list_alter() функцию, иначе вы получите исключение, вызванное бесконечной вложенностью.

global $theme;
$all_regions = system_region_list($theme);
$blocks = array();
foreach (array_keys($all_regions) as $region) {
  $blocks += block_list($region);
}

Если вам нужны блоки только в определенном регионе, вы можете отказаться от большей части кодавыше и просто идти с:

$blocks = block_list('region_name');
3 голосов
/ 17 ноября 2012

Я столкнулся с той же проблемой при вызове block_list('content').Глядя на код этой функции, я обнаружил, что она вызывает две другие функции, _block_load_blocks() и _block_render_blocks().Кажется, проблема возникает в _block_render_blocks(), поскольку отображаемый текст не добавляется к объекту содержимого.Это отличается от других блочных объектов, которые проходят через функцию.

Чтобы обойти это, вместо вызова block_list() я вызвал _block_load_blocks() напрямую.Это возвращает массив блоков, сгруппированных по регионам, минуя вызов _block_render_blocks().Теперь мы можем проверять блоки в области содержимого без исчезновения текста содержимого.Huzzar!

1 голос
/ 27 декабря 2014

У меня было похожее требование при внедрении рекламного сервера (DFP).Мое решение состояло в том, чтобы определить массив как глобальную переменную и включить php-код в каждый блок рекламного блока, который добавил новый элемент в массив.

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

В моем случае я хотел использовать информацию для добавления сценариев в раздел <head>, которые ссылаются только на дополнительные модули из размещаемых блоков.Мое полное решение было следующим:

1) Реализовать ловушку init для создания глобальной переменной, в которой будет храниться информация о том, какие блоки отображаются (необходимо создать пользовательский модуль, содержащий этот код):

YOURMODULE_custom_init() {
  $GLOBALS['dfp-ads'] = array();
}

2) Включить основной модуль php

3) Добавить код php в конце каждого рекламного блока, чтобы добавить строку в массив, созданный на шаге 1

<?php
   $GLOBALS['dfp-ads']['AD_OR_BLOCK_NAME_GOES_HERE']="AD SPECIFIC SCRIPT GOES HERE";
?>

4) Реализовать THEME_preprocess_html в моем файле template.php для доступа к глобальной переменной, построить скрипт и добавить скрипт в раздел <head> с вызовом drupal_add_html_head

function YOURTHEME_preprocess_html(&$vars) {
   $inline_script = LOGIC TO ACCESS $GLOBALS['dfp-ads'] AND BUILD SCRIPT GOES HERE;
   $element = array(
      '#type' => 'markup',
      '#markup' => $inline_script,
   );

   drupal_add_html_head($element, 'google-dfp');
}

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

В этом случае вместо THEME_preprocess_html вы можете попробовать hook_page_alter (& page) Страница API для этого хука утверждает, что на отдельные "блоки" может ссылаться их пара модуль / дельта в пределах региона:"

// The login block in the first sidebar region.
$page['sidebar_first']['user_login']['#block'];

Надеюсь, это кому-нибудь поможет!

...