Techniques for Overriding Themable Functions

Once you have found a themable function that you would like to override, you have two variations on how to go about doing it.

The first variation is to provide an alternative function in your theme that will be used instead of the functions provided by Drupal or by the theme engine. In general, this involves creating a function with the naming convention namespace_foo(), where namespace is the name of your theme engine and foo is the name of the function. Review Exercise 5-1 earlier in the chapter for an example of creating a phptemplate_breadcrumb($breadcrumb) function that overrides the theme _breadcrumb($breadcrumb) function.

The second way to override a themable function in your theme is actually an extension of the first way, but puts the code and logic for generating the output into a tpl.php template file instead. You still provide a function following the same naming convention, but instead of putting the logic for the output there, in the function, you use it to call the template file instead.

The second approach has several advantages over the first method. It is vastly easier to output large amounts of HTML from a template file rather than a PHP function, since you don't need to quote and escape everything. This is the largest advantage. Beyond that, switching and swapping tpl.php files between themes is easier and more portable than using copy and paste to move and rename themable functions into your theme, and template files are easier for people with weak PHP skills to work with.

For both approaches, you will need to create a file in your theme folder named template.php if it doesn't already exist. This is where Drupal will look for themable junctions that are specific to the current theme. In the case of the Bluemarine theme, the path to this file will be themes/ bluemarine/template.php. Here is the override to the breadcrumb function from Exercise 5-1:

<?php function phptemplate_breadcrumb($breadcrumb) { $output = '<h1>Hello World!</h1>'; $output .= implode(' / $breadcrumb); return $output;

Compare that to the original theme_breadcrumb function from includes/theme.inc:

function theme_breadcrumb($breadcrumb) { return '<div class="breadcrumb">'. implode(' A» $breadcrumb) .'</div>';

Notice that the new breadcrumb function takes the same parameter ($breadcrumb) and applies essentially the same logic as the original, but chooses to embellish the output in a different way. This is the responsibility of the theme developer who ventures to write new themable functions. You need to understand the original functionality, and, as far as desired, reproduce it in the override, including handling all of the input parameters.

The previous code demonstrates the first approach to overriding themable functions: writing new functions in template.php. A better implementation would be to create a breadcrumb.tpl.php file instead. The path to this new file would be themes/bluemarine/ breadcrumb.tpl.php, and here is what it would look like:

Notice a few things about this code. First, it is much shorter than the function version. Second, it isn't necessary to store all of the output in a variable. Third, pure HTML, such as the <h1>Hello World!</h1>, doesn't need to be quoted. This last point is especially practical when you consider more complex HTML that involves quotation marks or line breaks, both of which need to be escaped with backslashes and special characters in functions. Template files are also easier to edit in programs such as Dreamweaver, and therefore nicer for graphic designers who get the shivers when confronted with too much PHP code. You also end up with a collection of template files that can be used again for another theme, allowing you to build a theme library and reuse your code.

To let PHPTemplate know that it is to use the breadcrumb.tpl.php file, you need to add the following function to the file themes/bluemarine/template.php:

function phptemplate_breadcrumb($breadcrumb) { return _phptemplate_callback('breadcrumb', array('breadcrumb' => $breadcrumb));

The _phptemplate_callback function is PHPTemplate's mechanism for finding and including tpl.php files. Any time you want to use a template file, a call to this function is required. The first parameter to _phptemplate_callback is the name of the themable junction you wish to override, minus the theme_ part. In this case, you wish to override the theme_breadcrumb function, so the first parameter becomes 'breadcrumb'. If you had set out to override the theme_status_messages function, the first parameter would be 'status_messages'. The second parameter is an associative array of the variables that you wish to pass to the function. This will usually correspond one-to-one with the parameters that the original themable function requires. The function theme_breadcrumb($breadcrumb) receives one variable $breadcrumb, and so the array becomes 'breadcrumb' => $breadcrumb.

Now when theme('breadcrumb', $breadcrumb) is called, the function phptemplate_breadcrumb will be invoked, which will in turn lead to the inclusion of the breadcrumb.tpl.php template file. Does that sound complex? Complexity is the price to pay for flexibility, in this case.

0 0

Post a comment