Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
This becomes a critical bug because ppl begin to implement phptemplate_engine_preprorcess_hook into their modules because they have no other way and then two such meets and PHP dies. Not good. I am adding here some API functionality but it's an addition which does not break any existing code.
Comment | File | Size | Author |
---|---|---|---|
#39 | module-preprocess_1d.patch | 6.71 KB | dvessel |
#35 | module-preprocess_1c.patch | 5.58 KB | dvessel |
#21 | module-preprocess_1b.patch | 5.58 KB | dvessel |
#17 | module-preprocess_1.patch | 5.42 KB | dvessel |
#14 | module-preprocess_0.patch | 4.13 KB | merlinofchaos |
Comments
Comment #1
chx CreditAttribution: chx commentedIn addition, I cleaned up some chaff in there and also this addition comes for free because it gets cached so on runtime there is no penalty. Even on build time it iterates over module_list once.
Comment #2
chx CreditAttribution: chx commentedSpacing fix.
Comment #3
quicksketchTalking with chx, I needed some additional explanation on exactly what this patch does. Let's take an example template_preprocess_ function and look at how it changes:
We currently have:
template_preprocess_page()
, which can over-ridden by themes and theme engines via:phptemplate_preprocess_page()
mytheme_preprocess_page()
This change allows modules to add and change variables the variables during preprocess. Such as:
template_MODULE_NAME_preprocess_page
The flexibility this gives us is tremendous (though it blurs the line between modules and themes further). jjeff has been looking for a way to make jQuery update module swap out various versions of jQuery (see http://drupal.org/node/173941), now this is possible via:
This patch has some "interesting" (but correct) side-effects. Modules seem to have a higher priority than theme engines, but less than themes in setting variables. Here's the new order for variable declaration:
template_preprocess_page()
(default)phptemplate_preprocess_page()
(theme engine)template_MODULE_NAME_preprocess_page()
(modules)mytheme_preprocess_page()
(theme)So variables set in phptemplate_preprocess_page (as in the Garland theme) can be over-ridden by a module, but if Garland were to use garland_preprocess_page instead, the variables could not be over-ridden.
Looks great though. I've tested it with several theme functions to confirm this is the behavior. I'd love to see it in Drupal 6.
Comment #4
quicksketchmerlinofchaos had some questions about this segment of code, fearing it would put theme engine processing before the default processing.
But checking it a second time (each individually), I'm confirming that the order I stated above is correct.
Comment #5
quicksketchCapitalizing 't' at the start of comment sentence. :)
Comment #6
dvessel CreditAttribution: dvessel commentedsubscribe
Comment #7
dvessel CreditAttribution: dvessel commentedThe ordering is wrong. I tested with "template_aggregator_page" and it comes in last.
I'm not sure I like this new ability as a "themer". I like knowing where all my variables are being assembled. Simply enabling a new module could turn into more confustion. But yeah, it sounds super useful and I have hacked on the registry myself to get devel a complete theming log. So, I can go either way with this but expect some confusion.
And back to chx's point. In Drupal 5, modules never touched variable functions since there was a clear separation between the theme engine and theme(). Not that it wasn't possible but it wasn't done so I don't see this as a critical bug. Module authors should simply stay away from naming preprocess functions not meant for it.
The devel issue I mentioned is here:
http://drupal.org/node/167337
It started as an issue similar to what chx pointed out. It used phptemplate_preprocess to do it's tricks but we did find an odd workaround. Mosh mentioned some sort of hook so the registry could be altered right before it's saved. Maybe another option to consider in D7..
Comment #8
chx CreditAttribution: chx commentedI dumped the page preprocess functions after throwing in some for testing purposes. In D5 modules stayed away but I am fairly sure that people will start doing this in D6 and while we do not babysit broken code, this is much more that because any module implementing one of these will work and then two of them won't which is not pretty. Also, we still separate theming and logic it's just that we allow adding a variable to a theming function from anywhere.
Comment #9
Dries CreditAttribution: Dries commentedI'm not sure I like the template_ prefix. For consistency with the rest of Drupal, and the other preprocess hooks, we should use MODULE_preprocess_page() not template_MODULE_preprocess_page().
Also, the documentation is sloppy. We write THEME and MODULENAME, instead of THEME and MODULE.
I also don't like this one:
Comment #10
chx CreditAttribution: chx commentedAbout the "also" set, that's already in HEAD just I have simplified the code. About the template prefix, sure, I will remove it. Patch forthcoming.
Comment #11
chx CreditAttribution: chx commentedRemoved template_ and fixed comments. No functional change.
Comment #12
merlinofchaos CreditAttribution: merlinofchaos commentedThis patch is not quite right.
1) module-based template preprocess should happen prior to theme engines, shouldn't they?
2) If there is no theme engine, modules won't get put in because they happen under 'theme_engine'; they need to happen if $type == 'module'
I think what we want is this:
Comment #13
merlinofchaos CreditAttribution: merlinofchaos commentedI'm not completely sure about that module_implements; I guess we actually don't want to use that this way, since that's actually basically already doing our function_exists for us, so maybe just module_list() is fine.
Comment #14
merlinofchaos CreditAttribution: merlinofchaos commentedHere, try this patch instead, it is more robust.
Comment #15
merlinofchaos CreditAttribution: merlinofchaos commentedI went ahead and left the array_shift in. It's a little more difficult to read, but it prevents us from having to have an if on either side of the $prefixes = array() line.
Comment #16
chx CreditAttribution: chx commentedThat's very nicely done :) much more than mine.
Comment #17
dvessel CreditAttribution: dvessel commentedIt should indeed happen before theme engines right after the default preprocessors since themes may use the engine name.
I change merlin's patch so it's more readable. Removed the array_unshift. The docs for theme() was changed a bit too so it reflects the order the preprocessors are run.
I tested by throwing in all the possible preprocessors + 2 node preprocessors.
Comment #18
merlinofchaos CreditAttribution: merlinofchaos commentedLooks good, I approve.
Comment #19
chx CreditAttribution: chx commentedNicely readable.
Comment #20
Gábor HojtsyHm, indeed, much more readable. But what does this supposed to mean?
What does "itself" refer to?
Comment #21
dvessel CreditAttribution: dvessel commentedItself means the current hook that it's working under. Here's another. :)
Comment #22
Gábor HojtsyHm, I am getting to understand the calling order now. So the ENGINE_preprocess* functions are allowed to be defined by themes to let subthemes defined their own THEME_preprocess* functions and still get the ENGINE_preprocess* (ie. the parent theme's preprocess) functions called? So this kind of overcomes the problem of parent theme preprocess functions not being called from an inherited theme, and parent theme authors need to think about this in advance? Basically meaning that every theme author who considers her theme to be a possible parent for subthemes should use ENGINE_preprocess* instead of THEME_preprocess*?
This sounds like quite a hack to me and obviously it does not work at all with multiple inheritance levels of themes.
Or do I misread something?
Comment #23
dvessel CreditAttribution: dvessel commentedGábor, sorry for not being clear. There's only so much we can explain in the php docs.
The base and sub-themes can use it's own name or the engine name. Even if the base theme used it's own name, all the sub-themes will inherit their preprocessors. The suggestion to use the engine name for the base theme was made because it's easier to use "phptemplate_preprocess_HOOK" when copying all the various snippets that would eventually get posted in the handbooks. I'm not sure if that's a wise choice. It's simply a guideline but nothing prevents themes from doing otherwise.
I talked with Merlin on this and his thought was to move away from "ENGINE_preprocess*" for themes. At the moment, that naming ability is there and we have to document to minimize fatal re-declaration errors.
So, baz will run all it's parent themes preprocessors for theme('page'). If more than one of the themes used the theme engine, we'd have a problem.
Comment #24
dvessel CreditAttribution: dvessel commentedEh, bad example.. here it is again:
And theme('page') would run the above preprocessors when "baz" is the active theme.
Comment #25
Gábor HojtsySo then I see no reason to support or in any way suggest themes to use function names which conflict. This caused us enough trouble in the past (eg we was unable to get the regions from a theme because we have not been able to include it). Although the region problem itself is solved with .info files, I would encourage a practice where themes would stay in their own namespace.
I see some code examples in forums might not work anymore, but given the extent of theming changes in Drupal 6 anyway, I think this one is a minor change.
Comment #26
merlinofchaos CreditAttribution: merlinofchaos commentedGoba;
I've thought about this, but it's still a good thing to use the phptemplate_* notation (i.e, ENGINE_*) in snippets and in include files that might be included in different themes.
A prime example of this is that I have my own pager.inc that uses my (surprisingly unpopular) pager variant. I just drop it into the theme and 'include_once pager.inc' -- because it uses the phptemplate_* notation, it works great wherever I put it.
Now, if we remove the ability to use phptemplate_* notation, it has to be rewritten for every theme that utilizes it.
This is why I have been merely edging toward encouraging themes to always use their theme name. I think I agree with dvessel that the guideline should be that if you have 'base theme' in your .info file, you should *never* use ENGINE_* notation, but if you don't, it is okay. That minimizes the risk of errors, and still retains flexibility.
There is also the fact that we have trained all of our themers into phptemplate_* notation and it is not clear to me that about-facing on that right now will be beneficial.
Comment #27
merlinofchaos CreditAttribution: merlinofchaos commentedBTW, I'm not sure this conversation really affects the current patch.
Comment #28
Gábor HojtsyIt does affect the patch for sure. The fact that we "trained" people to do something, which hit us on the face anyway, is not a good reason to support this further. The reusability argument sounds better, but this is not reflected in the patch. There is a growing number of functions we can implement and I think it is very important to have clear documentation about these.
Comment #29
merlinofchaos CreditAttribution: merlinofchaos commentedI don't understand; this patch doesn't really affect the ENGINE_ stuff, it's adding MODULE_preprocess.
The ENGINE_ stuff is already there.
Comment #30
merlinofchaos CreditAttribution: merlinofchaos commentedAlso, regardless of the training argument, I still find the reusability argument (in snippets and in include files) to be both valid and valuable.
Also, changing that now would be an API change rather late. It would very seriously affect any theme that has already been ported to D6.
Comment #31
Gábor HojtsyMerlin, I am not genuinely against "adding" ENGINE_preprocess, but I read this diff lots of times now, and I still do not see where it was possible to use ENGINE_preprocess with the old code (as compared to ENGINE_engine_preprocess):
To me it seems like this line adds this possibility:
Although it might be that the first removed line adds that for theme engines, in which case I am mistaken. Frankly I was not an expert in the previous code and the new code really looks simpler, so this might be my misunderstanding.
Comment #32
merlinofchaos CreditAttribution: merlinofchaos commentedI think your comment illustrates just how much better the patch is than the original code.
Comment #33
dvessel CreditAttribution: dvessel commentedEh, this came up because I updated the php docs. It had little to do with the original issue.
Gábor, should I update the docs again? Don't want to hold up the issue for but the doc changes not related to this patch..
Comment #34
dvessel CreditAttribution: dvessel commentedTo answer this question..
It happened right here:
$name held the name of the engine. _theme_process_registry() iterates over and over again from here:
http://api.drupal.org/api/function/_theme_build_registry/6
Comment #35
dvessel CreditAttribution: dvessel commentedShould I dare set it back RTBC?
updated for hunk offsets. Same as patch #21
Comment #36
Gábor HojtsyDvessel: I know that that the documentation improvements are not strictly related to this patch, but adding more preprocess functions just makes it *much* more important to document the options better. The explanation here is not too practical. We know from merlin's explanation, that we can use this to provide included and reused code for our themes and it helps people copying code from our repositories. Cleaning up why we have these options is important IMHO.
+ * - ENGINE_preprocess(&$variables)
+ * This is meant to be used by themes that utilize a theme engine. Theme
+ * authors must be careful when using this in sub-themes with PHPTemplate
+ * since it can cause a fatal redeclare errors due to multiple template.php
+ * files being used. A good practice is to use the engine name for the base
+ * theme and the theme name for the sub-themes to minimize name collisions.
Comment #37
dvessel CreditAttribution: dvessel commentedGábor, well as it stands now we still have ENGINE_preprocess* without this patch and the explanations in there are completely off.
I'd like to hear some suggestions on what would be a practical guideline. Once we know that, I'll make the changes.
Comment #38
dvessel CreditAttribution: dvessel commentedI just reread your post.. So all I have to do is make it more clear. I thought you didn't like the guideline in general.
Patch forthcoming.
Comment #39
dvessel CreditAttribution: dvessel commentedHere's the changed docs. Everything else is the same.
Comment #40
merlinofchaos CreditAttribution: merlinofchaos commentedWait.
Please, this patch is NOT where we should be arguing about documentation changes. This is silly. Let's pull the documentation changes from this patch and put them in their own patch, because important issue A is getting slowed up by a bikeshed issue.
Comment #41
Gábor HojtsyThanks for the documentation improvements. I stand behind my belief that when we complicate a system with more options and possibilities, improving documentation for the different possibilities should go hand in hand. Committed the patch with the improved docs.
Comment #42
(not verified) CreditAttribution: commented