ARCHIVE: Converting 4.3.x themes to 4.4.x

Last modified: February 1, 2009 - 15:31

For more information on how the interaction between themes and modules has changed, see converting 4.3 modules to 4.4.

  • The theme system is no longer built on PHP's object model. The BaseTheme class is no more and, as such, you no longer have to use a class for your theme. Instead, a theme is a collection of functions. This will make Drupal theme development feel much the same as Drupal module development. Prefix your theme function with your theme's name. Examples:
    mytheme_page(), mytheme_comment(), mytheme_node().
  • mytheme::system() (or in the new parlance, mytheme_system()) is no longer used. The theme description used on the theme administration page should instead be returned by a new function called
    mytheme_help(). This function follows the same semantics as the regular module _help hook:
    <?php
    function mytheme_help($section) {
      switch (
    $section) {
        case
    'admin/system/themes#description':
          return
    t("A description of mytheme");
      }
    }
    ?>
  • All theme functions now return their output instead of printing them to the user. There should be no print or echo statements in your theme.
  • The mytheme_header() and mytheme_footer() functions and no longer used, a mytheme_page() function is introduced instead.
    <?php
    function mytheme_page($content, $title = NULL, $breadcrumb = NULL) {
      if (isset(
    $title)) {
       
    drupal_set_title($title);
      }
      if (isset(
    $breadcrumb)) {
       
    drupal_set_breadcrumb($breadcrumb);
      }
      ...
    }
    ?>

    This function should return the HTML code for the full page, including the header, footer and sidebars (if any). Note that it is important to set the title and the breadcrumbs for Drupal with the setter functions as suggested above, instead of just using the values provided as parameters. This way modules acting on the title or breadcrumb values can use the real value when generating blocks for example.
  • Themes now have the responsibility of placing the title, breadcrumb trail, status messages, and help text for each page. This gives them the flexibility to, for example, place the breadcrumb trail above the title or in the footer. It is now expected that mytheme_page() will return these elements. The page theme function should override the title and breadcrumb trail retrieved from Drupal, in case some explicit value is provided in the function parameters (see above). A theme can obtain the values set before by calling the functions drupal_get_title(), drupal_get_messages(), menu_get_active_help(), and drupal_get_breadcrumb(). The breadcrumb trail is returned from the latter function as an array of links; it can be formatted into a string by using theme("breadcrumb", drupal_get_breadcrumb()). Most themes use the following new code-snippet in their page function:
    <?php
    if ($title = drupal_get_title()) {
     
    $output .= theme("breadcrumb", drupal_get_breadcrumb());
     
    $output .= "<h2>$title</h2>";
    }

    if (
    $help = menu_get_active_help()) {
     
    $output .= "<div class=\"help\">$help</div><hr />";
    }

    foreach (
    drupal_get_messages() as $message) {
      list(
    $message, $type) = $message;
     
    $output .= "<strong>". t("Status") ."</strong>: $message<hr />";
    }
    ?>
  • The _head() hook is eliminated and replaced with the drupal_set_html_head() and drupal_get_html_head() functions, therefore the HTML head part should include the return value of drupal_get_html_head() instead of the return value of theme("head").
  • The theme_node() function takes an extra parameter now, $page, that indicates to the theme whether to display the node as a standalone page or not. If $page is true, then the title of the node should not be printed, as it will already have been printed by theme_page. Also note that the node body will only be filtered with the configured filters if the node page is displayed. Otherwise only the teaser will be filtered for performance reasons. Example:
    <?php
    function mytheme_node($node, $main = 0, $page = 0) {
      if (!
    $page) {
       
    $output = "<h2>" . $node->title . "</h2>";
      }
      if (
    $main && $node->teaser) {
       
    $output .= "<div>". $node->teaser . "</div>";
      }
      else {
       
    $output .= "<div>". $node->body . "</div>";
      }
      return
    $output;
    }
    ?>
  • To improve block themeability, theme_block() has been changed. The old
    function theme_block($subject, $content, $region = "main")

    has become
    function theme_block($block)

    with $block being an object containing $block->subject, $block->content, etc. See the doxygen doc for details and for how you can style blocks with CSS.
  • Also, theme_blocks() has been improved to allow themes to hook into (change) the blocks before outputting them. See this cvs log message for details.

fooo bar

 
 

Drupal is a registered trademark of Dries Buytaert.