You are here

themekey.module in ThemeKey 6.3

ThemeKey is designed as a generic theme switching module.

ThemeKey allows you to define simple or sophisticated Theme Switching Rules. Using these rules you are able to use a different theme depending on current path, taxonomy terms, language, node type and many many more properties. It can also be easily extended to support additional properties as exposed by other modules:

@author Markus Kalkbrenner | Cocomore AG

@author profix898

See also

themekey_properties.module

http://drupal.org/user/124705

http://drupal.org/user/35192

File

themekey.module
View source
<?php

/**
 * @file
 * ThemeKey is designed as a generic theme switching module.
 *
 * ThemeKey allows you to define simple or sophisticated Theme Switching Rules.
 * Using these rules you are able to use a different theme depending on current
 * path, taxonomy terms, language, node type and many many more properties.
 * It can also be easily extended to support additional properties as exposed by
 * other modules:
 * @see themekey_properties.module
 *
 * @author Markus Kalkbrenner | Cocomore AG
 *   @see http://drupal.org/user/124705
 *
 * @author profix898
 *   @see http://drupal.org/user/35192
 */
define('THEMEKEY_PAGECACHE_UNSUPPORTED', 0);
define('THEMEKEY_PAGECACHE_SUPPORTED', 1);
define('THEMEKEY_PAGECACHE_TIMEBASED', 2);

/**
 * Implements hook_theme().
 */
function themekey_theme() {
  $items = array(
    'themekey_rule_chain_form' => array(
      'file' => 'themekey_admin.inc',
      'arguments' => array(
        'form' => NULL,
      ),
    ),
    'themekey_debug_messages' => array(
      'template' => 'themekey-debug-messages',
      'arguments' => array(
        'messages' => array(),
      ),
    ),
    'themekey_page_cache_icon' => array(
      'file' => 'themekey_admin.inc',
      'arguments' => array(
        'page_cache_support' => 0,
      ),
    ),
  );
  return $items;
}

/**
 * Implements hook_perm().
 */
function themekey_perm() {
  return array(
    'administer theme assignments',
    'administer themekey settings',
  );
}

/**
 * Implements hook_menu().
 */
function themekey_menu() {
  $items = array();
  $items['admin/settings/themekey'] = array(
    'title' => 'ThemeKey',
    'description' => 'Map themes to Drupal paths or object properties.',
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer theme assignments',
    ),
    'file' => 'themekey_admin.inc',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'themekey_rule_chain_form',
    ),
  );
  $items['admin/settings/themekey/properties'] = array(
    'title' => 'Theme Switching Rule Chain',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => 0,
  );
  $items['admin/settings/themekey/properties/delete'] = array(
    'title' => 'Delete ThemeKey Property',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'themekey_admin_delete_rule_confirm',
      1,
    ),
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer theme assignments',
    ),
    'file' => 'themekey_admin.inc',
    'type' => MENU_CALLBACK,
  );
  $items['admin/settings/themekey/settings'] = array(
    'title' => 'Settings',
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer themekey settings',
    ),
    'file' => 'themekey_admin.inc',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'themekey_settings_form',
    ),
    'type' => MENU_LOCAL_TASK,
    'weight' => 5,
  );
  $items['admin/settings/themekey/settings/general'] = array(
    'title' => 'General',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => 0,
  );
  return $items;
}

/**
 * Implements hook_init().
 *
 * This is where all of Themekey's magic happens.
 * ThemeKey detects if any Theme Switching Rule matches
 * the current request and sets the global variable $custom_theme.
 */
