How to theme at a module level

There is a little known hook in Drupal called hook_theme_registry_alter. Here’s why you probably haven’t heard of it: It was largely undocumented until Drupal 7 came out.

Why? Probably oversight by the community as a whole but I think because of how powerful and potentially evil it can be. It allows modules to modify the way that Drupal understands theming. This allows you to effectively ignore how Drupal wants to render the page and tell it to use different code for certain aspects of your site.

Here are some use-cases

You want nodes of type xyz to ALWAYS render a certain way regardless of theme You want to package a view with a Features module and always have it render a certain way You want to override the way Drupal handles one aspect of the page render You generally want to confuse other developers that didn’t realize you did it ELMS is implementing this hook in the next release so I felt it was a good idea to explain how / why I’m using this hook (cause it can be very confusing). Basically, when you build a theme you make a file for each aspect of Drupal that you want to render differently. Pages, Nodes, Blocks and what not all have a base template that Drupal will use if you don’t include it.

What this hook allows you to do is hijack where Drupal looks for code. So, even if a theme says to change the book navigation, Drupal will ignore the theme’s code and use your module-theme code. This can get very confusing for people wanting to know “how did they make it look that way!” so here’s a break down.

Use case: Make book navigation render the exact same way in ELMS, regardless of what theme might be implemented.

This is how book navigation looks in ELMS. Instead of a previous, up, and next links on book pages, we have a jump menu. I always want this to take priority over how the theme says it should look so I use my friend hook_theme_registry_alter like so.

/** * Implementation of (undocumented) hook_theme_registry_alter(). */ function elms_helper_theme_registry_alter(&$vars) {   //make book navigation function with a jump menu   $vars[‘book_navigation’][‘theme path’] = drupal_get_path(‘module’,’elms_helper’);   $vars[‘book_navigation’][‘path’] = drupal_get_path(‘module’,’elms_helper’);   $vars[‘book_navigation’][‘theme paths’] = array(0 => drupal_get_path(‘module’,’elms_helper’)); }

So what is this saying? You can learn a lot more about this by doing a print_r($vars); in this function but here’s the gist of it. $vars[‘book_navigation’][‘theme path’] – the path to the theme to find the book-navigation. tpl.php, we say that it’s actually inside our module directory $vars[‘book_navigation’][‘path’] – same thing, where to look for the file, we say our module $vars[‘book_navigation’][‘theme paths’] – redundant but yes, look in our module for the file

The last one is the critical one though because theme paths can contain multiple values (0 usually being Drupal’s core handling, then 1 being the theme’s way of rendering). Now, in elms_helper’s module directory I include the book-navigation. tpl.php and the trick is implemented.

This is also really useful for theming views across themes but that example is far more complicated. I’ve also included the book-navigation. tpl.php file that is able to render the navigation with a jump menu. Adding it to your theme should render the navigation with a jump menu (test it first as I ported it from ELMS core code).