In template_preprocess()
we say:
Adds a default set of helper variables for variable processors and templates. This comes in before any other preprocess function which makes it possible to be used in default theme implementations (non-overridden theme functions).
In theme()
we say:
template_preprocess(&$variables, $hook): Creates a default set of variables for all theme hooks.
Wrong. template_preprocess()
does NOT run for all theme hooks. It does not run for theme functions at all, even though they are “theme hooks,” and even if the theme function has implemented it’s own preprocess function. It only runs for theme hooks implemented using templates, as indicated further down in the documentation:
If the implementation is a function, only the theme-hook-specific preprocess and process functions (the ones ending in _HOOK) are called from the list above. This is because theme hooks with function implementations need to be fast, and calling the non-theme-hook-specific preprocess and process functions for them would incur a noticeable performance penalty.
A little further down in theme()
we say:
There are two special variables that these preprocess and process functions can set: ‘theme_hook_suggestion’ and ‘theme_hook_suggestions’. These will be merged together to form a list of ‘suggested’ alternate theme hooks to use, in reverse order of priority. theme_hook_suggestion will always be a higher priority than items in theme_hook_suggestions. theme() will use the highest priority implementation that exists. If none exists, theme() will use the implementation for the theme hook it was called with. These suggestions are similar to and are used for similar reasons as calling theme() with an array as the $hook parameter (see below). The difference is whether the suggestions are determined by the code that calls theme() or by a preprocess or process function.
Wrong. You can implement theme hook suggestions all you want, but they will only work under certain circumstances and are actually processed 3 different ways. See #956520-16: Available theme hook suggestions are only exposed when there are preprocess functions defined.
Comment | File | Size | Author |
---|---|---|---|
#13 | drupal-1333122-44.patch | 10.61 KB | tim.plunkett |
#4 | 1333122-4.patch | 10.35 KB | effulgentsia |
Comments
Comment #1
jhodgdonThanks for reporting this. Looks like a definite doc bug. Would you consider writing at least a first-pass patch for it, since you may be one of only a few people who fully understand what it should say? :)
Comment #2
effulgentsia CreditAttribution: effulgentsia commentedWorking on a first draft now. Removing Novice tag, since this touches on some WTF internals of the theme system.
Comment #3
effulgentsia CreditAttribution: effulgentsia commentedBy the way, just added a comment to #736326-19: hook_process() and associated hooks are undocumented linking to this issue.
Comment #4
effulgentsia CreditAttribution: effulgentsia commentedHere's a draft.
I don't think that's true. I think that if your preprocess function *sets* a theme_hook_suggestion(s), then that function/template will be used regardless of how theme() is invoked, and I think that's all that's implied in the current documentation.
#956520: Available theme hook suggestions are only exposed when there are preprocess functions defined is a bug related to preprocess functions not currently being able to know what theme_hook_suggestion(s) have been implicitly set by the caller of theme(), and I hope we can fix that bug, but I don't know of documentation that this affects.
#939462: Specific preprocess functions for theme hook suggestions are not invoked is also a WTF related to preprocess_HOOK() and process_HOOK() only being called for the base hook, not the suggestions. Maybe the documentation of these hooks can be made more explicit regarding this, though I wonder if attention would be better spent figuring out the underlying issue instead. Looks like there's some progress on that issue: sorry for not attending to it yet; I'll try to soon.
Comment #5
JacineThis looks really good. Much, much, much better. Thank you so much @effulgentsia!
I'm going read closer and ask a few other themers to read these changes and make sure it all makes sense to them when I get back.
Contextual links uses it, and it's actually a great use case example: http://api.drupal.org/api/function/contextual_preprocess/7
Comment #6
effulgentsia CreditAttribution: effulgentsia commentedcontextual uses hook_preprocess(). It's hook_process() that needs an example.
Comment #7
JacineOops! Sorry about that! There is a use case for this too though. RDF module uses it to inject attributes it finds in random variables, along with theme_rdf_template_variable_wrapper(). It's actually a pretty crazy (magic) implementation IMO. It caught me off guard once, cuz I made a custom date variable and it wrapped it in a
<span>
with RDF attributes.rdf_process()
theme_rdf_template_variable_wrapper()
But maybe you saw that and thought it wasn't a good example...
Comment #8
jhodgdonThis is really nice, clear documentation -- thanks!
A couple of minor things I would suggest changing:
a)
This line is too long. See http://drupal.org/node/1354#functions
b) Not sure about this one, but I was a bit thrown by the use of the word "implemented" in a few places in the theme() documentation. For instance:
I would have used the word 'defined' here instead of implemented, maybe? But maybe not, I'm open to leaving it this way too.
Comment #9
moshe weitzman CreditAttribution: moshe weitzman commentedI think a module implements a hook so the proposed text already looks good to me. So, we just have a line length to fix and then RTBC.
Comment #10
jhodgdonOK. :)
Comment #11
Jacine#4: 1333122-4.patch queued for re-testing.
Comment #13
tim.plunkettRerolled. I'm still confused why this behavior itself not a bug, but I'll leave that for #1625158: template_preprocess() doesn't run for theme_field().
Comment #14
jhodgdonThe writing looks good here to me. I'll leave it for someone else to review for accuracy.
Comment #15
jhodgdonI gave this a careful read-over again, and decided that everything in here was just clarifying the documentation we already had (making sure people realize that certain functions are only used when a template is in play), and it also meshes with what Jacine and effulgentcia said above.
So, I went ahead and committed it to 8.x. It also applied well enough to 7.x, so I committed it there too. Thanks all for contributing to this update!