The actual code in phptemplate.engine has been vastly reduced, and much of what it does has been made inherent to Drupal. The PHPTemplate renderer has been made the default renderer. As of Drupal 6, the primary purpose of a theme engine is to tell Drupal to use a different renderer (and, if they like a different extension. i.e, .smarty instead of .tpl.php).
Additionally, theming with templates has been broken up into two sections, one for pre-processing, which is designed to transform data into something more suited for presentation (i.e, business logic), leaving the actual presenting to the template (presentation code).
If you're familiar with the _phptemplate_variables() function in PHPTemplate, what we've done is made it so that *every* theme template gets one (actually, a series) of these in order to massage the variables so that the template itself can do as little as possible. Let's take a fairly minor example:
Grabbing a theme function from aggregator module:
<?php
function theme_aggregator_feed($feed) {
$output = '<div class="feed-source">';
$output .= theme('feed_icon', $feed->url) ."\n";
$output .= $feed->image;
$output .= '<div class="feed-description">'. aggregator_filter_xss($feed->description) ."</div>\n";
$output .= '<div class="feed-url"><em>'. t('URL:') .'</em> '. l($feed->link, $feed->link, array('absolute' => TRUE)) ."</div>\n";
if ($feed->checked) {
$updated = t('@time ago', array('@time' => format_interval(time() - $feed->checked)));
}
else {
$updated = t('never');
}
if (user_access('administer news feeds')) {
$updated = l($updated, 'admin/content/aggregator');
}
$output .= '<div class="feed-updated"><em>'. t('Updated:') . "</em> $updated</div>";
$output .= "</div>\n";
return $output;
}
?>That's not terribly bad on its own, but it has a couple of things we really don't like to see at the theme layer, particularly that filter_xss, which is a real bear when using an alternate theme. The way this will look in Drupal 6 will be, approximately:
<?php
/**
* All arguments sent to the theme template will be in $variables. The only
* argument this template accepts is 'feed', so we'll look there.
*/
function template_preprocess_aggregator_feed(&$variables) {
$feed = $variables['feed'];
$variables['feed_icon'] = theme('feed_icon', $feed->url);
$variables['feed_image'] = $feed->image;
$variables['description'] = aggregator_filter_xss($feed->description);
$variables['feed_url'] = l($feed->link, $feed->link, array('absolute' => TRUE));
if ($feed->checked) {
$variables['updated'] = t('@time ago', array('@time' => format_interval(time() - $feed->checked)));
}
else {
$variables['updated'] = t('Never');
}
if (user_access('administer news feeds')) {
$variables['updated'] = l($updated, 'admin/content/aggregator');
}
}
?>And then, aggregator_feed.tpl.php will look like this:
<div class="feed-source">
<?php print $feed_url ?>
<?php print $feed_image ?>
<div class="feed-description">
<?php print $description ?>
</div>
<div class="feed-url">
<em><?php print t('URL:') ?></em> <?php print $feed_url ?>
</div>
<div class="feed-updated">
<?php print t('Updated:') ?></em> <?php print $updated ?>
</div>As you can see, this template can be in almost any language, with the exception that it probably should somehow support t(). However, it doesn't have to, because we have preserved and improved the old _phptemplate_variables() functionality. You can create this function:
<?php
phptemplate_preprocess_aggregator_feed(&$variables) {
...
}
?>Or
<?php
phptemplate_engine_preprocess_aggregator_feed(&$variables) {
...
}
?>Or
<?php
garland_preprocess_aggregator_feed(&$variables) {
...
}
?>Note that the engine gets its very own preprocess function if it needs it. This isn't used by PHPTemplate at all, at this point, but other templating engines may need it to do auto-transformation should they so desire.


Massive improvement
I've been following the theme layer improvements sporadically over the past month but this is the first time I've seen code examples of the changes. Wow. That's a massive improvement.
I can see a lot of if() statements vanishing from my tpl files. *:)
evolution or revolution
Should we call it an evolution or maybe a revolution of Drupal theme engine?
How it could reflect on performance of the Drupal?
...
Doesn't this calculation belong in the template file? I feel that putting this in the PHP is a mix of "bussiness & presentation" (or whatever it's called. oops.)
I'm asking this because I dislike identical code in one of the forum templates. I think this 'interval' formatting should be moved to the template file. I do encounter questions in the support forum about how to show a normal date (instead of this 'interval'), and I think that it would be logical for us to find this calculation in the template file itself.
I would open an 'issue' at d.o., but first I would like to hear your opinion please.
It's a six-of-one
It's a six-of-one half-a-dozen-of-the-other thing.
We try not to have functions in the actual template, format_interval/format_date are functions. That said, they are purely presentation functions, so a decent argument can be made (and I have made) that they should go into the template itself.
I suspect we're a little inconsistent with this particular case here, but my feeling is that as long as the raw data makes it to the template, we can document how to use format_interval/format_date without actually putting it into the default templates.
Have gone through your
Have gone through your Drupal 6 theming dojo presentation and am still in need of some clarifications: http://drupal.org/node/207393
Post new comment