Many times, sub-themes just need to tweak a variable in a tpl file and they don’t need to modify the tpl file's contents.
For example, if a sub-theme wants to modify the $submitted text, it doesn't need to modify the html/php in the base theme’s node.tpl.php.
Unfortunately, the auto-discovery phase of the theme registry building process first looks for tpl files in a theme and then for the corresponding preprocess functions. So if there isn't a tpl file, the theme registry building process won't look for a preprocess function.
No patch yet, but the way I envision this working is similar to the work-around that Zen 6.x-1.x has (#249532: Allow subthemes to have preprocess hooks without tpl files.). Grab the existing theme registry and loop through the known hooks (those that have tpl files), while looking for possible preprocess functions in the theme.
Comments
Comment #1
Gábor HojtsyHm, this might qualify as a D6 bug indeed.
Comment #2
dvessel CreditAttribution: dvessel commentedThis limitation is documented. A fix would be nice though.
Read the middle of this page in the list of notes:
http://drupal.org/node/223430
Comment #3
JohnAlbinSince the theme guide is amazingly accurate and based on the actual implementation (warts and all) and not based on the design, all the documented "limitations" fall into the "maybe this a bug" category. :-D
Let's see what the patch looks like and then decide whether this should be backported to D6.
Comment #4
merlinofchaos CreditAttribution: merlinofchaos commentedI am in favor of fixing this in D6 if the fix can be done without breaking the existing API, because it is a limitation that was not intended and causes quite a bit of acrobatics to get around.
Comment #5
cburschkaPlease, please, please put this in. In D7 certainly, and it would be nice in D6 as well, so we don't need to wait a year for the awesomeness.
#277063: The next generation of DHTML Menu
Comment #6
cburschkaHere is a patch for D6.
I'd submit the D7 patch first, but I've tested this one.
Comment #7
dixon_@Arancaytar: The patch is missing... ;)
Comment #8
cburschkaAnd in this case I can't even blame d.o. While rolling it, I got caught up in something and actually forgot. :P
Comment #9
cburschkaThe patch is for Drupal 6, but succeeds on HEAD with offset. Still testing if it works too.
Comment #10
cburschkaI've ported my new DHTML menu module to D7 for testing purposes, and it works. Unfortunately my server is incapable of running simpletest reliably.
Comment #11
cburschkaI still don't know whether this patch will be allowed into Drupal 6 or will have to wait for Drupal 7...
Comment #12
chx CreditAttribution: chx commentedThis is a documentation issue not a code one. Functions should have no preprocess for performance concerns. http://www.lullabot.com/articles/overriding-theme-functions-in-modules for a way .
Comment #13
merlinofchaos CreditAttribution: merlinofchaos commentedThis has nothing to do with theme functions, it has to do with theme templates, chx.
Comment #14
chx CreditAttribution: chx commentedHuh what? This has nothing to with theme functions???? I am confused.
Comment #15
merlinofchaos CreditAttribution: merlinofchaos commentedchx: Arancaytar's patch is wrong, but that's no reason to bury the whole issue. The actual issue is about themes having preprocess functions but using an ancestor's template.
Arancaytar: Your patch is wrong. It shouldn't be intercepting theme functions. chx is right on that part; theme functions need to have the speediest route possible.
Comment #16
merlinofchaos CreditAttribution: merlinofchaos commentedIMO the proper way to fix this bug is have an additional phase in phptemplate_theme() that searches for preprocess functions that match items in the $existing array that are not in the array that it's returning.
Comment #17
eMPee584 CreditAttribution: eMPee584 commentedWow this ridiculously sucks *g
I was just trying to override preprocess_forum_icon without having to modify the (incredibly complex ;) template file because my theme did not yet need any and i wouldn't want THAT one to be the first.. Well now indeed it is!
after putting debug statements into the theme.inc and noticing it looks for _preprocess hooks for EVERY enabled theme (of course it does) but not for themename_preprocess_$hook i can hardly see how not doing it for the theme aswell is a performance issue. The patch imho would be to simply add
$prefixes[] = $theme;
in theif ($type == 'module')
block.. this would of course require to have the correspondent _theme_process_registry call actually provide the $theme as 4th parameter (this itself probably qualifies as bug, invoking $module->name as $theme parameter is clearly bogus)..anyways, at least in the documentation (#223430: Preprocess functions) putting it in as the last of several notes is as good as not documenting it at all.
Comment #18
Pedro Lozano CreditAttribution: Pedro Lozano commentedSubscribiing. Because I also had this problem when trying to make my first theme in 6.x. Intuitively I thought that I cound preprocess vars for a template in template.php without having to copy the template to the theme when I'm not modifiying it.
Comment #19
merlinofchaos CreditAttribution: merlinofchaos commentedThis is a patch to 6.x to fix this issue. I think this is an important bug and I am personally responsible for letting this sit far too long; I've known how to fix it but I was unable to adequately explain the process.
This patch adds an extra phase in registry processing and specifically looks for preprocess functions for themes that do not register template overrides. I've tested this on a 3 level subtheme and it works quite well.
Comment #20
merlinofchaos CreditAttribution: merlinofchaos commentedHow to test:
If you don't have an easy to access subtheme already set up, here is a simple one you can do:
sites/all/themes/marland/marland.info:
sites/all/themes/marland/template.php:
If you like, copy themes/garland/logo.png to sites/all/themes/marland so you get a logo.
Then set your theme to Marland. The title of all pages should be modified with this test, even though you have no page.tpl.php.
If you make a similar test mod to an existing theme, be sure that:
1) You choose a preprocess that has no associated tpl.php (or theme function) for that theme and
2) You clear the cache.
Comment #21
quicksketchSubscribing.
Comment #22
dvessel CreditAttribution: dvessel commentedNaming the preprocessor after the sub-theme will still omit it. I tested with minnelli with "minnelli_preprocess_block" and it was ignored. Using "phptemplate_preprocess_block" did work though.
Comment #23
merlinofchaos CreditAttribution: merlinofchaos commenteddvessel: That's weird, the test I gave uses a subtheme name, and it worked for me in several different attempts. Are you sure you cleared cache?
Comment #24
dvessel CreditAttribution: dvessel commentedYeah, I did and just tested again with the example you provided. Same situation here.
I am using the latest Drupal 6 from CVS.
Comment #25
merlinofchaos CreditAttribution: merlinofchaos commentedOk, the first patch required the presence of hook_theme in the template.php which I hadn't realized. Moving the clause outside of that function_exists() (and providing a default array to $result) fixes that.
Comment #26
dvessel CreditAttribution: dvessel commentedOkay, this is fixed but there is another issue when the base theme uses the name of the theme, the preprocessor will register twice.
I tested with Garland by renaming "phptemplate_preprocess_page" to "garland_preprocess_page" resulted in this:
Comment #27
dvessel CreditAttribution: dvessel commentedThe only change here is the addition of an array_unique. Worked in my testing.
Comment #28
merlinofchaos CreditAttribution: merlinofchaos commentedHmm. Does garland get called for both base_theme and theme? How does that even get into the array twice?
I suppose array_unique is a good enough safety to catch any issues.
Comment #29
dvessel CreditAttribution: dvessel commentedIt looks like it's already added before running into your new block of code when looped in the "theme" phase. It's within $cache when it loops through the "theme_engine" or "base_theme_engine" phase.
I want to note that this applies to base themes too when they have no .tpl files, not just sub-themes from it's parent. This could get confusing when using path_to_theme() as it will always point to where the template is located. It's not as bad as splitting off of suggestions from its base template but I'm sure this will cause some head scratching. I'll update the docs when this gets in.
It would also be great if we could redo path_to_theme or simply rename it. themed_path() pointing to the template? And maybe path_to_theme() pointing to the theme. Dunno..
Comment #30
merlinofchaos CreditAttribution: merlinofchaos commentedRedoing path_to_theme() is probably only doable in Drupal 7, but I agree that it should be done.
Comment #31
dvessel CreditAttribution: dvessel commentedSince you think array_unique is okay, marking RTBC. Everything worked while testing.
Comment #32
emmajane CreditAttribution: emmajane commented+1 to finding a solution for this original issue. I haven't tested the patch but I agree with the logic of why it's needed. This is an issue that will affect themers who want to take advantage of base themes (which, quite frankly, will be everyone once they discover how AWESOME it is!). The assumption I propagate in the documentation I write is that subthemes inherit everything from their base (parent) theme and that you only need to add things to the subtheme if you're actually altering their output. Forcing people to copy an unaltered file into the sub-theme's directory is counter-intuitive (for lack of a better word).
Comment #33
webchickOk, this sounds like something we definitely need to fix, however:
- Merlin's patch doesn't apply for me.
- Dvessel's applies, but puts things in weird places. The $result = array(); appears in the middle of two function declarations, and the other stuff is all out-dented and weird.
Is it possible to re-roll this for 7.x?
Comment #34
webchickAnd actually let's fix this in the proper order. :)
Comment #35
webchickOK we figured out the conflict (silly concatenation rules).
I ran through the test in #20 (other than making 6.x into 7.x) and confirmed this patch fixes the bug.
Committed to D7. Moving back for consideration in D6. Here's the 6.x and 7.x version of the patch I committed.
Comment #36
webchickHm. Actually the 6.x version needs to be ported for 6.x's concatenation rules come to think of it. Should be a quick re-roll.
Comment #37
JohnAlbinRe-rolled Angie’s patch with the
properfubar-6.x string concat rules.Comment #38
keith.smith CreditAttribution: keith.smith commentedMinor, but there's a comment in there that also needs to end with a period.
Comment #39
webchickGah. How did I miss that? I am clearly slipping. :P
I guess we'll need to catch that in a monster "Add periods to all comments that don't have them" D7 patch.
Comment #40
JohnAlbinRe-rolled 6.x with period.
And the 7.x patch is my entry for Trivial Patch of the Month!
Comment #41
Gábor HojtsyLooks good, moving to RTBC, will review even more later.
Comment #42
Gábor HojtsyCommitted to 6.x, thanks. The final trivial patch against Drupal 7 still stands.
Comment #43
webchickLOL.
Committed to HEAD. :)
Comment #44
dvessel CreditAttribution: dvessel commentedAs soon as 6.7 is released, the docs need to be updated. http://drupal.org/node/223430
I'm just making this note here to remind myself or anyone else if I forget.
Comment #46
kramssov CreditAttribution: kramssov commentedWith patched D6.8 phptemplate_preprocess_node still gets ignored for me if node.tpl.php is not within the theme directory.
Comment #47
JohnAlbin@kramssov: Don’t use the phptemplate_ prefix for your preprocess functions (or theme functions). It causes all sorts of issues. Use mytheme_preprocess_node instead.
Comment #48
liquidcms CreditAttribution: liquidcms commentedso, what's the outcome of all this? and more importantly.. is there a Views example anywhere?
I was expecting that if i wanted to override a var used in a view that i no longer need to create a .tpl file for this; but as far as i can tell this still doesn't work.
should this not work:
function myzensubtheme_preprocess_views_view_field__myviewname__myfieldname(&$variables) { ... code to mod var ... }
Comment #49
nvanhove CreditAttribution: nvanhove commentedYou can use this code: