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

Comments

markconroy created an issue. See original summary.

markconroy’s picture

andrewmacpherson’s picture

Issue tags: +Accessibility

This 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.

markconroy’s picture

Issue summary: View changes
markconroy’s picture

Component: profile.module » Umami demo
ckrina’s picture

Issue tags: +dclondon
ckrina’s picture

Issue tags: +dcruhr18
borisson_’s picture

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:

    <span data-big-pipe-placeholder-id="callback=Drupal%5Cblock%5CBlockViewBuilder%3A%3AlazyBuilder&amp;args%5B0%5D=recipecategory&amp;args%5B1%5D=full&amp;args%5B2%5D&amp;token=pcva2mpXQyxRrGwdCofsGdjk4ljkqESK_R9WGvxjSgQ"></span>

This means that the |striptags|trim makes it empty, but there is a block there.

ckrina’s picture

Issue tags: +Nashville2018
pixelite’s picture

I'm taking a look at this now at DrupalCon code sprint.

pixelite’s picture

I 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|trim as an improvement. But I don't believe this will solve the problem with content loaded from BigPipe.

plopesc’s picture

Status: Active » Needs review
StatusFileSize
new2.61 KB

Hello,

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 striptags call in this patch.

What do you think?

Thank you.

nick_vh’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +DrupalDeveloperDays

This 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 :)

lauriii’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs steps to reproduce, +Needs framework manager review

Would 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.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

nick_vh’s picture

Status: Needs work » Needs review
StatusFileSize
new1.42 MB

Sure - here are the steps:

git clone git@github.com:nickveenhof/drupal8-umami-search.git
git checkout 2937640
composer install
mkdir docroot/themes/contrib
cp -R docroot/core/profiles/demo_umami/themes/umami docroot/themes/contrib/
cp -R docroot/core/profiles/demo_umami/modules/demo_umami_content docroot/modules/contrib/
rm .ht.sqlite || :
sudo rm -rf web/sites/default/settings.php
vendor/bin/drush site-install --db-url=sqlite://.ht.sqlite config_installer config_installer_sync_configure_form.sync_directory=../config/sync/ --yes
vendor/bin/drush ev '\Drupal::classResolver()->getInstanceFromDefinition(Drupal\demo_umami_content\InstallHelper::class)->importContent();'
vendor/bin/drush ev '\Drupal::classResolver()->getInstanceFromDefinition(Drupal\demo_umami_search_content\InstallHelper::class)->importContent();'
vendor/bin/drush search-api:reset-tracker
vendor/bin/drush search-api:index
vendor/bin/drush cr

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:

<aside class="layout-sidebar" role="complementary">
  <div class="region region-sidebar">
    <div></div>
  </div>
</aside>
markconroy’s picture

Version: 8.6.x-dev » 8.7.x-dev
Status: Needs review » Needs work
Issue tags: -dclondon, -dcruhr18, -Nashville2018, -DrupalDeveloperDays +DrupalEurope, +Novice

This patch is not applying against Drupal 8.7.x at the moment. Can someone do a reroll of it please?

eli-t’s picture

Issue tags: +Needs reroll
cferthorney’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new4.21 KB

Patch 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.

markconroy’s picture

Status: Needs review » Needs work

Can 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.

cferthorney’s picture

Status: Needs work » Needs review
StatusFileSize
new3.46 KB

Refactored and rerolled.

markconroy’s picture

Status: Needs review » Reviewed & tested by the community

This seems to work very well for me. Thanks for working on this everyone.

The last submitted patch, 12: umami_page_filter-2937640-12.patch, failed testing. View results

larowlan’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/profiles/demo_umami/themes/umami/templates/layout/page.html.twig
@@ -44,27 +44,28 @@
+  {% if page.pre_header|render|striptags('<drupal-render-placeholder>')|trim is not empty or
+     page.header|render|striptags('<drupal-render-placeholder>')|trim is not empty %}

I 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?

markconroy’s picture

@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)?

lauriii’s picture

Category: Task » Bug report
Status: Needs review » Needs work

If that's not a breaking change to existing themes (I guess it's not as long as it's not added to them)

I'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.

wim leers’s picture

+++ b/core/profiles/demo_umami/themes/umami/templates/layout/page.html.twig
@@ -44,27 +44,28 @@
-  {% if page.tabs %}
+  {% if page.tabs|render|striptags('<drupal-render-placeholder>')|trim is not empty %}

This 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.

wim leers’s picture

I see now that the IS already mentioned #953034, but it didn't link to it. Hence I didn't notice.

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>

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").

lauriii’s picture

Assigned: Unassigned » lauriii

I'm working on this

lauriii’s picture

Assigned: lauriii » Unassigned
Status: Needs work » Needs review
Issue tags: -Needs framework manager review, -Novice
StatusFileSize
new12.72 KB

I tried to rework the page template so that we don't need to do the if checks. Any thoughts on this approach?

larowlan’s picture

So I found a way to do this in twig without the dance around with the |trim|strip|makemeasandwich

{% set some_region %}{% spaceless %}{{ page.some_region }}{%endspaceless %}{% endset %}
{%if some_region %}
  <!-- markup goes here -->
  <div class="some-region">
    {{ some_region }}
  </div>
{% end if %}

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?

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

nick_vh’s picture

I 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.

nick_vh’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +drupaldevdays

Discussed 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.

volkerk’s picture

StatusFileSize
new12.91 KB

Re-rolled 2937640-30.patch against core 8.8.x

volkerk’s picture

Twig coding styles look good to me.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs issue summary update

So 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

<header class="layout-header" role="banner">
      <div class="container">
                    <div class="region region-pre-header">
    <div class="language-switcher-language-url block block-language block-language-blocklanguage-interface" id="block-languageswitcher" role="navigation">

After

<header class="layout-header" role="banner">
      <div class="container">
          <div class="layout-pre-header">
          <div class="region region-pre-header">
        <div class="language-switcher-language-url block block-language block-language-blocklanguage-interface" id="block-languageswitcher" role="navigation">

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.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

johnalbin’s picture

Title: Umami Theme - follow-up - checking for empty regions before printing the region » Umami Theme is incompatible with placeholders and HTML replaced elements when checking for empty regions
Issue summary: View changes

I'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:

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.

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?

johnalbin’s picture

Title: Umami Theme is incompatible with placeholders and HTML replaced elements when checking for empty regions » Umami theme ignores placeholders and HTML replaced elements when checking for empty regions
markconroy’s picture

We 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-name that can be used in our page.html.twig template like do:

  {% if has_highlighted %}
    {{ page.highlighted }}
  {% endif %}

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).

markconroy’s picture

Priority: Normal » Major

Based on what @JohnAlbin said, I think it's fair to bump this to major. Let's get it fixed.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mgifford’s picture

catch’s picture

This 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.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.