Программно разместить блоки?


14

Я использую Drupal 7. Прямо сейчас у меня есть заголовок меню и переключатель языка, который существует в заголовке моего сайта. Я разместил их там, перейдя в CMS> Структура> Блоки и перетаскивая блоки в область заголовка.

Как программно расположить эти блоки в заголовке?


В соответствии с вашим вопросом о том, как программно расположить эти блоки в заголовке, я предлагаю ознакомиться с модулем примеров http://drupal.org/project/examples, и, в частности, вы можете просмотреть и включить модуль Block Example, чтобы протестировать работу вашего блока программным способом. , Я предполагаю, что значение block_example_block_info()'region' может быть полезным для проверки.
сигарета

Джон, ты придумал ответ на это?
переиздание

Ответы:


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.


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

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's, но он не отображает контейнерный блок 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;
}

Хотя вы должны придерживаться контекста или только основных блоков. Создание новых плагинов не так плохо, как кажется. Просто назовите файлы правильно, настройте триггер и тест. пример .


На самом деле, если подумать, я почти сожалею о публикации этого решения. Не делай этого.
doublejosh

-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']);
  }
}

Это не отвечает на вопрос о том, как визуализировать блоки или как их идентифицировать в разметке.
Кристиан
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.