Problem/Motivation
Currently, the Umami theme checks for empty regions by doing this:
{% if page.header|render|striptags|trim is not empty %}
The idea behind using the striptags filter is that it would leave any plain text content produced by blocks and thus show regions that are not empty.
But the striptags filter also removes HTML replaced elements such as img, video, iframe, audio, canvas, etc. That filter also removes Drupal's <drupal-render-placeholder> used by Big Pipe.
That means the current code removes A LOT of valid content. If Umami were a regular theme (and not a demo theme for a specific set of demo content), this would be a major bug.
Because of the stripped content, this is NOT a duplicate of #953034: [meta] Themes improperly check renderable arrays when determining visibility but that issue is definitely related.
Steps to reproduce
TODO: Document how to see this bug with the Umami content. Do we need to add additional content? Or is it visible right out of the box?
Proposed resolution
Patch in #35 reworks the page template so that we don't need to do the if checks. Any thoughts on this approach?
User interface changes
Patch in #35 adds some new wrapper divs.
API changes
TBD
Data model changes
None
Release notes snippet
TBD
Original report
From issue:
==============
+++ b/core/profiles/demo_umami/themes/umami/templates/layout/page.html.twig
@@ -0,0 +1,132 @@
+ {% if page.header|render|striptags|trim is not empty %}
...
+ {% if page.tabs|render|striptags|trim is not empty %}
...
+ {% if page.banner_top|render|striptags|trim is not empty %}
...
+ {% if page.breadcrumbs|render|striptags|trim is not empty %}
...
+ {% if page.page_title|render|striptags|trim is not empty %}
...
+ {% if page.sidebar|render|striptags|trim is not empty %}
...
+ {% if page.footer|render|striptags|trim is not empty %}
...
+ {% if page.bottom|render|striptags|trim is not empty %}
Is this the only way we can do this? Surely we can do something smarter in preprocessing?
==============
If we just print
{% if page.tabs %}
{{ pagetabs }}
{% endif %}
We get empty regions printed on every page that there is no block in that region for. So on a views page, we'll have <div class="region-tabs"></div>
This is a known issue in Drupal core, so we can't fix it until that is fixed.
#953034: [meta] Themes improperly check renderable arrays when determining visibility
| Comment | File | Size | Author |
|---|---|---|---|
| #35 | 2937640-35.patch | 12.91 KB | volkerk |
| #30 | 2937640-30.patch | 12.72 KB | lauriii |
| #21 | umami_page_filter-2937640-21.patch | 3.46 KB | cferthorney |
| #19 | umami_page_filter-2937640-19.patch | 4.21 KB | cferthorney |
| #16 | Recipes___Umami_Food_Magazine.png | 1.42 MB | nick_vh |
Comments
Comment #2
markconroy commentedComment #3
andrewmacpherson commentedThis is desirable for accessibility.
Empty DIVs don't really matter much, as they don't pollute the semantics at all.
However an empty
<aside>is a problem for some assistive tech, as it will be included in their "landmark regions" navigation tools. An empty landmark region is potentially confusing. Same goes for header, footer, nav elements.Comment #4
markconroy commentedComment #5
markconroy commentedComment #6
ckrinaComment #7
ckrinaComment #8
borisson_It took me a while to figure this out, when there is a block in the sidebar that will be replaced with bigpipe, the output is something like:
This means that the
|striptags|trimmakes it empty, but there is a block there.Comment #9
ckrinaComment #10
pixeliteI'm taking a look at this now at DrupalCon code sprint.
Comment #11
pixeliteI was looking through https://www.drupal.org/node/953034.
There do not seem to be any solutions for both hiding the markup of a region if it's truly empty and displaying the region if it contains content added by BigPipe.
There was a suggestion to use
|render|strip_comments|trimas an improvement. But I don't believe this will solve the problem with content loaded from BigPipe.Comment #12
plopescHello,
We faced up with this situation when creating a new role in a demo site. Editor user was not able to view the node tabs because the block was filtered in a very aggressive way.
I fixed it passing some parameters to the
striptagscall in this patch.What do you think?
Thank you.
Comment #13
nick_vhThis patch is working as expected in our search demo site. We had similar issues that prevented bigpipe from working correctly.
Please get this committed to umami so we can inherit correctly from umami and use this awesome demo-content for more than 1 purpose :)
Comment #14
lauriiiWould be great if we could get the exact steps it takes to reproduce this. Also tagging for review from a framework manager since they originally raised this problem.
Comment #16
nick_vhSure - here are the steps:
Set $settings['config_readonly'] = FALSE; in your settings.php
Go to http://mysiteijustinstalled/admin/structure/block/manage/type?destinatio...
Change the page restrictions and leave this section empty. So the block could load on all pages
Go to the homepage and you should see the empty region:

