Drupal’s hook_block_info() is more useful than you think

Recently I was working on a Drupal project that required the use of a custom module and, within that module, custom blocks.  I searched for something like ‘drupal 7 custom block’ on google, grabbed the example code for hook_block_info() and hook_block_view() (as I’ve done plenty of times in the past), and went merrily on my way.
It seemed strange to me, however, that (as in the case of most examples of this hook) the only attribute given to the block would be ‘info’.   This time around I had the time to do a little further googling, and found that this hook, as I suspected, can be used for a lot more than just setting the block name.  Here, I’ll explain:

Most of the results for how to use this hook give you something like this:

function YOUR_MODULE_block_info() {
  $blocks = array();
  $blocks['YOUR_BLOCK_ABC'] = array(
    'info' => t('YOUR BLOCK NAME'),
  );
  return $blocks;
}

This sets up the block with the title and the block ID, and that’s it.  It’s simple, and it works (in conjunction with hook_block_view() that is).  I’ve been using this hook for some time in just that way – after you create the block using those two hooks, you then have to go into www.yoursite.com/structure/block/ and set the block’s status (active or otherwise), position in the template, etc.

It turns out that you don’t have to set those things manually, after all.  Instead of the following:

  $blocks['YOUR_BLOCK_ABC'] = array(
    'info' => t('YOUR BLOCK NAME'),
  );

Try something like this:

$blocks['YOUR_BLOCK_ABC'] = array(
    'info' => t('YOUR BLOCK NAME'),
    'status' => TRUE,
    'region' => 'sidebar_first',
    'visibility' => BLOCK_VISIBILITY_LISTED,
    'pages' => "YOUR_PAGE",
    ‘class' => 'your-custom-class',
);

So what exactly does this do for us?  Let’s break the array shown down:

    'info' => t('YOUR BLOCK NAME'),

Okay, so that line is identical to the other example.  This just registers the block name.

    'status' => TRUE,

This tells Drupal that the block is to be enabled by default (typical behaviour is disabled by default)

    'region' => 'sidebar_first',

This gives Drupal the default region you want the block to appear in.  Note that regions vary theme by theme, so you’ll need to make sure that the region you’re setting here exists on the site you want the block to be used in.

    'visibility' => BLOCK_VISIBILITY_LISTED,

As shown here, this indicates that the block will ONLY be listed on the pages you list.  There are three options for this: BLOCK_VISIBILITY_NOTLISTED, BLOCK_VISIBILITY_LISTED, and BLOCK_VISIBILITY_PHP.

    'pages' => "YOUR_PAGE",

Working with ‘visibility’ as seen above, the value put in ‘pages’ determines where the block may be found or where it may not be found, depending on how you’ve set it up.  In the example given, the block will only be visible on ‘YOUR_PAGE’.
To use multiple values for which pages you want the block to appear/not to appear on, you actually need to insert line breaks (not create an array out of it, as was my first instinct).  You can do so by using the following syntax:

    'pages' => "YOUR_PAGE\nYOUR_PAGE_NUMBER_TWO",

You can also allow the block to appear on subpages.  So if you have a path like this: www.example.com/mainpage/subpage, you can set the block to appear on ‘subpage’ (or any page that has the path /mainpage/whatever) by using the asterisk...  Like so:

    'pages' => "mainpage\nmainpage/*",

The \n is a special linebreak character; the /* tells Drupal to include the block on any path that matches ‘mainpage’ plus anything else, no matter what it is, that comes after that.

    ‘class' => 'your-custom-class',

This is useful for adding custom classes from the get-go.  It’s not always needed, but it can be useful in certain situations.
So the next time you’re creating a custom block server A for use on server B, you don’t have to set its properties manually twice.  And if you’re creating a series of blocks that will be used in the same place or the same way, you can use your copy-pasting skills to get you most of the way there without breaking a sweat!