You are here

clean_markup_blocks.module in Clean Markup 7

Provides clean block markup.

File

modules/clean_markup_blocks/clean_markup_blocks.module
View source
<?php

/**
 * @file
 * Provides clean block markup.
 */

/**
 * No HTML wrapper element.
 */
define('CLEAN_MARKUP_BLOCK_NO_ELEMENT', 'none');

/**
 * Implements hook_permission().
 */
function clean_markup_blocks_permission() {
  $permissions = array();
  $permissions['administer clean markup block settings'] = array(
    'title' => t('Administer clean block markup settings'),
    'description' => t('Change the HTML used to render blocks.'),
  );
  return $permissions;
}

/**
 * Implements hook_form_alter().
 */
function clean_markup_blocks_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id === 'block_admin_configure' || $form_id == 'block_add_block_form') {
    if (user_access('administer clean markup block settings')) {

      // Load defaults.
      $defaults = variable_get('clean_markup_blocks-defaults');
      $wrapper_elements = _clean_markup_get_html_wrapper_elements();
      $optional_wrapper_elements = _clean_markup_get_html_wrapper_elements(TRUE);

      // Get settings for this block.
      $variable_name = _clean_markup_blocks_generate_prefix($form['module']['#value'], $form['delta']['#value']);
      $this_block_settings = variable_get($variable_name, $defaults);

      // Set our own submit handler so we can save the settings in our custom
      // part of the form.
      $form['#submit'][] = '_clean_markup_blocks_block_configure_submit';

      // Create our custom part of the form.
      $form['clean_markup'] = array(
        '#type' => 'fieldset',
        '#title' => t('Clean markup options'),
        '#group' => 'visibility',
      );

      // Controls for block markup.
      $form['clean_markup']['block_wrapper'] = array(
        '#type' => 'select',
        '#title' => t('Block wrapper markup'),
        '#description' => t('Choose the HTML element to wrap the block.'),
        '#default_value' => $this_block_settings['block_wrapper'],
        '#options' => $optional_wrapper_elements,
      );
      $form['clean_markup']['enable_inner_div'] = array(
        '#type' => 'checkbox',
        '#title' => t('Enable inner div'),
        '#description' => t('Specify if you want an inner div element inside the main block wrapper.'),
        '#default_value' => $this_block_settings['enable_inner_div'],
        '#states' => array(
          'invisible' => array(
            ':input[name="block_wrapper"]' => array(
              'value' => CLEAN_MARKUP_BLOCK_NO_ELEMENT,
            ),
          ),
        ),
      );
      $form['clean_markup']['additional_block_classes'] = array(
        '#type' => 'textfield',
        '#title' => t('Additional block classes'),
        '#description' => t('Additional classes to set on the block wrapper.'),
        '#default_value' => $this_block_settings['additional_block_classes'],
      );
      $form['clean_markup']['block_html_id_as_class'] = array(
        '#type' => 'checkbox',
        '#title' => t("Output block's HTML ID as class"),
        '#default_value' => $this_block_settings['block_html_id_as_class'],
      );

      // Controls for title markup.
      $form['clean_markup']['title_wrapper'] = array(
        '#type' => 'select',
        '#title' => t('Title wrapper markup'),
        '#description' => t('Choose the HTML to use to wrap the block title.'),
        '#default_value' => $this_block_settings['title_wrapper'],
        '#options' => $wrapper_elements,
      );
      $form['clean_markup']['title_hide'] = array(
        '#type' => 'checkbox',
        '#title' => t('Visually-hide block title'),
        '#description' => t('Add the <code>element-invisible</code> CSS class to the block title. This hides it visually but leaves it visible to screenreaders.'),
        '#default_value' => $this_block_settings['title_hide'],
      );

      // Controls for content markup.
      $form['clean_markup']['content_wrapper'] = array(
        '#type' => 'select',
        '#title' => t('Content wrapper markup'),
        '#description' => t('Choose the HTML to use to wrap the block content.'),
        '#default_value' => $this_block_settings['content_wrapper'],
        '#options' => $optional_wrapper_elements,
      );
    }
  }
}

/**
 * Form submit handler for block_admin_configure() and block_add_block_form().
 *
 * This allows us to save our custom options.
 */
