Author image
Senior Developer

Render a block programmatically

This is a real quick one, but so useful! We often want to render a block within content, perhaps as part of a node (maybe in hook_node_view, and then made configurable like a field), but there's no obvious way to do this correctly for any block. Drupal normally renders its blocks per region, so there is no single function to embed a block. I came across this really simple solution by Damien Tournoud in a Drupal core issue, which I feel deserves more exposure:

$block = block_load($module, $delta);
$render_array = _block_get_renderable_array(_block_render_blocks(array($block)));
$output = render($render_array);

That's just three lines, and you probably only need the first two! (For example, when within a view hook, where the content will all be rendered later anyway.)

The advantages:

  • It uses block_load() which initially tries to get the block from the block table, so it will load any custom blocks, but will also fall-through to taking the block from code otherwise.
  • Blocks are taken from the cache first where possible (as part of _block_render_blocks()).
  • Blocks go through drupal_alter() (again, as part of _block_render_blocks()), which is lacking from most solutions I've seen.
  • Essentially, this is the closest thing to the way Drupal core itself renders blocks, re-using the same functions, so the same theming and wrapping elements are applied, including the block title.

Disadvantages:

  • You may wish to avoid the extra database query in block_load(), or hitting the cache tables in _block_render_blocks().
  • If you're not fussed about the block being rendered as Drupal would normally render a block, perhaps you don't want to use _block_get_renderable_array() as the block will get rendered as a full block which is not as quick as just invoking the block's callback to get it's content.
  • You may want to avoid the block being altered for performance reasons or if you're certain the block will not get altered anyway. However, bear in mind that keeping your block alterable may be useful in future.

Thank you Damien!

P.S. Unfortunately, there isn't really an equivalent of this for Drupal 6. If anyone has any good suggestions for it, please do leave them in the comments below.

Comments

Cool! Very helpful. Just a note - since the block module is optional in Drupal 7, some people may have it disabled.

However, the code in this article will still work just fine if you pop the following line at the top:

module_load_include('module', 'block');
Comments on this article are now closed, if you want to give us feeback you can use our contact form instead.