13

I see that both hook_preprocess_page() and hook_preprocess_html() are implementations of hook_preprocess_HOOK(), but I don't understand when to use which.

hook_preprocess_page is called first, but that doesn't really help me understand who is calling it.

Looking at the debug_print_backtrace() output, it's getting called by theme(), but that doesn't really get me to the answer.

Is it simply defined by the array that is passed into drupal_render()?

  • It's in the log message, but I edited the function names to align them with the API docs. – mpdonadio May 30 '13 at 14:52
  • 1
    template_preprocess_page() is different from hook_preprocess_page(), and there is documentation for hook_preprocess_HOOK, in the same way there is for hook_process_HOOK. – kiamlaluno May 30 '13 at 14:59
17

hook_preprocess_page is the preprocess hook invoked when the page.tpl.php template file is used, and hook_preprocess_html is the preprocess hook invoked when the html.tpl.php template file is used.

Both the preprocess hooks are invoked when a page is rendered with theme('page'), since the page element defined from system_element_info() defines html as theme wrapper.

  $types['page'] = array(
    '#show_messages' => TRUE,
    '#theme' => 'page',
    '#theme_wrappers' => array('html'),
  );

system_theme() then defines html as follows.

'html' => array(
  'render element' => 'page',
  'template' => 'html',
),

As for when to implement hook_preprocess_html(), you implement it to alter the variables used in the html.tpl.php file, which by default has the following content.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
  "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language; ?>" version="XHTML+RDFa 1.0" dir="<?php print $language->dir; ?>"<?php print $rdf_namespaces; ?>>

<head profile="<?php print $grddl_profile; ?>">
  <?php print $head; ?>
  <title><?php print $head_title; ?></title>
  <?php print $styles; ?>
  <?php print $scripts; ?>
</head>
<body class="<?php print $classes; ?>" <?php print $attributes;?>>
  <div id="skip-link">
    <a href="#main-content" class="element-invisible element-focusable"><?php print t('Skip to main content'); ?></a>
  </div>
  <?php print $page_top; ?>
  <?php print $page; ?>
  <?php print $page_bottom; ?>
</body>
</html>

As you can see, it contains just the HTML tags that wrap a page content, available in $page. With that, you can change the content of the <head> tag, the page title (the one that goes in the <title> tag in the <head> tag), the CSS styles and the JavaScript files added to a page, the classes and the attributes for the <body> tag.
With the page.tpl.php template file, you can change more of the page being rendered, including the site name, the site slogan, the page title, and the feeds associated with the page. For most of them, there is a specific Drupal function/hook you should instead use.

hook_preprocess_HOOK is the generic hook name used for all the preprocess hooks, in the same way hook_form_FORM_ID_alter() is the hook name used for a class of alteration hooks.

  • Thanks for the completeness of the answer. I'm backing into Drupal from Rails so I'm finding some aspects easier than others. – trimbletodd May 30 '13 at 18:44
8

hook_preprocess_page and hook_preprocess_html are theme layer hooks you can use to add variables that can be used in your templates (page.tpl.php & html.tpl.php).

hook_preprocess_hook is the big theme layer hook that page and html use, and the custom ones you've made in hook_theme() as well.

For example, here is the declaration of hook_theme():

function mymodule_theme($existing, $type, $theme, $path) {
  return array(
    'custom_theme_function' => array(
      'variables' => NULL
      'template' => 'custom-theme-template', // available as custom-theme-template.tpl.php
    ),
  );
}

and here are your preprocess functions:

mytheme_preprocess_page(&$vars) {
    $vars['variable'] = 'string'; // $variable will be available in page.tpl.php
}

mytheme_preprocess_html(&$vars) {
    $vars['variable'] = 'string'; // $variable will be available in html.tpl.php
}

mytheme_preprocess_custom_theme_function(&$vars) {
    $vars['variable'] = 'string';  // $variable will be available in the template you specified in mymodule_theme() (custom-theme-template.tpl.php)
}

additionally hook_preprocess() allows you to capture multiple theme hooks, and add variables in it as well

mymodule_preprocess(&$vars, $hook) {
  if ($hook == 'custom_theme_function') {
    $vars['variable'] = 'string'; // $variable will be available in them template you specified in mymodule_theme() (custom-theme-template.tpl.php)
  }
  if ($hook == 'page') {
    $vars['variable'] = 'string'; // $variable will be available in page.tpl.php
  }
  if ($hook == 'html') {
    $vars['variable'] = 'string'; // $variable will be available in html.tpl.php
  }
}
  • Thank you for the hint with the additional parameter. Really helped me out a lot, because stuff like "mytheme_preprocess_html" never gets called from within my modules. – func0der Oct 25 '13 at 14:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.