1

I'm trying to change the theme in code in drupal7. hook_custom_theme is too early since I need spaces_init to have happened already. The themekey module uses custom_theme so that's out.

The only method I've found so far is to change the theme callback using menu_alter. What other options are there?

2 Answers 2

4
+50

Both hook_custom_theme() and hook_init() are invoked from _drupal_bootstrap_full(), which contains the following code.

menu_set_custom_theme();   // It invokes hook_custom_theme(). 
drupal_theme_initialize();
module_invoke_all('init');

The reason of the order is explained in the comment before that code, which says:

Prior to invoking hook_init(), initialize the theme (potentially a custom one for this page), so that:

  • Modules with hook_init() implementations that call theme() or theme_get_registry() don't initialize the incorrect theme.
  • The theme can have hook_*_alter() implementations affect page building (e.g., hook_form_alter(), hook_node_view_alter(), hook_page_alter()), ahead of when rendering starts.

It seems that your situation is a circular-reference situation, where an implementation of hook_custom_theme() depends from hook_init(), and an implementation of hook_init() could depend from the value returned from hook_custom_theme().

If you are sure that the result of hook_custom_theme() doesn't influence the code of spaces_init(), which doesn't need the theme to be initialized, then you could invoke spaces_init() in your hook_custom_theme() using module_invoke('spaces', 'init'), but that sounds like a hack, and subject of problems if spaces_init() is changed, and it actually needs a theme to be initialized before being executed.

2
  • So far so good on running spaces_init early (although I had to do purl_init instead since spaces didn't work without purl). Still testing though and I won't be surprised if something is a little off.
    – valadil
    Commented Jun 4, 2012 at 17:00
  • Went with this one. Also added a hook_module_implements_alter to prevent spaces from running init again.
    – valadil
    Commented Jun 5, 2012 at 19:09
2

Implementations of hook_custom_theme() are only invoked from menu_get_custom_theme(). The theme callback set for the current menu item is invoked right after the hook_custom_theme() implementations. So if your hook_custom_theme() implementation is invoked too early, the theme callback for your page will also be invoked too early.

These seems to be the only safe ways to change the theme used on the page.

Having drupal_theme_initialize (which is what invoke menu_get_custom_theme()) invoked before implementation of hook_init() (such as spaces_init()) doesn't seems right. The theme should not be initialized so early. Unless a theme initializing function (such as theme()) is invoked in an hook_init() or hook_boot() implementation.

I would check if any of the hook_init() on your site initialize the theme. If one does, try changing the modules' weight or hook_modules_implements_alter() to ensure spaces_init() is invoked before. This should allow your hook_custom_theme() implementation to rely on spaces_init().

2
  • In common.inc drupal_theme_initialize() is run immediately before module_invoke_all('init'). I don't think I can delay hook_custom_theme till after init without modifying core. To clarify, I don't mind setting the theme earlier, I just need to have spaces initialized. Running purl_init during my custom_theme hook is working so far. Still looking for problems with that approach though.
    – valadil
    Commented Jun 4, 2012 at 14:56
  • Right, I missed the call to drupal_theme_initialize() in _drupal_bootstrap_full(). Try kiamlaluno's and invoke spaces_init() from your hook_custom_theme(). Commented Jun 4, 2012 at 15:36

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.