Placer des blocs par programme?

14

J'utilise Drupal 7. Pour le moment, j'ai un menu de navigation et un sélecteur de langue dans le titre de mon site Web. Je les ai placés là en allant dans CMS> Structure> Blocks et 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?

John
la source
Selon votre question sur la façon de situer ces blocs par programme dans l'en-tête, je suggère de consulter le module Exemples http://drupal.org/project/examples et plus précisément, vous pouvez consulter et activer le module Exemple de bloc pour tester le fonctionnement de votre bloc de manière programmatique . Je suppose que block_example_block_info()la valeur «région» pourrait être utile à tester.
cigotete
John, avez-vous trouvé une réponse à cela?
relipse le

Réponses:

4

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 (passé 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 hook_block_info()implémentations, avant que leurs valeurs soient remplacées par les valeurs obtenues à partir de la base de données
kiamlaluno
la source
3

Il est légitime d'ajouter un tableau pouvant être rendu à n'importe quelle région de page dans hook_page_build (). Exemple Drupal 7 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.

jonhattan
la source
2

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.

mpdonadio
la source
Cela ne permet pas aux modules tiers de modifier le bloc en cours de sortie, car les modules pourraient implémenter hook_block_view_alter qui n'est pas invoqué avec le code que vous avez montré.
kiamlaluno
Believe drupal_add_region_content()est une impasse car il est destiné aux pages d'installation / mise à niveau.
doublejosh
2

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 utiliserez plutôt 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

Wesley J
la source
0

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

hargobind
la source
-1

Ce n'est pas le meilleur formulaire, mais vous pouvez placer manuellement le contenu dans le tableau de pages comme ceci ...

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

Cependant, vous devez vous en tenir à l'utilisation de Context ou simplement de blocs de base. Faire de nouveaux plugins n'est pas aussi mauvais qu'il n'y paraît. Nommez simplement les fichiers correctement, configurez un déclencheur et un test. exemple .

doublejosh
la source
En fait, à la réflexion, je regrette presque d'avoir publié cette solution. Ne fais pas ça.
doublejosh
-1

vous pouvez également ajuster des blocs dans votre thème comme:

/**
 * 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']);
  }
}
rémy
la source
Cela ne répond pas à la question de savoir comment rendre les blocs ou comment les identifier dans le balisage.
Christian