Drupal : Renderizar una Region de un Theme dentro de una tpl de Nodo

Necesitaba renderizar una region del tema dentro de la tpl de node, la idea era tener una zona para configurar bloques customizables por pagina. Googleando un poco me encuentro con una solución usando el hook preprocess node. Básicamente usando block_get_blocks_by_region.

function mytheme_preprocess_node(&$variables) {

  // Get a list of all the regions for this theme
  foreach (system_region_list($GLOBALS['theme']) as $region_key => $region_name) {

    // Get the content for each region and add it to the $region variable
    if ($blocks = block_get_blocks_by_region($region_key)) {
      $variables['region'][$region_key] = $blocks;
    }
    else {
      $variables['region'][$region_key] = array();
    }
  }
}

Y luego dentro del node.tpl.php esto para renderizar en ese lugar los bloques

print render($region['sidebar_first']);

No funcionó, yo había seteado los bloques por contexto, cuando pruebo por el sistema de bloques del core funcionó. Ahí me di cuenta que el problema estaba en que context no se integra con la función block_get_blocks_by_region. Buscando un poco mas me encuentro con esta alternativa que usa contexto.

  function MYTHEMENAME__preprocess_node(&$vars) {
    if ($plugin = context_get_plugin('reaction', 'block')) {
      $vars['my_region_name'] = $plugin->block_get_blocks_by_region('my_region_name');
    }
  }

Esto tampoco me funcionó directamente, seguía sin renderizarme el bloque, pero esta vez por que no había content.

Buscando otra vez me encuentro que recomiendan usar drupal_static_reset(‘context_reaction_block_list’); para refrescar el cache y regenerar los bloques aclarando que puede ser un performance killer, así que hice lo siguiente.

function THEME_render_region_blocks() {
  static $once = false;
  static $result = '';
  if ($once == false && $result == '') {
    $once = true; //Required to avoid recursive infinite loop rendering.
    drupal_static_reset('context_reaction_block_list');
    $plugin = context_get_plugin('reaction', 'block');
    $node_internal = $plugin->block_get_blocks_by_region('node_internal');
    $result = drupal_render($node_internal);
  }
  return $result;
}

Asi puedo renderizar la region, solo una vez y cachearla por la ejecución, y evito un loop infinito que se generaba al renderizar.

En el preprocess node me quedo algo así:

function THEME_preprocess_node(&$vars) { 
 $vars['internews'] = dt_get_internews();
}

 

Algunas referencias

http://www.webomelette.com/add-region-node-template
http://drupal.stackexchange.com/questions/20054/can-regions-be-printed-within-a-node-template
https://www.drupal.org/node/1306172
http://www.raisedeyebrow.com/blog/2012/07/displaying-drupal-context-regions-node-templates
http://kahthong.com/2012/08/embed-drupal-block-region-node-page
https://www.drupal.org/node/2107877

Share