web-dev-qa-db-fra.com

Placer des blocs par programme?

J'utilise Drupal 7. Pour le moment, j'ai une navigation dans le menu principal et un sélecteur de langue qui existe dans l'en-tête de mon site Web. Je les ai placés là en allant dans CMS> Structure> Blocs et hten en faisant glisser les blocs dans la région d'en-tête.

Comment puis-je situer ces blocs par programme dans l'en-tête?

14
John

Pour modifier la région où sont placés les blocs définis par d'autres modules, vous pouvez implémenter hook_block_info_alter () , qui reçoit les arguments suivants:

  • $blocks (Transmis par référence): le tableau contenant les définitions de bloc, saisi par module et delta
  • $theme: Le thème pour lequel les blocs sont définis
  • $code_blocks: Les blocs tels que définis à partir des implémentations hook_block_info(), avant que leurs valeurs soient écrasées par les valeurs obtenues à partir de la base de données
4
kiamlaluno

Il est légitime d'ajouter un tableau pouvant être rendu à n'importe quelle région de page dans hook_page_build (). Drupal 7 exemple pour ajouter un minipanel à la zone de pied de page.

<?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;
  }
}

Il s'agit de la même technique qui utilise le module de contexte.

Remarque: vous n'avez pas besoin d'activer block.module pour que cela fonctionne.

3
jonhattan

Si vous ajoutez un bloc personnalisé, vous le faites en utilisant hook_block_info, en définissant l'option de statut sur 1 et l'option de région sur la région dans laquelle vous souhaitez placer le bloc.

Exemple:

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

Si vous souhaitez modifier un bloc déjà existant, vous utiliseriez à la place hook_block_info_alter (), la mise à jour des mêmes options a montré ci-dessous.

Exemple:

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

Pour plus d'informations, voir https://api.drupal.org/api/drupal/modules%21block%21block.api.php/function/hook_block_info/7

2
Wesley J

En D6, ce serait essentiellement

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

En D7, je pense que c'est

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

mais je suis toujours à jour sur D7.

2
mpdonadio

Ce code est basé sur celui de @ jonhattan, mais le sien ne rend pas le HTML du conteneur de blocs ou les liens contextuels. J'ai également fourni un moyen simple de spécifier tous les blocs et régions en un seul endroit.

<?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;
    }
  }
}

Remarque: Contrairement à son code, vous avez besoin du block.module installé.

0
hargobind