¿Colocar bloques programáticamente?

14

Estoy usando Drupal 7. En este momento, tengo un menú principal de navegación y un selector de idioma que existe en el encabezado de mi sitio web. Los coloqué allí yendo a CMS> Estructura> Bloques y luego arrastrando los bloques a la región del encabezado.

¿Cómo ubico programáticamente estos bloques en el encabezado?

John
fuente
De acuerdo con su pregunta sobre cómo ubicar programáticamente estos bloques en el encabezado, sugiero revisar el módulo de ejemplos http://drupal.org/project/examples y específicamente puede revisar y habilitar el módulo Ejemplo de bloque para probar el funcionamiento de su bloque de manera programática . Supongo que eso block_example_block_info()y el valor de 'región' podrían ser útiles para probar.
cigotete
John, ¿has encontrado una respuesta a esto?
relipse el

Respuestas:

4

Para alterar la región donde se colocan los bloques definidos por otros módulos, puede implementar hook_block_info_alter () , que recibe los siguientes argumentos:

  • $blocks (aprobado por referencia): la matriz que contiene las definiciones de bloque, codificadas por módulo y delta
  • $theme: el tema para el que se definen los bloques
  • $code_blocks: los bloques definidos a partir de las hook_block_info()implementaciones, antes de que sus valores sean anulados por los valores obtenidos de la base de datos
kiamlaluno
fuente
3

Es legítimo agregar una matriz renderizable a cualquier región de página en hook_page_build (). Ejemplo de Drupal 7 para agregar un minipanel a la región de pie de página.

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

Esta es la misma técnica que utiliza el módulo de contexto.

Nota: no necesita habilitar block.module para que esto funcione.

jonhattan
fuente
2

En D6 sería esencialmente

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

En D7 creo que es

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

pero todavía me estoy poniendo al día con D7.

mpdonadio
fuente
Esto no permite que los módulos de terceros alteren el bloque que se emite, ya que los módulos podrían implementar hook_block_view_alter que no se invoca con el código que muestra.
kiamlaluno
Creer drupal_add_region_content()es un callejón sin salida, ya que está destinado a las páginas de instalación / actualización.
doublejosh
2

Si está agregando un bloque personalizado, haga esto usando hook_block_info, estableciendo la opción de estado en 1 y la opción de región en la región en la que desea colocar el bloque.

Ejemplo:

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

Si desea cambiar un bloque ya existente, usaría hook_block_info_alter () en su lugar, la actualización de las mismas opciones se muestra a continuación.

Ejemplo:

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

Para obtener más información, consulte https://api.drupal.org/api/drupal/modules%21block%21block.api.php/function/hook_block_info/7

Wesley J
fuente
0

Este código se basa en @ jonhattan's, pero el suyo no representa el contenedor de bloques HTML o enlaces contextuales. También proporcioné una manera simple de especificar todos los bloques y regiones en un solo lugar.

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

Nota: a diferencia de su código, usted necesita el block.module instalado.

hargobind
fuente
-1

Esta no es la mejor forma, pero puede colocar manualmente el contenido en la matriz de páginas de esta manera ...

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

Aunque deberías seguir usando Context o solo bloques centrales. Hacer nuevos complementos no es tan malo como parece. Simplemente nombre los archivos correctamente, configure un disparador y una prueba. ejemplo .

doublejosh
fuente
De hecho, pensándolo bien, casi lamento publicar esta solución. No hagas esto.
doublejosh
-1

También puedes ajustar bloques en tu tema como:

/**
 * 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
fuente
Esto no responde a la pregunta de cómo representar bloques o cómo identificarlos en el marcado.
Christian