36

In Drupal 6, it was easy to insert a block into a template with the following code:

$block = module_invoke('views', 'block', 'view', 'block_name');
print $block['content'];

However, using the same instructions in Drupal 7 does not seem to work. I have looked around and cannot find the new method.

Does Drupal 7 have a routine that can allow for programmatically inserting a block into a template or node?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Randy Burgess
  • 4,835
  • 6
  • 41
  • 59
  • There's a bug now popping up related to a newer version of PHP. See the answer for @canintex below. – Randy Burgess Mar 10 '14 at 19:07
  • The above practice isn't recommended. See [Load a block in template?](https://drupal.stackexchange.com/questions/46489/load-a-block-in-template) for details. – colan Mar 19 '14 at 16:23
  • The above practice is *no longer* recommended in 2014. We didn't have much to go on back in 2011. – Randy Burgess Mar 20 '14 at 17:02

15 Answers15

86

D7:

<?php
  $block = module_invoke('module_name', 'block_view', 'block_delta');
  print render($block['content']);
?>

'module_name' = The machine name of the module (i.e. the module's folder name). This is true for core modules too, so for instance 'search', 'user' and 'comment' would all work here.

'block_delta' = The machine name of the block. You can determine what this is by visiting the block administration page and editing the block. The URL for editing a webform block, for instance, would be something like:

Drupal 7: admin/structure/block/manage/webform/client-block-11/configure

In this example, 'webform' is the module's name, 'client-block-11' is the block's delta.

Custom blocks will have module name of 'block' and a number for a delta, which you can also find by editing the block.

More information: http://drupal.org/node/26502

Braulio Soncco
  • 353
  • 1
  • 4
  • 20
kloewer
  • 1,016
  • 1
  • 9
  • 7
  • 2
    This did not work for me. I had to use `print $block['content'];` in Drupal 7. – bcosynot Nov 24 '12 at 05:38
  • 5
    This did not worked for me in the node. I had to use `print render($block);` for views block and `print render($block['content']);` for a custom block in Drupal 7. – Kevin Siji Jun 20 '13 at 08:57
27

This appears to be the solution for inserting blocks into templates for Drupal 7, but it seems a bit clunky and I have no idea about impact on performance:

$block = block_load('views', 'block_name');      
$output = drupal_render(_block_get_renderable_array(_block_render_blocks(array($block))));        
print $output;

If anyone has a better procedure, please do add.

Randy Burgess
  • 4,835
  • 6
  • 41
  • 59
  • 1
    This is the solution I settled on - as it is the only way I have found of including the block title and contextual links. Thanks. – jackocnr May 24 '12 at 22:38
  • This method will theme the block content with the correct template file. Kloewer's answer will get you the body of the block unthemed. – Segfault Jun 25 '13 at 19:52
  • 1
    since php 5.4 , you can only call drupal_render on a variable... meaning that you should get your $output up to _block_get_renderable_array(), then print drupal_render($output) – PatrickS Dec 01 '13 at 08:01
  • This is what I needed to get #attached js included, using render() in a .tpl.php file. – Shaun Dychko Jun 16 '14 at 22:48
21

With wrburgess's answer you may get an error if your server is using a newer version of PHP.

Strict warning: Only variables should be passed by reference in include()...

This is what I did to not cause/get rid of the error.

  <?php
    $blockObject = block_load('views', 'block_name');
    $block = _block_get_renderable_array(_block_render_blocks(array($blockObject)));
    $output = drupal_render($block);
    print $output;
  ?>
canintex
  • 638
  • 1
  • 7
  • 21
  • Thanks for adding this. I got bitten by the issue two days ago and wasn't sure of the cause. – Randy Burgess Mar 10 '14 at 19:06
  • Can anybody tell me what is the difference between drupal_render() and render(), and where should I use each function ? `Thank you !` – Stphane Nov 26 '15 at 16:09
  • @Stphane : http://drupal.stackexchange.com/questions/66302/what-is-the-difference-between-render-and-drupal-render#answer-66304 – canintex Nov 30 '15 at 17:14
  • Works great, thanks @canintex! I recommend adding a condition to make sure $blockObject exists prior to printing or setting any variables. – ahimsauzi Aug 19 '19 at 21:57
11

This work for me:

98 is the id of the block

$block =block_load('block',98);
$output = drupal_render(_block_get_renderable_array(_block_render_blocks(array($block))));
print $output;
CaDyMaN
  • 111
  • 1
  • 2
  • you will need this when rendering a block you created at admin/structure/block/manage/block/98/configure – Augusto Mar 31 '15 at 10:28
7

Just tested this in drupal 7 and it works:

$bloqueServicios = module_invoke('views', 'block_view', 'servicios-blo_home');
print render($bloqueServicios);

Good luck!

DanyAlejandro
  • 1,440
  • 13
  • 24
5

For some reason render() doesn't work for me, but this does:

<?php
    $block = module_invoke('block', 'block_view', '1');
    echo $block['content'];
?>
mkj
  • 2,761
  • 5
  • 24
  • 28
user1253382
  • 137
  • 1
  • 2
5

The module_invoke() function works. However, I found that rendering a block this way apparently won't use a custom template for that block. This might be OK depending upon your needs.

As commented before in other answers, this works as well and also makes use of custom templates:

$raw_block = block_load('your-module', 'delta');
$rendered_block = drupal_render(_block_get_renderable_array(_block_render_blocks(array($raw_block))));
print $rendered_block;

So, if you have a custom block--your-module--delta.tpl.php template file, it will be used to format the block.

Source: http://api.drupal.org/api/drupal/includes!module.inc/function/module_invoke/7

cafonso
  • 909
  • 11
  • 18
3

This worked for my Drupal 7 , URL: admin/structure/block/manage/addthis/addthis_block/configure NOTE:delta and module name present in the url itself

$addblock = module_invoke('addthis','block_view','addthis_block');
print render($addblock['content']);

More information can be found on http://technarco.com/drupal/insert-block-node-or-template-drupal-7

Umesh Patil
  • 4,668
  • 32
  • 24
3

Improving wrburgess' answer, you can do it in one line...

<?php print drupal_render(_block_get_renderable_array(_block_render_blocks(array(block_load('module_name', 'block_delta'))))); ?>

So for example, I use block number 6...

<?php print drupal_render(_block_get_renderable_array(_block_render_blocks(array(block_load('block', '6'))))); ?>
Santiago Bendavid
  • 961
  • 1
  • 9
  • 16
3

In my search to include a block in a template, i came across this post.

As an addition, if you want to include a custom block (that you added through the block interface) you have to use (instead of block_load(); in drupal 7)

$block = block_get_custom_block($bid);
$content = $block['body'];
Andro Selva
  • 53,910
  • 52
  • 193
  • 240
michaelmol
  • 151
  • 4
1
 $block = module_invoke('menu_block', 'block_view', '6');
 echo render ($block['content']);

This works for me for printing menu block.

MilanG
  • 6,994
  • 2
  • 35
  • 64
1

There's module called insert_block for those which want to insert block "Drupal way" (not to program anything, just enable the module). Here's how to set it up.

NOTE: I know this question is about "programmatically inserting a block into a template or node" but Google sends people here even their are looking for non-programmer solution like me.

Jasom Dotnet
  • 1,225
  • 12
  • 17
0

Recently I faced the same issue and I came across a nice solution which describes the solution in drupal as drupal's way.

You can print regions inside any template, but they aren't available out of the box in the node.tpl.php template. To make them available, you'll create a new variable for use in your node.tpl.php template that'll contain all the region content.

Creating new template variables is done by using a preprocess function. In your theme's template.php file, create a function that looks like this:

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();
    }
  }
}

Then, in your theme's node.tpl.php template, you can render any region by doing the following:

<?php print render($region['sidebar_first']); ?>

Where sidebar_first is the name of the region you want to render.

Read the complete article here: https://drupal.stackexchange.com/questions/20054/can-regions-be-printed-within-a-node-template

Community
  • 1
  • 1
0

Have a look how Drupal does it in _block_render_blocks. The result of that function gets passed to drupal_render.

Oswald
  • 31,254
  • 3
  • 43
  • 68
0

module_invoke Working fine for render block in the template file, but it's not working multilingual sites.

Sohan Jangid
  • 149
  • 1
  • 7