Template Suggestions in Drupal 7

One of the changes developers need to be aware of in Drupal 7 is the change to how template suggestions are made. The first thing to know is that the template_files key in preprocess functions has been replaced by theme_hook_suggestions. The guide for converting 6.x modules to 7.x covers this change. But there have also been other alterations to the way Drupal finds templates.

Chris Johnson, VP of Engineering
#Drupal | Posted

One of the changes developers need to be aware of in Drupal 7 is the change to how template suggestions are made. The first thing to know is that the template_files key in preprocess functions has been replaced by theme_hook_suggestions. The guide for converting 6.x modules to 7.x covers this change. But there have also been other alterations to the way Drupal finds templates.

In Drupal 6 you could implement a hook_theme_registry_alter and specify additional directories to search for template implementations. This was done by appending directories to the 'theme paths' key. This was very useful when your module defined a new content type and wanted to provide a default implementation. In Drupal 7, you need to register your template implementation under a theme key that will be checked after preprocessing is done. This is easier to understand after looking at the theme function's processing order.

Assume the theme function is called like so, theme('node'). A variety of checks are done to ensure everything is initialized correctly and that a theme registry entry exists for the key 'node'. It does and was provided by the node_theme implementation in node.module. After some additional checks the preprocess and process functions are run and additional template suggestions are collected. At this point a theme key you've registered has the opportunity to insert itself in the process. The template suggestions are checked to see if they represent other registered theme implementations and if so, the info for that registered implementation is used instead of the original one. From the comments in the theme function

  1. // If the preprocess/process functions specified hook suggestions, and the
  2. // suggestion exists in the theme registry, use it instead of the hook that
  3. // theme() was called with. This allows the preprocess/process step to
  4. // route to a more specific theme hook. For example, a function may call
  5. // theme('node', ...), but a preprocess function can add 'node__article' as
  6. // a suggestion, enabling a theme to have an alternate template file for
  7. // article nodes. Suggestions are checked in the following order:
  8. // - The 'theme_hook_suggestion' variable is checked first. It overrides
  9. // all others.
  10. // - The 'theme_hook_suggestions' variable is checked in FILO order, so the
  11. // last suggestion added to the array takes precedence over suggestions
  12. // added earlier.

Since you can register a path to use when returning data from a hook_theme implementation, you are able to have your module's directory checked for a default template implementation. Of course, if a template is provided in a theme the user's template will still take priority.

A module defining a new node type and default template implementation would look something like this

  1. function nodemod_theme($existing, $type, $theme, $path) {
  2. return array(
  3. 'node__nodemod' => array(
  4. 'render element' => 'elements',
  5. 'path' => drupal_get_path('module', 'nodemod') . '/theme',
  6. 'template' => 'node--nodemod',
  7. ),
  8. );
  9. }
  10.  
  11. function nodemod_node_info() {
  12. $type = array(
  13. 'nodemod' => array(
  14. 'name' => 'Nodemod type',
  15. 'base' => 'nodemod',
  16. 'description' => 'A new node type illustrating how to make sure node--nodemod.tpl.php is used',
  17. ),
  18. );
  19. return $type;
  20. }

[/php]

The above code will cause the theme function to look in the theme subdirectory of the nodemod module directory for a template called node--nodemod.tpl.php. The theme function will do this because the key node__nodemod matches what the node template returns as a template suggestion, 'node__' . $node->type, and the type of node provided by our module's node_info hook is nodemod.

For more information on Drupal 6 template suggestions check out the post Drupal 6 Theming for Module Developers - Suggesting TPLs from a module

Check out other Drupal 7 information in the following posts

* Lessons Learned in Upgrading to Drupal 7: API to Theming
* New in Drupal 7 for developers (Part 1)
* New in Drupal 7 for developers (Part 2)

Chris Johnson

VP of Engineering