Description

Change block #id tags using the "Block title" field. This provides easy and portable styling, "id=address" instead of "id=block-block-24".

Step 1 of 2

Set up a variable using a preprocess function and ensure that it is correctly formatted for #id attributes.

template.php

<?php
/**
 * Override or insert PHPTemplate variables into BLOCK templates.
 *
 * @param $vars
 *   A sequential array of variables to pass to the theme template.
 * @param $hook
 *   The name of the theme function being called ("block" in this case.)
 */
function mytheme_preprocess_block(&$vars, $hook) { //change mytheme to your theme name
  $block = $vars['block'];
  
  // Create css id attribute based on 'Block title' when available.
  if (!empty($block->title)) {
  // Create the variable and ensure that it is correctly formatted with mytheme_id_safe function
  $cssid = mytheme_id_safe($block->title);
  }
  else  {
  // If no "Block title", create css id attribute the traditional way.
  $cssid = "block-$block->module-$block->delta";
  }
  $vars['block_cssid'] = $cssid;
}
/**
 * Converts a string to a suitable html ID attribute.
 *
 * - Preceeds initial numeric with 'n' character.
 * - Replaces space and underscore with dash.
 * - Converts entire string to lowercase.
 * - Works for classes too!
 *
 * @param string $string
 *   The string
 * @return
 *   The converted string
 */
function mytheme_id_safe($string) { //change mytheme to your theme name
  if (is_numeric($string{0})) {
    // If the first character is numeric, add 'n' in front
    $string = 'n'. $string;
  }
  return strtolower(preg_replace('/[^a-zA-Z0-9-]+/', '-', $string));
}
?> /* exclude this closing php tag in your template.php file */

Step 2 of 2

Use the $block_cssid variable to print the #id attribute in the template file.

block.tpl.php

<div id="<?php print $block_cssid; ?>" class="block block-<?php print $block->module ?>">
<?php if ($block->subject): ?>
  <h2><?php print $block->subject ?></h2>
<?php endif;?>

  <div class="content">
    <?php print $block->content ?>
  </div>
</div>

Notes

  • This method ensures that the id attribute is correctly formatted (doesn't start with a numeral, all lower case, no space or illegal characters)
  • Add to the preprocess function if it already exists in your template.php file.
  • Include the mytheme_id_safe function at the end of your template.php file
  • If block.tpl.php doesn't exist in your theme folder, make a copy from modules/system to your theme directory. Only modify the copy in your theme folder.
  • This method will apply to all blocks. To target blocks on specific pages, see template suggestions.

Comments

generalconsensus’s picture

Thanks!

DanielF’s picture

I loved this snippet for Drupal 6. Made my CSS a lot nicer to work with. Unfortunately, it doesn't seem to work in D7, and I can't find a D7 version of this snippet. Could someone port this, please?

akobashikawa’s picture

In Drupal 6, alternative solution could be made via Block Class. It provides no descriptive id but descriptive class, or classes, you can define them in block configuration.
This module is available for Drupal 7 too.

jkwilson’s picture

I got it working in 7 with a small change in the final line of the preprocess function, to match what the block template was expecting. Instead of:

$vars['block_cssid'] = $cssid;

Use:

$vars['block_html_id'] = $cssid;

All other code from Step 1 stays the same and you can omit Step 2, as you should not need to alter your block template. Edit: Actually, my mistake, it did require the block template file in the theme, rather than the default. (Don't think it matters, but this is from the Zen theme.)

<div id="<?php print $block_html_id; ?>" class="<?php print $classes; ?>"<?php print $attributes; ?>>

  <?php print render($title_prefix); ?>
  <?php if ($title): ?>
    <h2<?php print $title_attributes; ?>><?php print $title; ?></h2>
  <?php endif; ?>
  <?php print render($title_suffix); ?>

  <?php print $content; ?>

</div><!-- /.block -->
njbarrett’s picture

<?php
/**
 * Override or insert variables into BLOCK templates.
 *
 * @param $vars
 *   A sequential array of variables to pass to the theme template.
 * @param $hook
 *   The name of the theme function being called ("block" in this case.)
 */
function mytheme_preprocess_block(&$vars) { //change mytheme to your theme name
  $block = $vars['block'];
  // Create id attribute based on 'Block title' when available.
  if (!empty($block->title)) {
    // Create the variable and ensure that it is correctly formatted using the inbuilt drupal function
    $id = drupal_clean_css_identifier($block->title);

    $vars['block_html_id'] = $id;
  }
}
?>