Problem/Motivation
In #2542050: Toolbar implementation creates super annoying re-rendering. Toolbar added the following code:
/**
* Implements hook_preprocess_HOOK() for HTML document templates.
*/
function toolbar_preprocess_html(&$variables) {
if (!\Drupal::currentUser()->hasPermission('access toolbar')) {
return;
}
$variables['attributes'] = new Attribute($variables['attributes']);
$variables['attributes']->addClass(['toolbar-tray-open', 'toolbar-horizontal', 'toolbar-fixed', 'toolbar-loading']);
}
Up to this point $variables['attributes'] is an array instead of an object. hook_preprocess_html
functions in themes might expect the variable to be an array instead of ArrayAccess
object since this change was introduced in 8.4.0.
This also makes theming fragile because depending on whether Toolbar module is enabled or not, the variable will be ArrayAccess
object or an array.
Proposed resolution
Use the existing array to add classes rather than converting the array to an Attribute
object.
Remaining tasks
Write a patch- Agree on how to handle the BC break
- Review
- Commit
User interface changes
None.
API changes
'attributes'
variable in hook_preprocess_html
will be always an array instead of Attribute
object.
Data model changes
None.
Comment | File | Size | Author |
---|---|---|---|
#32 | 2917653-32.patch | 801 bytes | dww |
#18 | 2917653-18.patch | 1.18 KB | markhalliwell |
Comments
Comment #2
bojan_dev CreditAttribution: bojan_dev commentedComment #3
idebr CreditAttribution: idebr at ezCompany commentedComment #4
idebr CreditAttribution: idebr at ezCompany commentedUpdated the issue summary to expand on the issue at hand.
Comment #5
idebr CreditAttribution: idebr at ezCompany commentedComment #7
idebr CreditAttribution: idebr at ezCompany commentedThe patch in #2 solves the fatal error in our custom theme implementing
hook_preprocess_html()
after updating to Drupal 8.4.0Comment #8
alexpottWell now we're in the worst of all worlds because there might code out there assuming this is an attribute :(
@idebr since Attribute implements ArrayAccess it'd be great if this issue detailed what your custom theme is doing in
hook_preprocess_html()
?Comment #9
idebr CreditAttribution: idebr at ezCompany commentedRe #8
Correct, currently
$variables['attributes']
inhook_preprocess_html()
may be an array or Attribute depending on where the hook is implemented. Assuming a stock Drupal installation where hooks are called in order of modules, themes and then by alphabet:$variables['attributes']
is an array$variables['attributes']
is an AttributeThe project consists of a multisite installation with a custom theme for the corporate site with a subtheme for its intranet. The intranet theme is stripped from flashy content, since its main focus is to provide textual content.
The following code:
resulted in the following notice:
Comment #10
idebr CreditAttribution: idebr at ezCompany commented@alexpott Did the additional information help at all? Tentatively updating status back to RTBC, since coding around switching data types makes coding in this area prone to errors.
Comment #11
lauriiiThank you @bojan_dev for opening the issue and creating the patch, and thank you @idebr for a clear explanation of the problem. Sorry for both of you that it has taken so long to provide feedback on this issue.
I discussed this issue today with @alexpott. We agreed that there are two possible ways to proceed with this:
According to our Drupal 8 backwards compatibility and internal API policy, preprocess function values can be changed. Given that the policy would allow us to make the code change, and the fact that the bug fix is reverting a relatively recent change, I'm leaning towards suggesting to proceed with the option 2.
Comment #13
idebr CreditAttribution: idebr at ezCompany commentedI added a draft change record for #11.2 at https://www.drupal.org/node/3002434
Comment #14
idebr CreditAttribution: idebr at ezCompany commentedClosed #3015783: type of $variables['attributes'] in hook_preprocess_html as a duplicate.
Comment #15
lauriiiI updated the issue summary with more information.
Sadly I still cannot think of a way to fix this without any disruption. However, In my opinion, we cannot leave the code as it is. The fact that Toolbar module changes the type of the
'attribute'
variable intoAttribute
object makes theming fragile because some themes might incorrectly expect the variable to beAttribute
object, which it isn't consistently since it depends on whether Toolbar module is enabled or not. Some themes might have already built code that relies on'attributes'
beingAttribute
object, but in fact, that code is broken at the moment since it creates dependency on Toolbar module being enabled.Hopefully, in future, we will run some type checks for variables: #3016948: Type check theme variables, but in the meanwhile, we just have to be more careful to not introduce this kind of changes.
Comment #16
markhalliwellGiven the Drupal Core frontend BC policy, I think option #11.2 is sufficient. Any decent theme should be prepared to handle either an array or
Attribute
object; that's what the Drupal Bootstrap base theme does.The CR is a little muddy though...
This seems to imply that the Twig template variable would suddenly become an array. This isn't true as ThemeManager::render ensures that
'attributes', 'title_attributes', 'content_attributes'
all becomeAttribute
objects prior to Twig template rendering.Comment #17
lauriiiThank you for the review @markcarver! I agree that the change record could use some more clarity, so I went ahead and updated it. Feel free to take another look at that.
Comment #18
markhalliwellCR looks good to me.
Was planning on marking this as RTBC, but it seems there still needs to be a release manager review?
Also, seems a bit unnecessary to have this be an array + foreach loop; they can just be simple additions... here's a new patch (no interdiff, patch is extremely tiny).
Comment #19
lauriii+1 on the new patch.
Comment #20
LendudeLooks we have a concession here that #11.2 is the way to go (I agree too), lets see if a release manager agrees :)
Comment #22
markhalliwellSeems like a random test failure.
Comment #24
markhalliwellAnother random test failure...
Comment #26
idebr CreditAttribution: idebr at ezCompany commentedTestbot:
15 Feb 2019 at 13:19 CET:
PHP 7 & MySQL 5.5 Build Successful
Comment #27
dwwSadly, the testbot got all kinds of confused yesterday. I've had to re-upload patches to a number of issues to unstick weirdness. Agreed #18 is RTBC. Here it is again. This should get the testbot to stop marking this needs work.
Comment #29
catchAgreed on changing this back, at the moment it depends when your hook is fired and whether toolbar is enabled, so could affect any new site seemingly at random. With the patch applied, we have consistent behaviour that won't affect new sites and would only affect a subsection of existing sites that have adapted to the bug since 8.4...
Committed c5b88d8 and pushed to 8.7.x. Thanks!
Comment #30
dwwWe can haz backport? ;) Maybe too disruptive in a patch release. But I don't see any explicit mention that this had to wait for a minor release, and @lauriii participated here multiple times. I would have assumed they would have said so if this wasn't backportable. ;) The issue lived on the 8.6.x branch for quite a while, and that's what we were testing against.
Thoughts?
Thanks,
-Derek
p.s. CR needs updates to clarify the version(s) where this is fixed, and to be published.
Comment #32
dwwSad, sad confused bot. :/ Here's #18/#27 yet again. A raw
git diff
this time, without the commit metadata.Comment #33
lauriiiI think this bug fix is too risky to be included in a patch release since some modules and themes built after 8.4.0 might have to be updated. I updated the CR and published it!
Comment #34
dwwOkay, sounds good. Thanks for being explicit (and fixing/publishing the CR!).
Cheers,
-Derek