Drupal 7: Creating Region Theme Settings

Drupal 7: Creating Region Theme Settings

Creating region theme settings

Creating theme settings in Drupal 7 is pretty straight forward using the Form API reference, but creating per-region settings requires a little more work. So let's get right to it.

If you do not have a theme-settings.php file, create one in the same directory as your theme's MY_THEME.info file. We'll be utilizing hook_form_system_theme_settings_alter() to set up our theme's custom settings.

Note: There is an issue which causes problems with sub-themes set as an admin theme #943212: hook_form_system_theme_settings_alter() vs. THEME_form_system_theme_settings_alter() name-clash. We'll include a workaround for Drupal 7, which most likely will not see any changes to the API for this issue.


 * Implements hook_form_system_theme_settings_alter().
function MY_THEME_form_system_theme_settings_alter(&$form, &$form_state, $form_id = NULL) {
  global $theme_key;

  // General "alters" use a form id. Settings should not be set here. The only
  // thing useful about this is if you need to alter the form for the running
  // theme and *not* the theme setting.
  // @see http://drupal.org/node/943212
  if (isset($form_id)) {

  // Get the active theme name.
  $theme_key = $form_state['build_info']['args'][0] === $theme_key ? $form_state['build_info']['args'][0] : $theme_key;

  // Fetch a list of regions for the current theme.
  $all_regions = system_region_list($theme_key);

  // Set the region padding options.
  $region_padding_options = array(
    0 => t('Default padding'),
    'large-padding' => t('Large padding'),
    'remove-padding' => t('Remove padding'),

  // Load all regions to assign separate settings for each region.
  foreach ($all_regions as $region_key => $region) {
    $form[$region_key] = array(
      '#type' => 'fieldset',
      '#title' => t('@region region', array('@region' => $region)),
      '#description' => t('Change the @region region settings.', array('@region' => $region)),
      '#collapsible' => TRUE,
    $form[$region_key][$region_key . '_padding'] = array(
      '#type' => 'select',
      '#title' => t('@title padding', array('@title' => $region)),
      '#description' => t('Set the padding for the @region region.', array('@region' => $region)),
      '#default_value' => theme_get_setting($region_key . '_padding', $theme_key),
      '#options' => $region_padding_options,

Now we're ready to retrieve the region settings and add classes to the default region template.


 * Implements template_preprocess_region().
function MY_THEME_preprocess_region(&$variables) {
  global $theme_key;
  $region = $variables['region'];
  $region_padding = theme_get_setting($region . '_padding', $theme_key);

  if ($region_padding) {
    $variables['classes_array'][] = $region_padding;

$variables['classes_array'] is the array used to add classes to regions. template_process() will flatten this to a string variable, $variables['classes'], to be used in region.tpl.php. Then you can use CSS to style the selectors .large-padding and .remove-padding.

That's it, you've now created per-region theme settings when you want to have fine-grain control over your regions.

Comments (1)

    • phyllismagill28026 (not verified)
    • August 16, 2017
    • Reply

    You are so cool! I do not suppose I have read something like this before. So good to discover another person with some genuine thoughts on this topic. Really.. many thanks for starting this up. This site is one thing that is required on the web, someone with a bit of originality!

Add new comment

The content of this field is kept private and will not be shown publicly.

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.