Програмно розміщувати блоки?


14

Я використовую Drupal 7. Зараз у мене в заголовку веб-сайту є навігація в головному меню та перемикач мови. Я розмістив їх там, перейшовши до CMS> Structure> Blocks та hten, перетягуючи блоки в область заголовка.

Як я програматично розміщую ці блоки в заголовку?


Відповідно до вашого запитання про те, як програмно розташувати цей блок у заголовку, пропоную переглянути модуль "Приклади" http://drupal.org/project/examples, і конкретно ви можете переглянути та включити блок "Приклад блоку" для тестування роботи вашого блоку в програмному порядку . Я здогадуюсь, що block_example_block_info()тест та значення «регіон» можуть бути корисними для перевірки.
cigotete

Джон, ти придумав відповідь на це?
реліп

Відповіді:


4

Щоб змінити область, в якій розміщені блоки, визначені іншими модулями, ви можете реалізувати прив'язку__блок_інфо () , яка отримує такі аргументи:

  • $blocks (передається посиланням): масив, що містить визначення блоків, введений модулем та дельтою
  • $theme: тема, для якої визначаються блоки
  • $code_blocks: блоки, як визначено з hook_block_info()реалізацій, перш ніж їх значення перекритими значеннями, отриманими з бази даних

3

Додано масив, що віддається, до будь-якого регіону сторінки в mook_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.


Це не дозволяє стороннім модулям змінювати вихідний блок, оскільки модулі можуть реалізовувати прив'язку_block_view_alter, на яку не викликається показаний вами код.
kiamlaluno

Повірте drupal_add_region_content()- це глухий кут, оскільки він призначений для встановлення / оновлення сторінок.
doublejosh

2

Якщо ви додаєте нестандартний блок, ви робите це за допомогою гачки_block_info, встановлюючи параметр статусу на 1, а варіант регіону - на область, у яку потрібно розмістити блок.

Приклад:

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

Якщо ви хочете змінити вже існуючий блок, замість цього ви скористаєтеся_ук_блок_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;
    }
  }
}

Примітка. На відміну від його коду, вам потрібно встановити блок.модуль.


-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.