function themekey_init() {
  global $theme, $custom_theme;
  if (isset($theme)) {
    if (variable_get('themekey_debug_trace_rule_switching', FALSE)) {
      themekey_set_debug_message('Skipped rule checking because another module already initialized the theme engine. $theme has been set to %theme.<br />This seems to be a bug. Visit !link and help us improve other modules.', array(
        '%theme' => $theme,
        '!link' => l('drupal.org/node/754970', 'http://drupal.org/node/754970'),
      ));
    }
  }
  elseif ('admin/build/block' != $_GET['q'] && strpos($_GET['q'], 'admin/build/block/list') !== 0 && strpos($_SERVER['SCRIPT_FILENAME'], 'cron.php') === FALSE && strpos($_SERVER['SCRIPT_FILENAME'], 'drush.php') === FALSE && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'install' && MAINTENANCE_MODE != 'update')) {

    // don't change theme when another module already set a $custom_theme like system.module does (administration theme) until administrator turns on this feature
    if (!$custom_theme || variable_get('themekey_override_custom_theme', 0)) {
      require_once drupal_get_path('module', 'themekey') . '/themekey_base.inc';
      $theme_candidate = themekey_match_rules();

      // If no theme has been triggered but a theme
      // is in the user's session, use that theme.
      if (!$theme_candidate && !empty($_SESSION['themekey_theme']) && (!$custom_theme || $custom_theme == variable_get('theme_default', 'garland'))) {
        $theme_candidate = $_SESSION['themekey_theme'];
        if (variable_get('themekey_debug_trace_rule_switching', FALSE)) {
          themekey_set_debug_message('ThemeKey Debug: No rule triggered a different theme. Reusing last theme from user\'s session: %custom_theme', array(
            '%custom_theme' => $theme_candidate,
          ));
        }
      }

      // We have a theme, apply it
      if (!empty($theme_candidate) && $theme_candidate != 'default') {
        if (user_is_logged_in() && variable_get('themekey_theme_maintain', 0) || !user_is_logged_in() && variable_get('themekey_theme_maintain_anonymous', 0)) {
          $_SESSION['themekey_theme'] = $theme_candidate;
        }
        elseif (!empty($_SESSION['themekey_theme'])) {
          unset($_SESSION['themekey_theme']);
        }
        $custom_theme = $theme_candidate;
        if (variable_get('themekey_debug_trace_rule_switching', FALSE)) {
          themekey_set_debug_message('Switching theme to %custom_theme.', array(
            '%custom_theme' => $custom_theme,
          ));
        }
      }
      elseif (variable_get('themekey_debug_trace_rule_switching', FALSE)) {
        if ($custom_theme) {

          // static rules set $theme_candidate to 'default and $custom_theme' directly
          themekey_set_debug_message('$custom_theme has been set to %custom_theme during rule matching.', array(
            '%custom_theme' => $custom_theme,
          ));
        }
        else {
          themekey_set_debug_message('Using default theme.');
        }
      }
    }
    elseif (variable_get('themekey_debug_trace_rule_switching', FALSE)) {
      if ($custom_theme) {
        themekey_set_debug_message('Skipped rule checking because $custom_theme already set to %custom_theme by another module.', array(
          '%custom_theme' => $custom_theme,
        ));
      }
    }
  }
  elseif (variable_get('themekey_debug_trace_rule_switching', FALSE)) {
    if (strpos($_GET['q'], 'admin/build/block') !== 0) {
      themekey_set_debug_message('Rule checking disabled on block configuration.');
    }
  }
  if (variable_get('themekey_debug_show_property_values', FALSE) && module_exists('themekey_debug')) {
    themekey_debug_properties();
  }
}

/**
 * Implements hook_themekey_load_validators().
 */
function themekey_themekey_load_validators() {
  module_load_include('inc', 'themekey', 'themekey_validators');
}

/**
 * Implements hook_help().
 */
function themekey_help($path, $arg) {
  $text_1 = t('For every page request Drupal steps through this Theme Switching Rule Chain until an activated rule matches or it reaches the end. If a rule matches, the theme associated with this rule will be applied to render the requested page.');
  switch ($path) {
    case 'admin/help#themekey':
      module_load_include('inc', 'themekey', 'themekey_help');
      return '<p>' . t('ThemeKey allows you to define simple or sophisticated Theme Switching Rules. Using these rules you can use a different theme depending on current path, taxonomy terms, language, node type and many, many more properties. It can also be easily extended to support additional properties, as exposed by other modules.') . '</p>' . '<p>' . $text_1 . '</p>' . drupal_get_form('themekey_help_tutorials_form', FALSE) . drupal_get_form('themekey_help_examples_form', FALSE) . drupal_get_form('themekey_help_properties_form', FALSE) . drupal_get_form('themekey_help_operators_form', TRUE);
    case 'admin/settings/themekey':
      module_load_include('inc', 'themekey', 'themekey_help');
      return '<p>' . $text_1 . '<br />' . t('To get an idea how to get started you might have a look at the !tutorials_link.', array(
        '!tutorials_link' => l(t('tutorials'), 'admin/help/themekey'),
      )) . '</p> ' . drupal_get_form('themekey_help_examples_form', TRUE) . drupal_get_form('themekey_help_properties_form', TRUE) . drupal_get_form('themekey_help_operators_form', TRUE);
  }
}

