 [ ← blog / drupal ](/) Apr 11, 2014  ·  \#drupal  ·  3 min read 

# Changing the Drupal theme based on path



When using Drupal we all know there are two themes: default and administrative. By having two different themes site managers have a better user experience by knowing "this is public," and "this is administrative." It also proves beneficial to have specific administration themes due to the kinds of content and forms that a site manager has to interface with. Drupal does provide the option of letting site builders decide if adding or editing a node takes place in the default theme or the administrative theme.

Chances are, at least in all of my cases, you have "Use the administrative theme when editing or creating content" checked. There's just one drawback: what if one specific node (or other entity for that matter) should be edited through the default theme?

A recent project utilized a simplistic forum, so I enabled Drupal core's Forum module. Forum is built on nodes and terms, which means editing and creating forum nodes will fall within the administrative theme. Regular users may not have "View the administration theme" permission, but what about site administrators? Just because a user has elevated permissions does not mean his or her user experience should have deteriorated. Luckily Drupal's menu subsystem defines the theme used per path. Using *hook\_menu\_get\_item\_alter()* there is a way to modify the theme callback and change a path's theme.

```php
/**
 * Implements hook_menu_get_item_alter().
 */
function mymodule_menu_get_item_alter(&$router_item, $path, $original_map) {
  if ($router_item['path'] == 'node/add/forum') {
    $router_item['theme_callback'] = 'mymodule_menu_theme_callback'; 
  } 
} 

function mymodule_menu_theme_callback() { return 'default_theme'; }
```

I do want to note that there is `<a href="https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_custom_theme/7">hook_custom_theme()</a>`*.* For those who haven't heard of it, you've been saved some heartache. For those who have, I feel your pain. Inspecting this snippet from `menu.inc` you can see `hook_custom_theme()` is **always** overridden if menu\_get\_item() returns an actual callback function.

```php
    /**
     * Excerpt from menu.inc
     * Lines 1745-1755
     */
  
    // First allow modules to dynamically set a custom theme for the current
    // page. Since we can only have one, the last module to return a valid
    // theme takes precedence.
    $custom_themes = array_filter(module_invoke_all('custom_theme'), 'drupal_theme_access');
    if (!empty($custom_themes)) {
      $custom_theme = array_pop($custom_themes);
    }
    // If there is a theme callback function for the current page, execute it.
    // If this returns a valid theme, it will override any theme that was set
    // by a hook_custom_theme() implementation above.
    $router_item = menu_get_item();
```

The proofs in the code, which makes me wonder why it is even there. Regardless using *hook\_custom\_theme()* over *hook\_menu\_get\_item\_alter()* provides more reliable results

 

  ![](/themes/custom/mglaman/images/headshot.webp)Thanks for reading

I write about Drupal, PHP, and the quiet infrastructure behind large sites — caching, config, and testing. New posts land every week or two.

 [Subscribe via RSS →](/rss.xml) [About me →](/about-me) 

 



 

  [← Older

An Open Microsoft: Microsoft to open-source more of .Net

 ](/blog/open-microsoft-microsoft-open-source-more-net) [Newer →

Making Drupal compatible with Internet Explorer's Compatibility Mode

 ](/blog/making-drupal-compatible-internet-explorers-compatibility-mode)