Welcome to the Geeks & God Static Archive. Read more »

Allowing Users to Easily Toggle Drupal Block Content

User Rating:
5
Average: 5 (1 vote)

This Drupal 6 module tutorial will show you how to create a block and allow users with a specified permission to select its output from predefined content options using a custom administration screen.

When Cornerstone Church started Live Streaming our services, we wanted a quick and easy way to switch the "Featured Series" block on our home page into a big button that linked to our live streaming page.

In order to allow users to switch this block without having access to Block administration, I wrote a quick little custom module that displays different contents in a block depending on a setting stored in the variables table. Users with the correct permission can navigate to admin/content/livetv and toggle between the two displays.

The following image displays an example of how this all looks.

Live TV Toggle Sample Screenshot

At first, it seemed like a good idea to automate this. Even though we normally stream at the same time every week, there were a lot of reasons to not do this, including variations from our normal schedule and managing when Drupal cron runs to cause the switch. We have a special user account for live stream moderators that only has access to change this setting.

The "broadcasting live" section is just a link. The info for making it look like a button is in the theme layer.

<a href="/media/webtv" id="live-tv-link" title="Click here to watch">Click here to watch a live service.</a>

So let's dig into this module and find out how it works! If you would like a copy of this module, check out the LiveTV Toggle Example sandbox project on drupal.org and use the Git instructions tab to check out the 6.x-1.x branch or download the latest snapshot tarball from the repository viewer.

Setting up Permissions

The first thing we need to do is define a new permission to grant to our users. This is a simple task using hook_perm().

/**
 * Implementation of hook_perm().
 *
 * Users with the specified permission will be allowed to toggle the
 * display.
 */
function livetv_perm() {
  return array('toggle live tv block');
}

Creating a menu item

Next we need to add a menu item for the administration form. We will use Drupal's Forms API to generate the admin screen and store the results. This menu item creates the path admin/content/livetv and specifies the necessary permissions to access the form. The value passed to 'page arguments' specifies the function containing the form information.

/**
 * Implementation of hook_menu().
 */
function livetv_menu() {
  $items = array();
  $items['admin/content/livetv'] = array(
    'title' => t('Live TV Toggle'),
    'description' => t('Switch between Live TV and Current Series block'),
    'page callback' => 'drupal_get_form',
    'page arguments' => array('livetv_admin_settings'),
    'access arguments' => array('toggle live tv block'),
    'type' => MENU_NORMAL_ITEM,
  );
  return $items;
}

Generating the admin form

Creating a form in Drupal is really just a matter of populating an array with values to define the form elements. The systems_settings_form() function is magical. When a form created with this function is submitted, the values are stored in the variables table using the form element name as the id.

The following function creates an administration form whose response is stored in the livetv_toggle variable.

/**
 * Generate a system settings form. The results of this form will
 * be stored in 'livetv_toggle' in the variables table.
 */
function livetv_admin_settings() {
  $options = array('1' => t('Show Live TV Info'), '0' => t('Show Current Series Promo'));
  $form = array();
  $form['livetv_toggle'] = array(
    '#type' => 'radios',
    '#title' => t('Display Options'),
    '#default_value' => variable_get('livetv_toggle', 0),
    '#options' => $options,
    '#description' => t('Currently selected display'),
  );
  return system_settings_form($form);
}

Creating a block

Now we can use Drupal's hook_block() to create a block. This block is then placed using the admin/build/block form (or Context module) like any other block. What makes our block work differently is that we'll populate $block['content'] differently depending on our options. When setting up the block, we'll specify livetv_block_render() as the source of our block's contents.

/**
 * Implementation of hook_block().
 */
function livetv_block($op = 'list', $delta = 0, $edit = array()) {
  switch ($op) {
    case 'list':
      $blocks[0] = array(
        'info' => t('Live TV or Current Series'),
      );
      return $blocks;
    case 'configure':
      return;
    case 'save':
      return;
    case 'view': default:
      switch ($delta) {
        case 0:
          $block['content'] = livetv_block_render();
          break;
      }
      return $block;
  }
}

Generating our block content

Now all we have to do is generate content based on the setting selected in our admin screen. This is the part you'll probably want to customize. Simply change the value of $output based on your own needs.

In my case, I want to generate a link when the variable livetv_toggle is set to 1 or display my current_series view when it's set to anything else. We'll use l() to generate the link and views_embed_view() to display the view.

/**
 * Generate contents for the block.
 *
 * If the controller value is set to 1, render a link to the
 * live streaming page at media/webtv.
 *
 * Otherwise, render the current_series view. We are rendering
 * a title here because views_embed_view() doesn't add a title
 * and we need one to be part of the content.
 *
 * To customize this module to suit your needs, simply change
 * the values of $output.
 *
 */
function livetv_block_render() {
  $output = "";
  switch (variable_get('livetv_toggle', 0)) {
    case 1:
      $attributes = array(
        'id' => 'live-tv-link',
        'title' => t('Click here to watch'),
      );
      $output = l(t('Click here to watch a live service.'), 'media/webtv', array(attributes => $attributes));
      break;
    default:
      $output = '<h2 class="title">'. t('Featured Series') .'</h2>'. views_embed_view('current_series');
      break;
  }
  return $output;
}

Discussion

That's really all there is to it. This is really just a glue module that ties a couple of existing pieces together.

It would be very easy to make this module more complicated. As already mentioned, we could make this fire from cron. We could extend the administration form to allow the user to specify the link target and the view name. But all of that would defeat the point of this exercise. This module is so simple that there's no reason to not tailor it to the exact needs of a single site. Little custom modules like this make it very easy to add nice details to a website without a lot of extra work or the bulk of a more generalized tool.