Drupal 7 hook_block changes, with example template module
Drupal seven broke out the old hook_block($op = 'list', $delta = 0, $edit = array()) function, which took an operation as an argument, into four functions, hook_block_info, hook_block_save, hook_block_view, hook_block_configure.
Below, I will present a custom block module template that will allow you to insert code into programmatically defined blocks. If you don't know how to create a module, skip to the end.
Creating programmatic blocks can save you the need to turn on the PHP filter on your site. Turning on the PHP filter for node or block content is bad because it allows permissioned users to post arbitrary PHP code which can break your site. Because, architecturally, it is stored in the database, when a PHP syntax error breaks access to your site, you can't access the configuration changes via the normal administration. This means you would need to use Drush or edit the database to disable that PHP block. Additionally, a node with a PHP snippet that includes drupal_goto() in its body will break cron, leaving your site un-indexed for search, among other bad things. An attacker's first choice would be the PHP filter, if they could obtain that permission. So best just leave it off, if you can. If you need it and understand the potential problems and how to fix them, carry on.
hook_block_info
hook_block_info tells Drupal about the existence of your block. You declare a delta that is the unique identifier, within your module. This does not need to be unique on your site, because Drupal will prefix this identifier with your module name.
<?php
function modulename_block_info() {
$blocks['sharethis'] = array(
'info' => t('modulename Sharethis'),
'cache' => DRUPAL_NO_CACHE, //see link below for what this does.
//many other properties can be added here in this way.
//for all options, http://api.drupal.org/api/drupal/modules--block--block.api.php/function/hook_block_info/7
);
$blocks['twitter'] = array(
'info' => t('Sample Block'),
'cache' => DRUPAL_NO_CACHE, //don't cache this one
);
return $blocks;
}
?>
hook_block_view
hook_block_view tells Drupal what to output for your block. You can specify $block['content'] and block['subject']. Subject is the title of your block, whereas content is your block's body. The Drupal 7 change here is that $block['content'] can be a renderable array. Here's a good intro to what that means and here is the forms API reference page.
<?php
function modulename_block_view($delta) {
$block = array();
//delta is your block name. then just set it equal to your return functions.
switch ($delta) {
case 'sharethis':
//use helper functions to set the blocks. Cleaner.
$block = modulename_sharethis();
break;
case 'twitter':
$block = modulename_twitter();
break;
}
return $block;
}
function icrc_blocks_sharethis() {
$content = 'test sharethis block';
//get the variable you set on the config page and do different things
if($icrc_blocks_sharethis_options = variable_get('icrc_blocks_sharethis_options', FALSE)){
$content .= $icrc_blocks_sharethis_options;
}
$content .= <<<EOT
ljlkajs//. l;kjasflk-=090_(""''""" whatever crazy stuff I want to put here
EOT;
//this $block['content'] uses the old way, just a regular string.
$block['content'] = $content;
$block['subject'] = 'title';
return $block;
}
function modulename_twitter() {
//this block content uses a renderable array for its content.
//great description of renderable arrays here: http://randyfay.com/node/79
$content = array(
'first_para' => array(
'#type' => 'markup',
'#markup' => 'A first paragraph',
),
'second_para' => array(
'#type' => 'markup',
'#markup' => 'A second paragraph',
)
);
$block['content'] = $content;
return $block;
}
?>
hook_block_configure
This function is where you expose configuration options be set when you click the "configure" dropdown on the corner of your block. These config options are saved in an array called $edit and passed to hook_block_save below.
<?php
function modulename_block_configure($delta) {
if ($delta == 'sharethis') {
$form['options'] = array(
'#type' => 'textfield',
'#title' => t('Configuration options here'),
'#default_value' => variable_get('modulename_sharethis_options', NULL),
// insert other configuration options here according to formapi:
// http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html/7
);
$form['twitter'] = array(
'#type' => 'checkbox',
'#title' => t('Include %anonymous', array('%anonymous' => format_username(drupal_anonymous_user()))),
'#default_value' => variable_get('modulename_switch_user_include_anon', FALSE),
);
return $form;
}
}
?>
hook_block_save
hook_block_save() is where you can save the configuration options you set in the above, normally using variable_set. You have access to the options via the $edit variable.
If you are confused, enable the devel module, uncomment the dpm() statement, and save a block. You'll see what hook_block_configure is passing to this function and then you can decide what to do with it.
<?php
function modulename_block_save($delta, $edit = array()) {
//dpm($edit, $delta); //enable devel and uncomment this to see what is being passed to this function.
//check to see if you are in your block, by checking delta
if ($delta == 'sharethis') {
//save the options into the variable you want to save
//remember, this will automatically serialize arrays for you,
//and variable_get will automatically unserialize them
//http://api.drupal.org/api/drupal/includes--bootstrap.inc/function/variable_set
variable_set('modulename_sharethis_options', $edit['options']);
}
}
?>
Below is the full module code. To create a module, create a folder in /sites/all/modules/custom/modulename. Then create two files, modulename.info, and modulename.module. Replace modulename with your module's unique name.
Here is the contents of modulename.info
<?php
core = "7.x"
dependencies[] = "block"
description = "custom block module"
name = "custom blocks"
?>
This code goes into modulename.info
<?php
function modulename_block_info() {
$blocks['sharethis'] = array(
'info' => t('modulename Sharethis'),
'cache' => DRUPAL_NO_CACHE, //see link below for what this does.
//many other properties can be added here in this way.
//for all options, http://api.drupal.org/api/drupal/modules--block--block.api.php/function/hook_block_info/7
);
$blocks['twitter'] = array(
'info' => t('Sample Block'),
'cache' => DRUPAL_NO_CACHE, //don't cache this one
);
return $blocks;
}
/**
* Implementation of hook_block_configure().
*/
function modulename_block_configure($delta) {
if ($delta == 'sharethis') {
$form['options'] = array(
'#type' => 'textfield',
'#title' => t('Configuration options here'),
'#default_value' => variable_get('modulename_sharethis_options', NULL),
// insert other configuration options here according to formapi:
// http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html/7
);
$form['twitter'] = array(
'#type' => 'checkbox',
'#title' => t('Include %anonymous', array('%anonymous' => format_username(drupal_anonymous_user()))),
'#default_value' => variable_get('modulename_switch_user_include_anon', FALSE),
);
return $form;
}
}
function modulename_block_save($delta, $edit = array()) {
//dpm($edit, $delta); //enable devel and uncomment this to see what is being passed to this function.
//check to see if you are in your block, by checking delta
if ($delta == 'sharethis') {
//save the options into the variable you want to save
//remember, this will automatically serialize arrays for you,
//and variable_get will automatically unserialize them
//http://api.drupal.org/api/drupal/includes--bootstrap.inc/function/variable_set
variable_set('modulename_sharethis_options', $edit['options']);
}
}
function modulename_block_view($delta) {
$block = array();
//delta is your block name. then just set it equal to your return functions.
switch ($delta) {
case 'sharethis':
//use helper functions to set the blocks. Cleaner.
$block = modulename_sharethis();
break;
case 'twitter':
$block = modulename_twitter();
break;
}
return $block;
}
function icrc_blocks_sharethis() {
$content = 'test sharethis block';
//get the variable you set on the config page and do different things
if($icrc_blocks_sharethis_options = variable_get('icrc_blocks_sharethis_options', FALSE)){
$content .= $icrc_blocks_sharethis_options;
}
$content .= <<<EOT
ljlkajs//. l;kjasflk-=090_(""''""" whatever crazy stuff I want to put here
EOT;
//this $block['content'] uses the old way, just a regular string.
$block['content'] = $content;
$block['subject'] = 'title';
return $block;
}
function modulename_twitter() {
//this block content uses a renderable array for its content.
//great description of renderable arrays here: http://randyfay.com/node/79
$content = array(
'first_para' => array(
'#type' => 'markup',
'#markup' => 'A first paragraph',
),
'second_para' => array(
'#type' => 'markup',
'#markup' => 'A second paragraph',
)
);
$block['content'] = $content;
return $block;
}Tags: hook_block_view