Using Drupal blocks without hook_block_info

I usually recommend using alternatives to the Drupal core block system, as it's not easy to export and has several limitations like not being possible to put the same block in two different regions, even if they are in different pages. But sometimes it can be useful, mostly if you render them from the code (because you will not export them and then you can place them wherever you want.

If we are using them like that, we can get rid off the hook_block_info. That hook is not really necessary. Here is a small snippet of code:

<?php
 
/**
 * Implements hook_block_info().
 */
function my_module_block_info() {
  $blocks['first_block'] = array(
    'info' => t('This block will appear on admin/structure/blocks'),
  );
  return $blocks;
}
 
/**
 * Implements hook_block_view().
 */
function my_module_block_view($delta = '') {
  $block = array();
  switch ($delta) {
    case 'first_block':
      $block['content'] = 'First block content';
      break;
    case 'hidden_block':
      $block['content'] = 'This block can be used but not through the admin/structure/blocks page';
      break;
  }
  return $block;
}

And then, we can render them programmatically wherever we want using a single line of code:

<?php
render(module_invoke('my_module', 'block_view', 'hidden_block'));

Or, if we have several blocks that we use, we can simplify that code implementing a simple hook_theme:

<?php

/**
 * Implements hook_theme().
 */
function my_module_theme() {
  $theme['block_viewer'] = array(
    'variables' => array(
      'delta' => NULL,
    ),
  );
  return $theme;
}
 
/**
 * Theme function to render a block.
 */
function theme_block_viewer($variables) {
  return render(module_invoke('my_module', 'block_view', $variables['delta']));
}

And then, we can render blocks easily anywhere (like templates or other theme functions) with:

<?php
theme('block_viewer', 'hidden_block');