在Drupal 7中,如何获取页面上使用的所有块的列表?

时间:2011-12-29 21:38:20

标签: drupal drupal-7 drupal-modules drupal-blocks

我正在构建一个模块,以块的形式管理广告单元,这些模块都需要彼此了解并传递信息。

因此,我需要找到一个简单的钩子或其他函数来获取将在页面上使用的每个块的列表,因此我可以确定知道页面上的整个广告单元列表。

我已经尝试过hook_block_list_alter()但是这似乎返回了我的Drupal安装中存在的整个块的列表,没有指定实际上将在这个页面上呈现哪些块。

那么,现在该怎么办?

3 个答案:

答案 0 :(得分:5)

我认为这与订单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');

答案 1 :(得分:3)

我在调用block_list('content')时遇到了同样的问题。查看此函数的代码,我发现它调用了另外两个函数_block_load_blocks()_block_render_blocks()。问题似乎发生在_block_render_blocks()中,因为显示文本未添加到内容对象中。这与通过函数的其他块对象不同。

为了解决这个问题,我直接拨打了block_list(),而不是拨打_block_load_blocks()。这将返回按区域分组的块数组,绕过_block_render_blocks()调用。 现在我们可以检查内容区域中的块而不会使内容文本消失。 Huzzar!

答案 2 :(得分:1)

在实施广告服务器(DFP)时,我有类似的要求。我的解决方案是将一个数组定义为一个全局变量,并在每个广告单元块中包含php代码,为该数组添加一个新元素。

然后,一旦页面上的所有块都被执行,您只需访问全局变量即可查看调用了哪些广告块。因为构建被调用块列表的代码是每个块的一部分,所以块是否显示在区域,面板或其他任何地方都无关紧要。

就我而言,我想使用这些信息将脚本添加到<head>部分,该部分仅引用正在放置的块中的添加单元。我的完整解决方案如下:

1)实现hook 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)在template.php文件中实现THEME_preprocess_html以访问全局变量,构建脚本,并通过调用drupal_add_html_head将脚本添加到<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');
}

从您的描述中可以看出,您不需要广告块列表来为head部分构建javascript,而是希望使用这些信息来修改块本身的内容。

在那种情况下,您可以尝试hook_page_alter(&page) insteaad THEME_preprocess_html 该挂钩的api页面指出个别&#34;块可能被区域内的模块/增量对引用:&#34;

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

希望能帮助别人!