/**
 * Replacement for drupal_set_message() during ThemeKey's initialization.
 * drupal_set_message() might call init_theme() too early, which causes ThemeKey
 * to not switch the theme.
 *
 * themekey_set_debug_message() put the untranslated messages on a stack and
 * hands them over to drupal_set_message() on demand.
 *
 * @param $msg
 *   the message as string. If the message is 'flush'
 *   all messages stored on the stack will be printed using
 *   drupal_set_message()
 *
 * @param $placeholder
 *   associative array of string replacments for $msg
 *   @see t()
 *
 * @param $translate
 *   boolean, if set to TRUE $msg will be handled by t()
 *   when handed over to drupal_set_message()
 */
function themekey_set_debug_message($msg, $placeholder = array(), $translate = TRUE) {
  static $msg_stack = array();
  global $user, $theme;
  if (1 == $user->uid || variable_get('themekey_debug_non_admin_users', FALSE)) {
    if ('flush' == $msg) {
      $messages = array();
      if (variable_get('themekey_debug_trace_rule_switching', FALSE)) {
        $messages[] = t('Current theme: %theme', array(
          '%theme' => $theme,
        ));
      }
      foreach ($msg_stack as $key => $msg) {
        $messages[] = $msg['translate'] ? t($msg['msg'], $msg['placeholder']) : $msg['msg'];
        unset($msg_stack[$key]);
      }
      if (!empty($messages)) {
        return theme('themekey_debug_messages', $messages);
      }
    }
    else {
      $msg_stack[] = array(
        'msg' => $msg,
        'placeholder' => $placeholder,
        'translate' => $translate,
      );
    }
  }
}

/**
 * Implements hook_footer().
 *
 * Prints out debug messages for admin user.
 *
 * @return string
 */
function themekey_footer() {
  return themekey_set_debug_message('flush');
}

/**
 * Returns the content of $_GET['q'] as expected.
 * Therefore, $_GET['q'] gets transformed if necessary.
 * E.g., Ajax Views rewrites the q parameter.
 *
 * @return string
 */
function themekey_get_q() {
  static $get_q = '';
  if (empty($get_q)) {
    if ('views/ajax' == $_GET['q'] && !empty($_GET['view_path'])) {

      // required for ajax views. see http://drupal.org/node/567222
      $get_q = $_GET['view_path'];
    }
    else {
      $get_q = $_GET['q'];
    }
  }
  return $get_q;
}

/**
 * Implements hook_cron().
 */
function themekey_cron() {
  if (variable_get('themekey_cron_page_cache', 1)) {
    module_load_include('inc', 'themekey', 'themekey_cron');
    themekey_cron_clear_page_cache();
  }
}

Functions

Namesort descending Description
themekey_cron Implements hook_cron().
themekey_footer Implements hook_footer().
themekey_get_q Returns the content of $_GET['q'] as expected. Therefore, $_GET['q'] gets transformed if necessary. E.g., Ajax Views rewrites the q parameter.
themekey_help Implements hook_help().
themekey_init Implements hook_init().
themekey_menu Implements hook_menu().
themekey_perm Implements hook_perm().
themekey_set_debug_message Replacement for drupal_set_message() during ThemeKey's initialization. drupal_set_message() might call init_theme() too early, which causes ThemeKey to not switch the theme.
themekey_theme Implements hook_theme().
themekey_themekey_load_validators Implements hook_themekey_load_validators().

Constants

Namesort descending Description
THEMEKEY_PAGECACHE_SUPPORTED
THEMEKEY_PAGECACHE_TIMEBASED
THEMEKEY_PAGECACHE_UNSUPPORTED @file ThemeKey is designed as a generic theme switching module.