Problem/Motivation
layout_discovery registers theme implementations for all layouts, modules and themes alike.
It includes a 'base hook' that allows template_preprocess_layout() to run for all layouts.
When a module registers a theme function that points directly to a theme's template, twig_theme() discovers the theme's template and uses that to overwrite the theme definition, overwriting the 'base hook', preventing the preprocess from running.
Proposed resolution
Use NestedArray::mergeDeep() instead of += to merge the results into the final set, the recursive merge will let previously-found keys to persist into the final set.
Remaining tasks
N/A
User interface changes
N/A
API changes
There are rare cases where this change will cause preprocess functions to run that previously weren't running before.
However these were supposed to run, and the documentation implies that they run.
There should be no adverse effects from this.
Data model changes
N/A
| Comment | File | Size | Author |
|---|---|---|---|
| #17 | interdiff.txt | 1.35 KB | lauriii |
| #17 | preprocess_functions-2861840-17.patch | 6.23 KB | lauriii |
| #17 | preprocess_functions-2861840-17-test-only.patch | 4.86 KB | lauriii |
| #14 | 2861840-layout-14.patch | 5.89 KB | tim.plunkett |
| #14 | 2861840-layout-14-interdiff.txt | 2.16 KB | tim.plunkett |
Comments
Comment #2
tim.plunkettComment #3
tim.plunkett- if ($this->theme->getEngine()) {
+ if (FALSE && $this->theme->getEngine()) {
Obviously this change will break many many things, but it fixes this one instance.
Comment #4
tim.plunkettThis fixes the one case, curious to see what else breaks.
Comment #8
tim.plunkettWe need the deep merge to handle things like 'base hook' and 'incomplete preprocess functions', but can't let it end up with both 'function' and 'template'.
Comment #9
aspilicious commentedLooking fine, will test this tomorrow.
Comment #10
aspilicious commentedI tested this on our production site and it works perfectly.
Code and test looks good as well.
Comment #11
lauriiiI think the documentation here could be improved. Could we state more clearly why we want to avoid both being defined in the theme registry?
We should also create some test coverage outside the layout_discovery module since this is a bug in the theme system.
Comment #12
tim.plunkettAgreed on both, thanks @lauriii!
Comment #13
tim.plunkettWorking on the test, posting the comment change.
Also while rewriting the comment I realized we only care about the case of 'template' needing to override 'function'.
Comment #14
tim.plunkettThe layout-specific test is largely overkill with this new generic test, as it is testing the same thing.
However, I think it's worth keeping since it proves (past the existing unit tests) that themes can provide layouts.
Comment #15
tim.plunkettComment #16
aspilicious commentedSeems like both points are covered.
Second try for RTBC.
Comment #17
lauriiiThe bug fix itself looks good now. Thank you also for clarifying the documentation, it looks good for me now. I was manually testing this and added test coverage to ensure that multiple preprocess functions are added and ordered correctly since that was one of the first things I wanted to test manually and was still lacking test coverage.
I looked back to the history of this line and it looks like this bug exists in Drupal 7 as well and could be backported there later.
The minor BC break being caused by the change needs sign-off from another maintainer.
Comment #19
joelpittetThe proposed solution and test look great. I'll +1 this from another theme system maintainer's point of view.
This one hunk looked a bit suspect could you explain why this is needed?
Not sure I understand why this was needed. Could you add this to the Proposed solution in the IS?
Comment #20
aspilicious commentedDS implemented a workaround but other layout modules are probably being hit by the same bug. Joel, you should ask tim for more information if you need some.
Comment #21
markhalliwellYes, I can confirm that this is happening in other layout modules #2872583: Empty "layout" and "settings" in _bootstrap_layouts_preprocess_layout().
Comment #22
markhalliwellRelated core issue (or possibly a dup of this issue?).
Comment #23
tim.plunkett#19
The docs say that template will be used if both are present, but the code checks function first. If they are merged together, that split needs to be manually done here.
Comment #24
himerus commented+1 on this so far after some initial testing.
I'd been 'fighting' for a while why I couldn't get omega_preprocess_layout() to be fired.
I've been working on an integration (currently template based and not custom class) of layout_discovery into the 5.x branch of Omega, and getting some final logic in preprocess_layout is the last bit I need to get all features for responsive region management in order to assign some final classes based on populated regions.
Will be running this patch locally for testing, and looking more over the DS solution so that I don't need to require Omega users to patch Drupal for this functionality until this is in core.
Definitely have some additional investigation/discovery to do around this issue and #2862683: 'base hook' key prevents template suggestions from working.
Comment #26
yan commentedI came here from this issue:
#2875775: Overriding template results in fatal error, id() on null
Patch from #17 seems to solve the problem.
Comment #27
yan commentedPatch from #17 works after latest update to Drupal 8.4.4, too.
Does this make it RTBC?
Comment #29
larowlanCommitted as 0f2bebf and pushed to 8.5.x
As per https://www.drupal.org/core/release-cycle-overview#current-development-c... 8.4 is in 'critical fixes only', so this can't be backported to 8.4