What is the correct way to change the active Drupal theme programmatically?
6 Answers
Drupal 6 solution:
You want to make sure you change the global $custom_theme
variable fairly early in page execution.
global $custom_theme;
$custom_theme = 'garland';
-
A couple of hooks to try that are very early in page execution (if you're using a custom module) are hook_boot() and hook_init(). Mar 18, 2011 at 4:52
-
where is
$custom_theme
defined? is it enough for changing theme? Jun 10, 2012 at 16:59 -
2Please, mention
hook_custom_theme
api.drupal.org/api/drupal/modules%21system%21system.api.php/… Dec 1, 2012 at 15:47 -
1
-
I know you asked how to do it programattically, but in case that's your solution, not the actual problem, you can also use the ThemeKey module. This allows you to set conditions which, when met, changes the theme. You can make conditions based on paths, taxonomy, content type, create or edit date and more. You can also add in the Themekey Properties module module to get even more options.
Again, I know this isn't programmattically, but I'm not sure if the real question behind your question is how to change themes based on conditions.
-
4Yeah if you want to manage this through the UI, I'd recommend ThemeKey. Mar 3, 2011 at 1:56
-
Or at least checkout drupalcode.org/project/themekey.git/blob/refs/heads/7.x-2.x:/… where ThemeKey does its magic Dec 1, 2012 at 15:48
-
@Chaulky is right : I'm using ThemeKey since a while, it is the easiest way to manage theming customisations upon user name, role, page, whatever you want. I recommend it.– BenjNov 12, 2014 at 19:16
The best way to do this is to create an update hook in a module:
function yourmodule_update_N() {
variable_set('theme_default','yourtheme');
}
-
-
This would only be correct if you wanted to change the theme globally. I had assumed from the question that the OP wanted to change the theme on a particular page, or in a particular context. Mar 20, 2017 at 20:57
Changing the active theme via Drush
drush vset theme_default garland
drush vset admin_theme garland
drush cc all
Changing the active theme via a module
The basics of changing the default theme and administration theme:
// Changes the theme to Garland
variable_set('theme_default', $theme_default);
// Changes the administration theme to Garland
variable_set('admin_theme', $admin_theme);
Here's a small function to set back the themes safely to default Drupal themes like Bartik or Garland (tested in Drupal 6 and 7):
/**
* Set the active Drupal themes (the default and the administration theme) to default ones.
* Tested in Drupal 6, 7 (but possibly working in version 8 too according to the documentations [some similarities between 7 and 8]).
*/
function TESTMODULE_set_active_theme_to_default($affect_admin_theme = TRUE) {
// Provides a list of currently available themes.
$list_themes = list_themes(TRUE);
// 6, 7, 8, etc.
$major_version = (int)VERSION;
$theme_default = isset($list_themes['bartik']) ? 'bartik' : 'garland';
$admin_theme = isset($list_themes['seven']) ? 'seven' : 'garland';
// Changes the theme to Garland
variable_set('theme_default', $theme_default);
// Changes the administration theme to Garland if argument is TRUE
if($affect_admin_theme){
variable_set('admin_theme', $admin_theme);
}
// if Switchtheme module (https://drupal.org/project/switchtheme) is enabled, use it
if (module_exists('switchtheme')) {
if (empty($_GET['theme']) || $_GET['theme'] !== $theme_default) {
$query = array(
'theme' => $theme_default
);
// in D6, drupal_goto's second argument is the query string,
// in >=D7, a more general $options array is used
if($major_version < 7){
$options = $query;
}
else{
$options = array('query' => $query);
}
drupal_goto($_GET['q'], $options);
}
}
drupal_set_message(t('Default theme has been changed to %theme_default, administration theme has been changed to %admin_theme.', array(
'%theme_default' => $theme_default,
'%admin_theme' => $admin_theme
)));
}
You can call it in a hook_init() implementation (comment it out after it's not needed):
/**
* Implements hook_init()
*/
function TESTMODULE_init() {
// ATTENTION! Comment out the following line if it's not needed anymore!
TESTMODULE_set_active_theme_to_default();
}
-
This is also the method you would use when enabling a theme in an install profile
variable_set('theme_default','yourtheme');
Mar 6, 2015 at 6:57
In Drupal 7, use hook_custom_theme()
:
/**
* Implements hook_custom_theme()
* Switch theme for a mobile browser
* @return string The theme to use
*/
function mymodule_custom_theme() {
//dpm($_SERVER['HTTP_USER_AGENT']);
$theme = 'bartik'; // core theme, used as fallback
$themes_available = list_themes(); // get available themes
if (preg_match("/Mobile|Android|BlackBerry|iPhone|Windows Phone/", $_SERVER['HTTP_USER_AGENT'])) {
if (array_key_exists('custommobiletheme', $themes_available)) $theme = 'custommobiletheme';
else { drupal_set_message("Unable to switch to mobile theme, because it is not installed.", 'warning'); }
}
else if (array_key_exists('nonmobiletheme', $themes_available)) $theme = 'nonmobiletheme';
// else, fall back to bartik
return $theme;
}
Adapted from <emoticode />
Return the machine-readable name of the theme to use for the current page.
The comments for this function may be worth reading:
This hook can be used to dynamically set the theme for the current page request. It should be used by modules which need to override the theme based on dynamic conditions (for example, a module which allows the theme to be set based on the current user's role). The return value of this hook will be used on all pages except those which have a valid per-page or per-section theme set via a theme callback function in hook_menu(); the themes on those pages can only be overridden using hook_menu_alter().
Note that returning different themes for the same path may not work with page caching. This is most likely to be a problem if an anonymous user on a given path could have different themes returned under different conditions.
Since only one theme can be used at a time, the last (i.e., highest weighted) module which returns a valid theme name from this hook will prevail.
For Drupal 8:
In settings.php
$config['system.theme']['default'] = 'my_custom_theme';
Update config programatically:
\Drupal::configFactory()
->getEditable('system.theme')
->set('default', 'my_custom_theme')
->save();