The module uses variable_set('theme_default', $theme_name); to set the theme to display, but this affects the site default (radio button on admin/build/themes). Instead, the module should set the theme for the current user, for the current session or page view. (Since the code is called on each page view, it is acceptable to set the theme on each page load.)

Comments

tronathan’s picture

I'm not sure how to set the theme for a given page load or session - I cant find any documentation about this. Does anyone have information about how to tell drupal what theme to use for a given user or page load?

tronathan’s picture

I should be able to look at how this module does theme switching:

http://drupal.org/project/role_theme_switcher

tronathan’s picture

Status: Active » Needs review

I updated the code to the following:

function context_theme_context_page_reaction() {
  $theme_names = context_active_values('context_theme');
  if (!empty($theme_names)) {
    $theme_name = $theme_names[0];
    global $user, $custom_theme, $theme_info;

    // Change active theme in user object
    $user->theme = $theme_name;
    // Also change the active theme globally
    $custom_theme = $theme_name;
<b>
    // unset the current theme to force a rebuild
    unset($GLOBALS['theme']);
</b>  }
  return;
}

According to init_theme(), if the theme object is set, it will be returned. We need to force a rebuild of the theme before render since it has already been built by the time this method is called. Using php unset() on a global doesnt work outside of the scope of the function, so I unset it from the globals array.

Is this the correct way to force a theme rebuild in code?

fatfish’s picture

when unsetting the GLOBAL themes I get

warning: array_map() [function.array-map]: Argument #2 should be an array in /home/virtual/mymedia/public_html/atrium-1-0-b/modules/system/system.module on line 966.
warning: array_keys() [function.array-keys]: The first argument should be an array in /home/virtual/mymedia/public_html/atrium-1-0-b/includes/theme.inc on line 1771.
warning: Invalid argument supplied for foreach() in /home/virtual/mymedia/public_html/atrium-1-0-b/includes/theme.inc on line 1771.

When I comment it out the ERROR disapear.
In both cases - themes are not switched.

tronathan’s picture

Priority: Normal » Critical

I looked at this in some detail and discovered the following about drupals bootstrap process:

1) Drupal calls all of the module _init functions
2) The template engine is initialized
3) Template engine includes a file using include(templatename/template.php)
4) Context reaction hook fires

The template system uses static variables and includes, things which can't be "undone" or "reset" to use the new theme. The problem is that we need to set the theme before the template engine is initialized.

I tried adjusting system module wieghts but to no avail.

This would work if our theme switching happened in _init() as it does with Role Theme Switcher http://drupal.org/project/role_theme_switcher .

It may be happening because Context loads block information, which requires knowing about regions, which requires knowing about the template.

Can the context module be modified to fire the theme hook sooner, or can the block loading happen later or optionally?

tronathan’s picture

Assigned: tronathan » Unassigned
Category: bug » support

Does anyone know if its possible to set the drupal theme during a hook_context_page_reaction() hook (context_theme_context_page_reaction() in this case)

Is this possible?

Note that this method is very poorly documented right now, and isn't listed at http://drupalcontrib.org/api/search/6/context?

tronathan’s picture

Crossposted to Context module at: http://drupal.org/node/580940

geraud’s picture

Why not use Subsites module for that ? (http://drupal.org/project/subsites)
Subsites can have their own theme and can be a condition in the context module.

sinasalek’s picture

http://drupal.org/project/themekey is another good example