theme()
drupal/includes/theme.inc, line 587
Generate the themed output.
All requests for theme hooks must go through this function. It examines the request and routes it to the appropriate theme function. The theme registry is checked to determine which implementation to use, which may be a function or a template.
If the implementation is a function, it is executed and its return value passed along.
If the implementation is a template, the arguments are converted to a $variables array. This array is then modified by the module implementing the hook, theme engine (if applicable) and the theme. The following functions may be used to modify the $variables array. They are processed in this order when available:
$hook The name of the theme function to call. May be an array, in which case the first hook that actually has an implementation registered will be used. This can be used to choose 'fallback' theme implementations, so that if the specific theme hook isn't implemented anywhere, a more generic one will be used. This can allow themes to create specific theme implementations for named objects.
... Additional arguments to pass along to the theme function.
An HTML string that generates the themed output.
function theme() {
$args = func_get_args();
$hook = array_shift($args);
static $hooks = NULL;
if (!isset($hooks)) {
init_theme();
$hooks = theme_get_registry();
}
if (is_array($hook)) {
foreach ($hook as $candidate) {
if (isset($hooks[$candidate])) {
break;
}
}
$hook = $candidate;
}
if (!isset($hooks[$hook])) {
return;
}
$info = $hooks[$hook];
global $theme_path;
$temp = $theme_path;
// point path_to_theme() to the currently used theme path:
$theme_path = $info['theme path'];
// Include a file if the theme function or preprocess function is held elsewhere.
if (!empty($info['file'])) {
$include_file = $info['file'];
if (isset($info['path'])) {
$include_file = $info['path'] . '/' . $include_file;
}
include_once DRUPAL_ROOT . '/' . $include_file;
}
if (isset($info['function'])) {
// The theme call is a function.
$output = call_user_func_array($info['function'], $args);
}
else {
// The theme call is a template.
$variables = array(
'template_files' => array()
);
if (!empty($info['arguments'])) {
$count = 0;
foreach ($info['arguments'] as $name => $default) {
$variables[$name] = isset($args[$count]) ? $args[$count] : $default;
$count++;
}
}
// default render function and extension.
$render_function = 'theme_render_template';
$extension = '.tpl.php';
// Run through the theme engine variables, if necessary
global $theme_engine;
if (isset($theme_engine)) {
// If theme or theme engine is implementing this, it may have
// a different extension and a different renderer.
if ($info['type'] != 'module') {
if (function_exists($theme_engine . '_render_template')) {
$render_function = $theme_engine . '_render_template';
}
$extension_function = $theme_engine . '_extension';
if (function_exists($extension_function)) {
$extension = $extension_function();
}
}
}
if (isset($info['preprocess functions']) && is_array($info['preprocess functions'])) {
// This construct ensures that we can keep a reference through
// call_user_func_array.
$args = array(&$variables, $hook);
foreach ($info['preprocess functions'] as $preprocess_function) {
if (drupal_function_exists($preprocess_function)) {
call_user_func_array($preprocess_function, $args);
}
}
}
// Get suggestions for alternate templates out of the variables
// that were set. This lets us dynamically choose a template
// from a list. The order is FILO, so this array is ordered from
// least appropriate first to most appropriate last.
$suggestions = array();
if (isset($variables['template_files'])) {
$suggestions = $variables['template_files'];
}
if (isset($variables['template_file'])) {
$suggestions[] = $variables['template_file'];
}
if ($suggestions) {
$template_file = drupal_discover_template($info['theme paths'], $suggestions, $extension);
}
if (empty($template_file)) {
$template_file = $info['template'] . $extension;
if (isset($info['path'])) {
$template_file = $info['path'] . '/' . $template_file;
}
}
$output = $render_function($template_file, $variables);
}
// restore path_to_theme()
$theme_path = $temp;
return $output;
}