An annoying attribute of the D6 theme system is that if you override a base theme's preprocess function in a subtheme, the parent's preprocess function is not called. You also can't easily call it unless it's always named phptemplate_preprocess_foo(), but that creates namespace problems.

The attached patch adds a utility function, used in the starter theme, that calls a parent theme's corresponding preprocess function if it exists. It is essentially equivalent to the parent::__construct() operation in OOP code, and should be used in the same way.

Comments

johnalbin’s picture

Status: Needs review » Needs work

What about when SUBTHEME_preprocess($vars, $hook) wants to call its parent? It can’t call zen_parent_preprocess() with a $hook because that will call PARENT_preprocess_HOOK() and not PARENT_preprocess().

And…

  1. $theme[$theme] should be $themes[$theme]
  2. Since all preprocess functions are called with params $vars, $hook, I would prefer zen_parent_preprocess to have the params in this order: $theme, $vars, $hook

Maybe Zen could just hijack phptemplate_engine_preprocess(&$vars, $hook) and (optionally with a theme setting) auto-call the preprocess functions up from the root? But we would still need something like this patch for when you wanted to turn off that auto-call code.

Crell’s picture

If Zen is going to hijack the engine preprocessor, I'd rather just make it its own theme engine; PHPTemplate++. :-) (Zengine: The Revenge?)

If thema_preprocess() wants to call its parent preprocessor, themeb_preprocess(), it just calls zen_parent_preprocess($vars, 'themea'); $hook is NULL if not specified, in which case it doesn't try for a hook but just uses the basic _preprocess() parent. See the comment "// If no hook is specified, then we're climbing the generic preprocess chain.".

I'll swap the parameters of zen_parent_preprocess() and submit a new patch soon(tm).

johnalbin’s picture

If Zen is going to hijack the engine preprocessor, I'd rather just make it its own theme engine; PHPTemplate++. :-) (Zengine: The Revenge?)

The problem Zengine had was that it couldn't use .tpl.php as its extension (phptemplate claims that.) So JJeff had to use .zen files. Ick. So, no thanks on the Zengine TNG. :-)

If you don't like the idea of hijacking phptemplate_engine_preprocess() (which I think is safe since D6 doesn’t use it), another option is to have all subthemes define a SUBTHEME_preprocess() which calls a zen_preprocess() which then does the optional auto-call of the other preprocess functions.

If thema_preprocess() wants to call its parent preprocessor, themeb_preprocess(), it just calls zen_parent_preprocess($vars, 'themea');

Let me clarify my question with an example. If phptemplate is currently on the node hook, it will call SUBTHEME_preprocess($vars, 'node') and then SUBTHEME_preprocess_node($vars). My question was, from within SUBTHEME_preprocess() how do you pass the non-NULL value of $hook (which is set to 'node' in this example) to the PARENT_preprocess() function?

Crell’s picture

To answer both of those questions... wait, the hook is passed to SUBTHEME_preprocess()? I must have missed that in the docs. If that's the case, that makes life a lot easier because we can do all the hierarchy climbing straight in SUBTHEME_preprocess(). I'll have to look into that tomorrow.

Crell’s picture

Status: Needs work » Needs review
StatusFileSize
new5.83 KB

OK, after checking the latest Zen and confirming that, duh, there is a $hook parameter that I never noticed before, here's a new and improved version. This version requires only that the generic mytheme_preprocess() function call zen_parent_preprocess(). Everything else is magic. It also allows us to remove the phptemplate_preprocess_*() calls from subtheme preprocess functions, and make Zen use zen_* rather than phptemplate_*. All of which has been done in this patch. And there is no need to use the engine preprocessor routines.

johnalbin’s picture

StatusFileSize
new11.16 KB

Here’s a new patch that adds zen_classic into the mix.

Unfortunately, here's the problem with our latest attempt:

Zen classic has its own page.tpl.php, but relies on Zen's other *.tpl.php. But the zen_classic_preprocess() function is only being called on the page hook, not on any of the other hooks. So it looks like I need to fix #249532: Allow subthemes to have preprocess hooks without tpl files. before this patch will work. Fortunately, I think I know how to do that; and should have a patch for that shortly.

Also, it turns out, unlink preprocess functions, you can use BASETHEME_themeoverride() functions without jumping through hoops. woot! So I changed phptemplate_breadcrumb to zen_breadcrumb, etc.

Finally… crap! Does #252430: Allow BASETHEME_ prefix in preprocessor function names make this issue mostly obsolete? (I found this issue through the Lullabot article email you just sent.)

Crell’s picture

I think this patch is good even without #249532. However, it looks like #252430 is a more complete fix. This is useful as a stopgap until Drupal 6.3, I guess, but otherwise that one should be the focus so that it works in core properly.

johnalbin’s picture

Status: Needs review » Fixed

The fix I did for #249532: Allow subthemes to have preprocess hooks without tpl files. seems to also fix this issue, and is a work-around for #252430: Allow BASETHEME_ prefix in preprocessor function names, and fixes #253599: Subtheme _preprocess_hook's being run twice ?.

A quad-fecta! I'm actually a bit shell-shocked at how that fix auto-magically fixed the other 3 issues.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.