You can see in the HTML the following empty region:
Comment #17
markconroy commentedThis patch is not applying against Drupal 8.7.x at the moment. Can someone do a reroll of it please?
Comment #18
eli-tComment #19
cferthorneyPatch now applies cleanly. There was a slight rework to allow for the factor the
{% if %}had been extended to include both the header and the preheader region.Comment #20
markconroy commentedCan we add the same check around the {{ page.highlighted }} region.
Also, we seem to have inherited some code in core/modules/block_content/src/Form/BlockContentDeleteForm.php that shouldn't be part of this patch.
Comment #21
cferthorneyRefactored and rerolled.
Comment #22
markconroy commentedThis seems to work very well for me. Thanks for working on this everyone.
Comment #24
larowlanI think we need a new twig filter for this, as littering our templates with this makes them harder to maintain, but also will result in more updates if things changes.
Having a filter means we can update it in one place
Thoughts?
Comment #25
markconroy commented@larowlan
If that's not a breaking change to existing themes (I guess it's not as long as it's not added to them), then, yes, a filter might be a better solution.
Should we commit this and create a follow up issue against Drupal core rather than Umami (if so, mark this as fixed) or would you rather we do that as part of this issue (if so, mark this as needs work)?
Comment #26
lauriiiI'm wondering how would the addition of a new filter break backwards compatibility?
I would prefer adding the filter here, since then we could say that this is the way empty regions are supposed to be checked. Also, fixing any potential side effects of the solution would be easier once we have a centralized place to control that.
I think it would be also useful to get a review from the render API subsystem maintainers.
Comment #27
wim leersThis is not possible, for complex reasons explained in #953034: [meta] Themes improperly check renderable arrays when determining visibility.
I see that this is explicitly doing a complete render to sort of work around it. But it then still strips placeholder tags, meaning that it may be concluding that something is empty even though it won't be (once the placeholder is rendered).
See #953034-200: [meta] Themes improperly check renderable arrays when determining visibility.
Comment #28
wim leersI see now that the IS already mentioned #953034, but it didn't link to it. Hence I didn't notice.
We should instead ensure that we don't have emptiness-based conditions. It would be okay to check for pre-rendering emptiness (i.e. "this region has no blocks placed in it"), but not to check for post-rendering emptiness (i.e. "this region has >=1 blocks, but maybe all of them render to nothing for this request").
Comment #29
lauriiiI'm working on this
Comment #30
lauriiiI tried to rework the page template so that we don't need to do the if checks. Any thoughts on this approach?
Comment #31
larowlanSo I found a way to do this in twig without the dance around with the |trim|strip|makemeasandwich
Basically, set also is a block, if you combine that with spaceless, you render the element in advance without whitespace.
If it yields nothing, your if fails.
Thoughts?
Comment #33
nick_vhI updated the demo site as mentioned in comment #16 and this is working as expected. @laurii, what are the next steps we can take to get this committed? I'm reluctant to set this to RTBC as I am not aware enough of the standards this has to meet before we can commit this.
Comment #34
nick_vhDiscussed in person with @laurii at Drupal Dev Days and he is in agreement we can mark this as RTBC. If for whatever reason someone objects, please reopen/comment/add suggestions how to improve.
Comment #35
volkerk commentedRe-rolled 2937640-30.patch against core 8.8.x
Comment #36
volkerk commentedTwig coding styles look good to me.
Comment #37
alexpottSo another reason why this is a very good thing to do is that the current approach in HEAD results in the final page having markup like
<div id="block-umami-disclaimer--2" class="block-type-disclaimer-block block block-block-content block-block-content9b4dcd67-99f3-48d0-93c9-2c46648b29de">instead of
<div id="block-umami-disclaimer" class="block-type-disclaimer-block block block-block-content block-block-content9b4dcd67-99f3-48d0-93c9-2c46648b29de">This is because the rendering but not using the output causes the \Drupal\Component\Utility\Html::getUniqueId() to add --2 etc to IDs! So this is definitely a good thing to fix.
The resulting fix is changing the HTML in other ways though that we might not want. For example...
Before
After
We've inserted a new div
<div class="layout-pre-header">into the design. I'm not sure that we should be doing that here.Also the issue summary needs updating with the solution and why it is appropriate for Umami.
Comment #43
johnalbinI've updated the issue summary because it was difficult to reconcile what was being discussed in the comments and what is done in the patch. There's bits that still need to be updated by someone else if they understand the issue and the patch better.
As for the priority of this bug, I'd like to point out:
Having this code in core means developers are definitely copying this out of core and putting it in contrib and custom themes. And THOSE copies are major bugs.
Does that mean this issue is major?
Comment #44
johnalbinComment #45
markconroy commentedWe had a similar issue with LocalGov Drupal, and fixed it like this:
https://github.com/localgovdrupal/localgov_base/blob/1.x/localgov_base.t...
Basically, render the region via php, and if there's something there create a variable for
has_region-namethat can be used in our page.html.twig template like do:Then for regions that lazy load content (just the "messages" region in our theme) we exclude that from the list of "has_region-name" items).
Comment #46
markconroy commentedBased on what @JohnAlbin said, I think it's fair to bump this to major. Let's get it fixed.
Comment #50
mgiffordI think this most closely aligns with https://www.w3.org/TR/UNDERSTANDING-WCAG20/content-structure-separation-...
Comment #51
catchThis was partly changed in #3439017: Umami page.tpl.php breaks block placeholders which was similar but I think more problems were identified here.
@berdir just opened #3516523: Umami page template renders header regions multiple times too.