You are here

Die, phptemplate_ Prefix, Die!

Submitted by John on Tue, 2009/05/12 - 7:56pm

Ok, I mentioned this in twitter a few weeks ago, I created an issue about it in D7’s issue queue, and there are 2 small print notes in the D6 theme guide, but I don’t think my message was visible enough. So let me just say for the record (again)…

Never, never, ever, ever use phptemplate_ as the prefix for your theme’s preprocess functions. Don’t do it! phptemplate_ prefix should talk to the hand! Expunge it from your memory. It’s an ex-prefix. Seriously, cut it out! So, let me re-phrase:

Every time you use phptemplate_ prefix,
God adds a pointless issue to Drupal’s issue queue.

Please, think of the issue queue!

A few examples makes things clearer. Imagine you have this basetheme->subtheme hierarchy:

  • basetheme
  • subtheme1 (basetheme is its parent)
  • subtheme2 (subtheme1 is its parent)
  1. If subtheme2 is the active theme and basetheme has a phptemplate_preprocess function, the theme registry loads all 3 theme’s template.php files and has no way to know which theme owns the phptemplate_ prefixed preprocess function. Thus, that phptemplate_preprocess function gets registered by ALL 3 of those themes and gets run three times instead of once. ouch!
  2. Worse case: if basetheme defines phptemplate_preprocess() and then a un-observant subtheme1 creates the exact same function in its template.php, the unlucky themer will get a Fatal PHP error and possible WSOD (White screen of Death)! yay.
  3. Here's another awful consequence: Let's say that both the basetheme and the subtheme1 want to override theme_links. If basetheme defines a basetheme_links() and subtheme1 defines a phptemplate_links(), the one defined by subtheme1 should be used, but themeEngineName_links is assumed to be less specific than themeName_links, so subtheme1's phptemplate_links() override is ignored in deference to the basetheme_links() override.

The original rationale for allowing themeEngineName prefixes was “This makes it easier to move around code between themes and post snippets on Drupal.org.” But we already require themers to copy theme functions from modules and rename them from theme_function() to themeName_function(), so the copy-and-rename-function meme is already out there. Plus, copy-and-rename will help themers who are new to programming concepts understand that you can't give 2 functions the same name.

“Portability of function names” is a crutch that we shouldn't be giving to beginning themers. It just turns them into cripples. We should teach them a little PHP the right way so we don’t confuse them more later.

So phptemplate_ prefix MUST DIE!

If you use them in your D6 themes, stop now! Better yet, go and fix them in your existing themes. Especially, if you have a contrib theme using them. For D7, I just rolled a patch for this in http://drupal.org/node/422116. Review please!

Posted in:

Comments

brad's picture

Any thoughts on how catching this might be automated or partially automated? Maybe Coder module could issue a warning? Or a SimpleTest test that runs on all themes? Just throwing it out there - I don't know much about the inner workings of those systems.

So basically this only matters if you're using subthemes right? Then it seems a little extreme to expel and abolish the whole concept of using the phptemplate prefix... Many of my themes use 10 or more function overrides and that I re-use regularly and they're working fine just like that. Subthemes are really a special feature for a special kind of theme, so in the context of basetheme/subtheme projects I totally agree with you.

IceCreamYou's picture

Wouldn't it be better to fix the behavior of phptemplate_ in core rather than change the custom for every existing theme?

As the developer of PHPTemplate, I can only say that they were the right solution at the time. In the time before sub themes or even .info files, the only way to customize themes without majorly branching from core, was to copy the directory and edit your own copy of it. The original intent had nothing to do with 'snippets' or what not, it had to do with portability.

Not doing that resulted in having to do global search replaces on files, instead of it just be edit and go. We also pre-provided templates for the most commonly overrided theme functions which could just be copied.

The fact that a new feature doesn't properly take into account the phptemplate prefix does not mean the phptemplate prefix kills kittens. It might just have outgrown it's usefulness and been superceded by a better way of accomplishing the same thing. The old model was that only one 'template.php' file was ever loaded, so PHP's inherent lack of namespaces never was a problem.

I totally agree with you, Adrian! Even crusty code was once new and sparkly. In Drupal 5, there was nothing wrong with phptemplate_ prefixes. (It forced some awkward work-arounds with the Theme Settings API module, but that was just because I was pushing the boundaries in contrib.)

It was good code at the time, but its out-lived its usefulness.

@IceCreamYou: It’s not possible to fix point #2 above (WSOD). The only way to prevent it is to not allow phptemplate_ prefixes in your themes.

@peach: I believe that any theme should be a potential basetheme. If you’ve downloaded a contrib theme and just want to change one little thing, you should make a sub-theme of it. The “don’t hack core” mantra should apply to any module or theme that you download. And by leaving in phptemplate-prefixed functions in your theme, you make sub-theming it difficult and buggy.

@brad: In D7, we won’t need to catch that error; if someone leaves a phptemplate-prefixed function in, it simply won’t work (if the patch gets committed). In D6, coder.module could be updated to check for that, but its too late to fix this problem in already-contributed D6 themes. Plus, Drupal 6’s garland theme uses them.

dvessel's picture

Point one is rather nasty. I never use the engine prefix so I never knew.

I won't miss it in 7 but it would be a good idea to fix it in 6.