43

I have a Drupal instance running on example.org. Which has a theme X installed and activated. Now for a limited period an event is supposed to be held on the site for which a special section has been "carved out." All the things related to that event will go to example.org/event2011.

I want to have a different theme to be shown whenever a page under this section is viewed (e.g. http://example.org/event2011/about, http://example.org/event2011/node/123). How do I do that?

I have gone through many modules, but none of them is supporting Drupal 7. Preferably, I would like it to be done using modules and don't want to change anything my self at the code level.

0

9 Answers 9

33

Since the change is for a limited period of time, and implementing it isn't much difficult, I would suggest to create a custom module, or add the code to change the theme used for specific pages in an existing, suitable, custom module.

It is enough to implement hook_custom_theme(), for example using the following code.

function mymodule_custom_theme() {
  if (arg(0) == 'event2011') {
    return 'the theme to use for that page';
  }
}

If the theme must be changed for http://example.com/event2011, but not for http://example.com/event2011/node/123, code similar to the following one could be used.

function mymodule_custom_theme() {
  if (arg(0) == 'event2011' && !arg(1)) {
    return 'the theme to use for that page';
  }
}

As for using theme callbacks in a menu callback definition, the documentation says:

As a general rule, the use of theme callback functions should be limited to pages whose functionality is very closely tied to a particular theme, since they can only be overridden by modules which specifically target those pages in hook_menu_alter(). Modules implementing more generic theme switching functionality (for example, a module which allows the theme to be set dynamically based on the current user's role) should use hook_custom_theme() instead.

1
24

A custom solution like the other comment suggests is probably best, but if you really want to use a module, your best bet is ThemeKey. As of 5/23/11, it has a stable release.

9

Alternatively you can use the new theme callback option of the menu system hook_menu_alter() as outlined below. p.s Checkout hook_menu() for more details on the theme callback

<?php
/**
* Implements hook_menu_alter().
*/
function mymodule_menu_alter(&$items) {
  // Set the theme callback function for all node pages. As per the
  // standard behavior for hook_menu() properties, this will be
  // inherited by all paths underneath node/%node as well, unless
  // they define their own theme callback.
  $items['node/%node']['theme callback'] = 'mymodule_default_node_theme';

  // Set a different theme callback for node edit pages, and pass
  // along the node object to this function so we can make decisions
  // based on it.
  $items['node/%node/edit']['theme callback'] = 'mymodule_edit_node_theme';
  $items['node/%node/edit']['theme arguments'] = array(1);
}
/**
* Defaults to using the 'some_theme' theme for node pages.
*/
function mymodule_default_node_theme() {
  return 'some_theme';
}

/**
* For editing page nodes, uses the 'some_other_theme' theme.
*/
function mymodule_edit_node_theme($node) {
  return $node->type == 'page' ? 'some_other_theme' : mymodule_default_node_theme();
}
?>

Additionally there is also an example of using the more traditional hook_custom_theme()

<?php 
/**
* Implements hook_custom_theme().
*/
function mymodule_custom_theme() {
  // check path using arg(0)
  // check $user
  // do whatever special checking you want and simply return theme key (name of theme folder most of the time)
    return 'special_theme';
  }
}
?>

Taken from: http://drupal.org/node/224333#custom_theme

7

You can simply use Context and use the theme to get applied when the path is /event2011/ you can simple set the path in condition of cotext and change the theme in the action of the content. This was you can very easily switch between themes on a site based on URL. Even works for mobiles ;)

1
  • the theme action passes custom variables to the theme, it doesn't actually change it
    – Alex Weber
    Commented May 6, 2011 at 19:55
7

Using ThemeKey is simple and it's the most popular and powerful module so far (with support for 8.x) for theme switching rules which allow automatic selection of a theme depending on current path, taxonomy terms, language, node-type, and many, many other properties. It can also be easily extended to support additional properties exposed by other modules. Beside the standard features ThemeKey automatically extends it's features of many contrib modules and has modules extending it.

Usage (7.x)

After enabling module, go to admin/config/user-interface/themekey. There are many options for switching the theme, but probably you would be interested with path:node_alias, so set the value as you want like you say /my_url and then select the theme you want to enable at this url. You can also use wildcards such as web/* or /^web/.*.

Check: How Load a Theme For Path

Advanced usage

ThemeKey 7.x contains an optional module called ThemeKey Example to demonstrate developers how to extend ThemeKey.

Help (7.x)

Check out video tutorial by Mustardseed (7.x).

More help on that topic can be found at /admin/help/themekey.

Also check other SE questions related to .


Alternatively there is also Switchtheme (7.x) which adds a block to allow users to switch between enabled themes.

6

When using URL aliases or the Pathauto module, be aware of the subtleties and differences when using components of the current Drupal path.

There are situations where you may not want to use arg(). In fact, the Drupal API documentation actually suggests avoiding use of this function where possible, as resulting code is hard to read.

Consider the following example, as proposed by kiamlaluno:

function mymodule_custom_theme() {
  if (arg(0) == 'event2011') {
    return 'custom_theme_machine_name';
  }
}

In Drupal 7, if a node has an alias of event2011, using arg(0) will return node as the first URL component, as opposed to the alias.

print_r(arg(0));

Array
(
    [0] => node
    [1] => 150
)

Instead, if you need to work with an alias there are several ways to get the current URL in Drupal, including menu_get_object(), current_path(), request_path() and others.

Here's a re-worked example that uses an alias as a trigger for switching the theme:

function mymodule_custom_theme() {
  $current_page_path = explode('/', request_path());      

  if ($current_page_path[0] == 'event2011') {
    return 'custom_theme_machine_name';
  }
}
3

How to switch theme depending on user role:

Create a custom module and copy & paste the following:

<?php
/**
 * Implementation of hook_init().
 */
function mymodule_init() {
  global $custom_theme, $user;
  if (in_array('my special role', $user->roles)) {
    $custom_theme = 'mytheme';
  }
}
?>

You have to replace:

mymodule => with your module name

my special role => with the name of the role that your users will need to have in order for them to see a different theme.

mytheme => with the name of the theme that you want to switch to

2

You could use the Page Theme module to achieve exactly that

The Page Theme module is a simple and easy module to use which allows to use different themes than the site default on specific pages.

Features

  • Assign a theme to a single page or list of pages. (Set a page as a Drupal path)
  • Allow to use '*' character as a wildcard in Drupal paths.
  • Allow to arrange themes. (If pages are several defined, the first theme in the list will be used)
  • Allow to enable/disable a theme.
  • Drupal novice friendly.
1

If you want to use a theme that is different from the theme site default on content creating, editing, and viewing pages you can use the Content Theme module.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.