在Drupal7中,如何获得页面上使用的所有块的列表?

在Drupal7中,如何获得页面上使用的所有块的列表?,drupal,drupal-7,drupal-modules,drupal-blocks,Drupal,Drupal 7,Drupal Modules,Drupal Blocks,我正在构建一个模块,以模块的形式管理广告单元,所有模块都需要相互了解并传递信息 因此,我需要找到一个简单的钩子或其他函数来获得页面上将使用的每个块的列表,这样我就可以确保知道页面上广告单元的整个列表 我尝试了hook_block_list_alter(),但这似乎返回了Drupal安装中存在的所有块的列表,没有指定哪些块将实际呈现或不呈现在该页面上 那么,现在我该怎么办呢?我想这与调用的顺序有关hook\u block\u list\u alter(),但我不完全确定。无论哪种方式,下面的代码都

我正在构建一个模块,以模块的形式管理广告单元,所有模块都需要相互了解并传递信息

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

我尝试了hook_block_list_alter(),但这似乎返回了Drupal安装中存在的所有块的列表,没有指定哪些块将实际呈现或不呈现在该页面上


那么,现在我该怎么办呢?

我想这与调用的顺序有关
hook\u block\u list\u alter()
,但我不完全确定。无论哪种方式,下面的代码都将为您提供当前页面上下文中所有块的列表。请确保不要将其放入
hook\u block\u list\u 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');

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

为了解决这个问题,我没有调用
block\u list()
,而是直接调用
\u block\u load\u blocks()
。这将返回按区域分组的块数组,绕过
\u block\u render\u blocks()
调用。
现在,我们可以检查内容区域中的块,而不会使内容文本消失。哈扎

我在实现adserver(DFP)时也有类似的需求。我的解决方案是将数组定义为全局变量,并在每个向数组添加新元素的ad单元块中包含php代码

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

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

1) 实现hook init以创建一个全局变量,在其中存储有关显示哪些块的信息(您需要创建一个自定义模块来包含此代码):

2) 启用核心php模块

3) 在每个ad块的末尾添加php代码,以便向步骤1中创建的数组中添加一行

<?php
   $GLOBALS['dfp-ads']['AD_OR_BLOCK_NAME_GOES_HERE']="AD SPECIFIC SCRIPT GOES HERE";
?>
从您的描述听起来,您不需要ad块列表来构建头部部分的javascript,而是希望使用这些信息来修改块本身的内容

在这种情况下,您可以尝试使用主题、预处理和html 该钩子的api页面声明单个“块可由其区域内的模块/增量对引用:”


希望这对别人有帮助

太好了!记得在代码片段之前添加一行:global$theme//。我把它放在我的_module_init()中。@AdamFriedman:很好,我编辑了答案,包括:)***问题***我也在使用面板3,我认为这里有某种错误。您的代码实际上会导致面板和其中的所有内容都被删除。我打印出了所有的地区名称,发现罪魁祸首是地区:“内容”。当执行block_list(“content”)时,会以某种方式清除面板的内容。所以我只是检查一下,然后打电话继续;在循环中。而且,由于我在面板中放置块,它们实际上不在“内容”区域;事实上,他们不在任何地区。我完全忘了这件事。因此,我必须找到一些解决方案,也可以得到当前面板中的所有块。哎哟。
<?php
   $GLOBALS['dfp-ads']['AD_OR_BLOCK_NAME_GOES_HERE']="AD SPECIFIC SCRIPT GOES HERE";
?>
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');
}
// The login block in the first sidebar region.
$page['sidebar_first']['user_login']['#block'];