以编程方式放置块?


14

我正在使用Drupal7。现在,我的网站标题中存在一个主菜单导航和语言切换器。我将它们放置在此处,方法是转到CMS> Structure> Blocks,然后将这些块拖到标题区域中。

如何以编程方式将这些块放置在标题中?


根据您有关如何以编程方式在标头中放置这些块的问题,我建议您查看示例模块http://drupal.org/project/examples,特别是您可以查看并启用模块块示例,以编程方式测试您的块。我认为block_example_block_info()“区域”值可能对测试很有帮助。
cigotete 2011年

约翰,您有答案吗?
relipse

Answers:


4

要更改放置其他模块定义的块的区域,可以实现hook_block_info_alter(),该函数接收以下参数:

  • $blocks (通过引用传递):包含块定义,由模块和增量键组成的数组
  • $theme:定义块的主题
  • $code_blocks:根据hook_block_info()实现定义的块,然后从数据库获取的值覆盖它们的值

3

将可渲染的数组添加到hook_page_build()中的任何页面区域是合法的。在Drupal 7中向页脚区域添加迷你面板的示例。

<?php
/**
 * Implements hook_page_build().
 */
function MODULE_page_build(&$page) {
  $block = module_invoke('panels_mini', 'block_view', 'blah');
  $blocks['blah'] = array('#markup' => $block['content']);

  $region = 'footer';
  if (isset($page[$region])) {
    $page[$region] = array_merge($page[$region], $blocks);
  }
  else {
    $page[$region] = $blocks;
  }
}

这是使用上下文模块的相同技术。

注意:您不需要block.module enable即可工作。


2

在D6中,基本上是

$block = module_invoke("the_module_name", "block", "view", the_block_delta);
drupal_set_content("the_region_name", theme("block", $block));

在D7中,我认为是

$block = module_invoke("the_module_name", "block_view", the_block_delta);
drupal_add_region_content("the_region_name", theme("block", $block));

但是我仍然要跟上D7的步伐。


这不允许第三方模块更改正在输出的块,因为模块可以实现不使用您显示的代码调用的hook_block_view_alter
kiamlaluno

相信drupal_add_region_content()是死路一条,因为它打算用于安装/升级页面。
doublejosh 2012年

2

如果要添加自定义块,请使用hook_block_info来执行此操作,将status选项设置为1,将region选项设置为要放置该块的区域。

例:

MODULE_block_info() {
  $blocks = array();
  $blocks['my_block'] = array(
    'info' => t('My Block Name'),
    'status' => 1,
    'region' => 'THE_REGION_I_WANT',
   );
   return $blocks;
}

如果要更改一个已经存在的块,则应使用hook_block_info_alter(),更新相同的选项如下所示。

例:

MODULE_hook_block_info_alter(&$blocks, $theme, $code_blocks) {
  $blocks['my_block']['status'] = 1;
  $blocks['my_block']['region'] = 'THE_REGION_I_WANT';
}

有关更多信息,请参见https://api.drupal.org/api/drupal/modules%21block%21block.api.php/function/hook_block_info/7


0

这段代码基于@jonhattan,但他没有呈现块容器HTML或上下文链接。我还提供了一种简单的方法来在一个地方指定所有块和区域。

<?php
/**
 * Implements hook_page_build().
 */
function MODULE_page_build(&$page) {
  global $theme;

  // A list of blocks you wish to display, keyed by region.
  // These are in the format of: 'module_name' => 'delta'.
  $blocks_to_render = array(
    'header' => array(
      'block' => 1,
    ),
  );

  // Add the blocks to each region.
  foreach ($blocks_to_render as $region => $block_list) {
    $block_objects = array();
    foreach ($block_list as $module_name => $delta) {
      $block = block_load($module_name, $delta);
      // Alter some of the defaults to match the current context.
      $block->theme = $theme;
      $block->region = $region;
      $block->weight = 0;
      $block_objects[] = $block;
    }
    $blocks_build = _block_get_renderable_array(_block_render_blocks($block_objects));

    if (isset($page[$region])) {
      $page[$region] = array_merge($page[$region], $blocks_build);
    }
    else {
      $page[$region] = $blocks_build;
    }
  }
}

注意:与他的代码不同,您确实需要安装block.module。


-1

这不是最好的形式,但是您可以像这样手动将内容放入页面数组中...

function mymodule_page_alter(&$page) {
  $my_content = _mymodule_render_mycontent();
  $page['my_region']['my_special_insert']['content']['#markup'] = $my_content;
}

虽然您应该坚持使用Context或仅使用核心块。制作新插件并不像看起来那样糟糕。只需正确命名文件,设置触发器和测试即可。例子


实际上,转念一想,我几乎后悔发布了该解决方案。不要这样
doublejosh 2015年

-1

您还可以调整主题中的块,例如:

/**
 * Implements hook_preprocess_page().
 */
function your_theme_preprocess_page(&$variables) {

  if (drupal_is_front_page()) {
    $variables['page']['region_one'] = $variables['page']['region_two'];
    unset($variables['page']['region_two']);
  }
}

这没有回答如何渲染块或如何在标记中标识它们的问题。
基督教徒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.