Community Documentation

hook_theme

6 core.php hook_theme($existing, $type, $theme, $path)
7 system.api.php hook_theme($existing, $type, $theme, $path)
8 system.api.php hook_theme($existing, $type, $theme, $path)

Register a module (or theme's) theme implementations.

Modules and themes implementing this hook return an array of arrays. The key to each sub-array is the internal name of the hook, and the array contains information about the hook. Each array may contain the following elements:

  • arguments: (required) An array of arguments that this theme hook uses. This value allows the theme layer to properly utilize templates. The array keys represent the name of the variable, and the value will be used as the default value if not passed to the theme() function. These arguments must be in the same order that they will be given to the theme() function. Default values will only be passed to templates. If you want your theme function to assume defaults, specify them as usual in the argument list in the theme_HOOK_NAME() default implementation.
  • file: The file the implementation resides in. This file will be included prior to the theme being rendered, to make sure that the function or preprocess function (as needed) is actually loaded; this makes it possible to split theme functions out into separate files quite easily.
  • path: Override the path of the file to be used. Ordinarily the module or theme path will be used, but if the file will not be in the default path, include it here. This path should be relative to the Drupal root directory.
  • template: If specified, this theme implementation is a template, and this is the template file without an extension. Do not put .tpl.php on this file; that extension will be added automatically by the default rendering engine (which is PHPTemplate). If 'path', above, is specified, the template should also be in this path.
  • function: If specified, this will be the function name to invoke for this implementation. If neither 'template' nor 'function' is specified, a default function name will be assumed. For example, if a module registers the 'node' theme hook, 'theme_node' will be assigned to its function. If the chameleon theme registers the node hook, it will be assigned 'chameleon_node' as its function.
  • pattern: A regular expression pattern to be used to allow this theme implementation to have a dynamic name. The convention is to use __ to differentiate the dynamic portion of the theme. For example, to allow forums to be themed individually, the pattern might be: 'forum__'. Then, when the forum is themed, call: theme(array('forum__'. $tid, 'forum'), $forum).
  • preprocess functions: A list of functions used to preprocess this data. Ordinarily this won't be used; it's automatically filled in. By default, for a module this will be filled in as template_preprocess_HOOK. For a theme this will be filled in as phptemplate_preprocess and phptemplate_preprocess_HOOK as well as themename_preprocess and themename_preprocess_HOOK.
  • override preprocess functions: Set to TRUE when a theme does NOT want the standard preprocess functions to run. This can be used to give a theme FULL control over how variables are set. For example, if a theme wants total control over how certain variables in the page.tpl.php are set, this can be set to true. Please keep in mind that when this is use by a theme, that theme becomes responsible for making sure necessary variables are set.
  • type: (automatically derived) Where the theme hook is defined: 'module', 'theme_engine', or 'theme'.
  • theme path: (automatically derived) The directory path of the theme or module, so that it doesn't need to be looked up.
  • theme paths: (automatically derived) An array of template suggestions where .tpl.php files related to this theme hook may be found.

The following parameters are all optional.

Parameters

$existing: An array of existing implementations that may be used for override purposes. This is primarily useful for themes that may wish to examine existing implementations to extract data (such as arguments) so that it may properly register its own, higher priority implementations.

$type: What 'type' is being processed. This is primarily useful so that themes tell if they are the actual theme being called or a parent theme. May be one of:

  • module: A module is being checked for theme implementations.
  • base_theme_engine: A theme engine is being checked for a theme which is a parent of the actual theme being used.
  • theme_engine: A theme engine is being checked for the actual theme being used.
  • base_theme: A base theme is being checked for theme implementations.
  • theme: The actual theme in use is being checked.

$theme: The actual name of theme that is being being checked (mostly only useful for theme engine).

$path: The directory path of the theme or module, so that it doesn't need to be looked up.

Return value

A keyed array of theme hooks.

Related topics

▾ 32 functions implement hook_theme()

$custom_theme in developer/globals.php
Name of custom theme to override default theme.
aggregator_theme in modules/aggregator/aggregator.module
Implementation of hook_theme()
block_theme in modules/block/block.module
Implementation of hook_theme()
book_theme in modules/book/book.module
Implementation of hook_theme()
chameleon.theme in themes/chameleon/chameleon.theme
A slim, CSS-driven theme which does not depend on a template engine like phptemplate
chameleon_theme in themes/chameleon/chameleon.theme
Implementation of hook_theme. Auto-discover theme functions.
color_theme in modules/color/color.module
Implementation of hook_theme().
comment_theme in modules/comment/comment.module
Implementation of hook_theme().
dblog_theme in modules/dblog/dblog.module
Implementation of hook_theme()
drupal_common_theme in includes/common.inc
Provide theme registration for themes across .inc files.
drupal_maintenance_theme in includes/bootstrap.inc
Enables use of the theme system without requiring database access.
filter_theme in modules/filter/filter.module
Implementation of hook_theme()
forum_theme in modules/forum/forum.module
Implementation of hook_theme()
init_theme in includes/theme.inc
Initialize the theme system by loading the theme.
locale_theme in modules/locale/locale.module
Implementation of hook_theme()
menu_theme in modules/menu/menu.module
Implemenation of hook_theme().
node_theme in modules/node/node.module
Implementation of hook_theme()
path_to_theme in includes/theme.inc
Return the path to the current themed element.
phptemplate_theme in themes/engines/phptemplate/phptemplate.engine
Implementation of hook_theme().
poll_theme in modules/poll/poll.module
Implementation of hook_theme()
profile_theme in modules/profile/profile.module
Implementation of hook_theme()
search_theme in modules/search/search.module
Implementation of hook_theme()
syslog_theme in modules/syslog/syslog.module
system_find_base_theme in modules/system/system.module
This function has been deprecated in favor of system_find_base_themes().
system_theme in modules/system/system.module
Implementation of hook_theme().
taxonomy_theme in modules/taxonomy/taxonomy.module
Implementation of hook_theme().
trigger_theme in modules/trigger/trigger.module
Implementation of hook_theme().
update_theme in modules/update/update.module
Implementation of the hook_theme() registry.
upload_theme in modules/upload/upload.module
Implementation of hook_theme()
user_theme in modules/user/user.module
Implementation of hook_theme().
_drupal_maintenance_theme in includes/theme.maintenance.inc
Sets up the theming system for site installs, updates and when the site is in off-line mode. It also applies when the database is unavailable.
_init_theme in includes/theme.inc
Initialize the theme system given already loaded information. This function is useful to initialize a theme when no database is present.

File

developer/hooks/core.php, line 2141
These are the hooks that are invoked by the Drupal core.

Code

<?php
function hook_theme($existing, $type, $theme, $path) {
  return array(
    'forum_display' => array(
      'arguments' => array('forums' => NULL, 'topics' => NULL, 'parents' => NULL, 'tid' => NULL, 'sortby' => NULL, 'forum_per_page' => NULL),
    ), 
    'forum_list' => array(
      'arguments' => array('forums' => NULL, 'parents' => NULL, 'tid' => NULL),
    ), 
    'forum_topic_list' => array(
      'arguments' => array('tid' => NULL, 'topics' => NULL, 'sortby' => NULL, 'forum_per_page' => NULL),
    ), 
    'forum_icon' => array(
      'arguments' => array('new_posts' => NULL, 'num_posts' => 0, 'comment_mode' => 0, 'sticky' => 0),
    ), 
    'forum_topic_navigation' => array(
      'arguments' => array('node' => NULL),
    ), 
    'node' => array(
      'arguments' => array('node' => NULL, 'teaser' => FALSE, 'page' => FALSE), 
      'template' => 'node',
    ), 
    'node_filter_form' => array(
      'arguments' => array('form' => NULL), 
      'file' => 'node.admin.inc',
    ),
  );
}
?>

Comments

WSOD

If you do something like this:

<?php
function test_theme($existing, $type, $theme, $path) {
 
drupal_set_message("<pre>".print_r($existing,true)."</pre>");
}
?>

You will (potentially) get a White Screen of Death (WSOD).

Remember to return, at the very least, an empty array:

<?php
function test_theme($existing, $type, $theme, $path) {
 
drupal_set_message("<pre>".print_r($existing,true)."</pre>");
  return array();
}
?>

And if the WSOD happens to you...

Try a regular /update.php to remedy it.

if trying to include a template from a subfolder in your module

you may not need to use the path argument of the hook_theme(), instead you can just prefix the value of the template string with the name of the subfolder in your module folder that contains the template

'template' => 'templates/mymoduletemplate' ,
etc...

that has allowed me to keep my folders cleaner

if you want to use the path argument, you can use
drupal_get_path('module', $module_name);
to get the path to the folder of your module, and then suffix the fodler that will contain your templates

this can also be helpful to break apart large modules into subfolders for better organziation, and use them as includes in your code.

Be careful

Be careful. I dont' think this will work if a theme tries to override your module's template since it will look for a templates directory within the theme.

'arguments' array only used for template files.

Just wanted to throw this out there so other people don't run into the same problem I did.

The default argument defined in by 'arguments' aren't used when functions are called.

So say you have this

<?php
function HOOK_theme(...) { ... $hooks['reminder'] = array('arguments' => array('reminder_color' => 'blue')); ...}

function
HOOK_reminder($reminder_color) {... print $reminder_color; ...}

function
foo(...) {... theme('reminder') ...} //will not print 'blue', will throw an error - too few arguments
function bar(...) {... theme('reminder', NULL) ...} //will not print 'blue'
?>

BUT, if you were in reminder.tpl.php then

<?php
print $reminder_color; //prints 'blue'
?>

----------------

To see why read through the theme() function and pay special attention to these variables: $info['arguments'], $info['function'], $info['template']

The way to catch both

The way to catch both instances is to also use argument defaults in your theme function:

<?php
function HOOK_reminder($reminder_color = 'blue') {... print $reminder_color; ...}
?>

Yeah, this just happened to

Yeah, this just happened to me. Now I have one further complication: I want my default value to be a call to variable_get(), not a static value, and I can't put that into the function definition's default arg value.. i.e. this is a no-go:

<?php
function HOOK_reminder($reminder_color = variable_get('reminder_color', 'blue')) { ... }
?>

I'd think when theme() retrieves the output via function (not template), it should pass in the default values for arguments as they're defined in HOOK_theme() implementations...

Your theme functions should start with theme_

The key to each sub-array is the internal name of the hook

It took me a while to figure this out. To most of you this is probably quite obvious but don't forget to start your theme functions with "theme_"

<?php
function myModule_theme($existing, $type, $theme, $path) {
    return array(
       
'my_theme_function' => array(
           
'arguments' => array('argument1' => null, 'argument2' => null)
    );
}

function
theme_my_theme_function($argument1, $argument2) {
   
// Do something with the arguments en generate some content
   
$content = "Blah blah";
    return
$content;
}
?>

That's documented above...

# function: If specified, this will be the function name to invoke for this implementation. If neither file nor function is specified, a default function name will be assumed. For example, if a module registers the 'node' theme hook, 'theme_node' will be assigned to its function. If the chameleon theme registers the node hook, it will be assigned 'chameleon_node' as its function.

I'm totally confused by this.

I'm totally confused by this. In my 5.x module I used _phptemplate_callback($hook, $vars), where $hook was name of the template and $vars its variables. I don't understand how to implement this hook from a module where I can pass the template name with variables. Please advise.

I think I'm starting to get

I think I'm starting to get it now, but still didn't get to work it right. So here is my implementation:
Instead of _phptemplate_callback($hook, $vars) I now have:

theme('template_name', $vars_array); //which should be the final output

hook_theme implementation
function mymodule_theme($existing, $type, $theme, $path){
  return array(
    'template_name' => array(
      'template'    => 'template_name',
      'arguments'  => array(),
    ),
  );
}

I see my custom template appears, but without the arguments' values.

OK. Got it to work. The array

OK. Got it to work. The array of arguments has to have pre-defined keys in the hook_theme().

render elements and variables instead of arguments

The keys returned by this function have changed in D7

http://drupal.org/update/modules/6/7#hook_theme_render_changes

Watch out for the search

If you set in an overriding path in the hook_theme array Drupal will still look for a templates directory in the themes directory. It will take from the theme's template directory before looking to the override path.

I want to Drupal use tpl-file

I want to Drupal use tpl-file from theme folder, if it exists here, else to use file from module folder. How i can do that?

<?php
function ttanalytics_theme() {
    return array(
        
'ttanalytics_news_view' => array(
           
'arguments' => array('ttanalytics_news' => NULL),
           
'template' => 'analytics-news',
            
'path' => path_to_theme(),
            
'theme paths' => array(path_to_theme(),drupal_get_path('module', 'ttanalytics')),

         ),
    );
}
?>

Doesn't work

try this

try this

<?php
function ttanalytics_theme() {
    return array(
        
'ttanalytics_news_view' => array(
           
'arguments' => array('ttanalytics_news' => NULL),
           
'template' => 'ttanalytics-news-view',
         ),
    );
}
?>

i think, but not sure. The template name must be same as theme hook name, but '_' replaced by '-'.
Sorry for my english

Template Hook: very important bit...

To the detriment of what hair remains, this bit of documentation eluded me when trying to set up a template theme hook. For the arguments return value:
* These arguments must be in the same order that they will be given to the theme() function.

Dynamic templates

I have a scenario where we can upload zipped packages of content. Each package has a .tpl file to be used to display the content contained therein.

I am launching the content via a url such as "content_view/99/longid", where:
"99" is the node id of the package in question
"longid" is an identifier for the content item we want to display (located IN the package)

As mentioned above, each of the uploaded content packages has it's own .tpl file to be used for displaying the content. THESE ARE NOT page.tpl.php FILES. They are used to theme a piece of page content - NOT the page proper.

I want to be able to tell Drupal to use the appropriate file for the appropriate package.

eg. The "Poker" package has a contentview.tpl.php file which should be used to display all of the content for the "Poker" package, but a "Light Trucks" package would have it's own version of the contentview.tpl.php file. The kicker is that these .tpl files are located in their respective packages - not in either the theme folder or the module folder.

From the supplied path, I can get the location of the .tpl file I need , but I can't get Drupal to use it.

It would seem like I could use a preprocess_hook function (eg. mymodule_preprocess_contentview()), but so far, no joy. :(

Does anyone have any suggestions or links of note that deal with this subject?

Cheers!

Solution found

Ok... After a good night's sleep, I decided to have a look at the core code. I figured, "If Drupal can do it, so can I".

I found the function that actually processes the tpl files and copied that code to my own theming function (in my module directory).

Now my themeing function looks like this:

function theme_my_launchpage($data){
$template_file=$data['template'];
extract($data, EXTR_SKIP);  // Extract the variables to a local namespace
ob_start();                      // Start output buffering
include "./$template_file";      // Include the template file
$contents = ob_get_contents();   // Get the contents of the buffer
ob_end_clean();                  // End buffering and discard
return $contents;
}

Now, the variables stored in $data are inserted into the .tpl file ($data['template']) which is assigned when the menu callback runs.

Hope this helps someone. ...and if it does, please say so. I'm curious how many other people run into this type of use-case.

Login or register to post comments