Improve Drupal's performance by not executing block logic on page templates with no regions - Part 2

Printer-friendly version

This is a follow up of an earlier post. You should read this one to understand this one fully: Improve Drupal's performance by not executing block logic on page templates with no regions.

As I told there in the final paragraph, it was possible to generalize this technique to work on multiple templates with a different combination of blocks. This is a general solution to solve this.

As you know, you can have multiple page templates in PHPTemplate by settings $vars['template_file'] in theme_page. We add this variable in _phptemplate_variables for the 'page' hook.

function _phptemplate_variables($hook, $vars) {
  if ($hook == 'page') {
                $vars['template_file'] = phptemplate_get_template();
    return $vars;
  }
  return array();
}

Note that we moved the logic for deciding which page template we use in a seperate function, which implementation is here. This is the only function you need to adjust to your context. The other code you can just copy-paste and reuse in your own templates.

function phptemplate_get_template() {
        static $active_template;
       
        if(isset($active_template)) {
                return $active_template;
        }

        if(drupal_is_front_page()) {
                $active_template = 'page-left';
        } else {
                $active_template = 'page';
        }
       
        return $active_template;
}

We also define a mapping to specify what regions are used on what templates.

function phptemplate_get_template_regions($region) {
        $map = array(
                'page' => array('content', 'left', 'right'),
                'page-left' => array('content', 'left'),
        );
        return $map[$region];
}

As told in the previous article, the core logic of the block was executed on demand of the block_list function. This function was called from the theme_blocks function.

We don't want to run the block_list function on regions that don't appear in our page template, so we put a wrapper function around the core function.

function phptemplate_block_list($region) {
        if(!in_array($region, phptemplate_get_template_regions(phptemplate_get_template()))) {
                return array();
        }
       
        return block_list($region);
}

And now we override theme_blocks to call this function:

function phptemplate_blocks($region) {
  $output = '';

  if ($list = phptemplate_block_list($region)) {
    foreach ($list as $key => $block) {
      // $key == <i>module</i>_<i>delta</i>
      $output .= theme('block', $block);
    }
  }

  // Add any content assigned to this region through drupal_set_content() calls.
  $output .= drupal_get_content($region);

  return $output;
}

And we're done!

To apply this to your own themes, just copy all these functions and change my implementation of phptemplate_get_template and phptemplate_get_template_regions to your situation. If you already have your own _phptemplate_variables, add my logic to yours.

Comments

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • Images can be added to this post.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <bash>, <javascript>, <mysql>, <php>. Beside the tag style "<foo>" it is also possible to use "[foo]". PHP source code can also be enclosed in <?php ... ?> or <% ... %>.

More information about formatting options