function _clean_markup_blocks_block_configure_submit($form, &$form_state) {
  if (user_access('administer clean markup block settings')) {

    // Load defaults.
    $defaults = variable_get('clean_markup_blocks-defaults');
    $valid_wrapper_elements = _clean_markup_get_html_wrapper_elements(TRUE);

    // Get settings for this block.
    $variable_name = _clean_markup_blocks_generate_prefix($form_state['values']['module'], $form_state['values']['delta']);
    $new_block_settings = variable_get($variable_name, $defaults);

    // Match user input with valid wrapper element keys, otherwise user may be
    // trying to XSS.
    $new_block_settings['block_wrapper'] = array_key_exists($form_state['values']['block_wrapper'], $valid_wrapper_elements) ? $form_state['values']['block_wrapper'] : $defaults['block_wrapper'];
    $new_block_settings['title_wrapper'] = array_key_exists($form_state['values']['title_wrapper'], $valid_wrapper_elements) ? $form_state['values']['title_wrapper'] : $defaults['title_wrapper'];
    $new_block_settings['content_wrapper'] = array_key_exists($form_state['values']['content_wrapper'], $valid_wrapper_elements) ? $form_state['values']['content_wrapper'] : $defaults['content_wrapper'];

    // @ATTENTION: We assume that check_plain will be run before this value is
    // output; we're not running it here.
    $new_block_settings['additional_block_classes'] = $form_state['values']['additional_block_classes'];

    // Drupal 7 takes care of ensuring checkboxes that are in the form but were
    // submitted as FALSE show up in $form_state['values'] as FALSE even though
    // they weren't in the POST data. :D.
    $new_block_settings['enable_inner_div'] = (bool) $form_state['values']['enable_inner_div'];
    $new_block_settings['title_hide'] = (bool) $form_state['values']['title_hide'];
    variable_set($variable_name, $new_block_settings);
  }
}

/**
 * Helper function to generate a unique variable name for a block.
 *
 * @param string $module
 *   The name of the module providing this block.
 * @param string $delta
 *   The delta of this block in this module.
 *
 * @return string
 *   The unique name of the variable corresponding to the block identified by
 *   the parameters.
 */
function _clean_markup_blocks_generate_prefix($module, $delta) {
  return 'clean_markup_blocks--' . $module . '-' . $delta;
}

/**
 * Implements MODULE_preprocess_HOOK().
 */
function clean_markup_blocks_preprocess_block(&$variables) {

  // Load defaults.
  $defaults = variable_get('clean_markup_blocks-defaults');

  // Get settings for this block.
  $variable_name = _clean_markup_blocks_generate_prefix($variables['block']->module, $variables['block']->delta);
  $current_block_settings = variable_get($variable_name, $defaults);

  // Copy simple settings into variables.
  $variables['block_wrapper'] = $current_block_settings['block_wrapper'];
  $variables['inner_div'] = $current_block_settings['enable_inner_div'];

  // Convert the additional block classes into an array, then merge into the
  // existing classes array. Note the use of check_plain to prevent XSS.
  $variables['classes_array'] = array_merge($variables['classes_array'], explode(' ', check_plain($current_block_settings['additional_block_classes'])));

  // Only output a title if one is set.
  if ($variables['block']->subject) {
    $variables['title'] = array(
      '#prefix' => render($variables['title_prefix']),
      '#suffix' => render($variables['title_suffix']),
      '#type' => 'html_tag',
      '#tag' => $current_block_settings['title_wrapper'],
      '#attributes' => isset($variables['title_attributes']) ? $variables['title_attributes'] : array(),
      '#value' => $variables['block']->subject,
    );
    $variables['title']['#attributes']['class'] = array(
      'title',
      'block-title',
    );
    if ($current_block_settings['title_hide']) {
      $variables['title']['#attributes']['class'][] = 'element-invisible';
    }
  }
  else {
    $variables['title'] = array();
  }

  // Only wrap the content if the user wants a wrapper.
  if ($current_block_settings['content_wrapper'] !== CLEAN_MARKUP_BLOCK_NO_ELEMENT) {
    $variables['content'] = array(
      '#type' => 'html_tag',
      '#tag' => $current_block_settings['content_wrapper'],
      '#attributes' => array(
        'class' => array(
          'content',
        ),
      ),
      '#value' => $variables['content'],
    );
    $variables['content']['#attributes'] += $variables['content_attributes_array'];
  }

  // Output the block HTML ID as a class if requested.
  if (array_key_exists('block_html_id_as_class', $current_block_settings) && $current_block_settings['block_html_id_as_class'] == TRUE) {
    $variables['classes_array'][] = $variables['block_html_id'];
  }
}

/**
 * Implements hook_theme_registry_alter().
 */
function clean_markup_blocks_theme_registry_alter(&$theme_registry) {
  $theme_registry['block']['template'] = drupal_get_path('module', 'clean_markup_blocks') . '/theme/block';
}

Functions

Constants

Namesort descending Description
CLEAN_MARKUP_BLOCK_NO_ELEMENT No HTML wrapper element.