Render a block programmatically
James Williams
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 theblock
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.