Problem/Motivation

In #953034: [meta] Themes improperly check renderable arrays when determining visibility the second case is that a region does contain empty blocks, but no placeholders.

It must be rendered (and html tags stripped?) to determine if it is empty or not, but we don't want to render it twice.

Proposed resolution

Use a new twig tag, so instead of:

Old:

{% if content.sidebar_first %}
<div class="sidebar-first">
  {{ content.sidebar_first }}
</div>
{% endif %}

use new:

{% section content.sidebar_first %}
{# This whole section will only be shown if the passed variable is not empty #}
<div class="sidebar-first"{{- section_attributes -}}>{# section_attributes and section_content are required to be present #}
  {{ section_content }} {# This contains the rendered content. #}
{% endsection %}
</div>

Internally in the template this would be a twig block:

function block__internal_[hash]($context, $blocks) {
  $context['section_content'] = render_var($context['sidebar_first']);
  if ($this->extension('drupal_core')->emptySection($context)) {
    return;
  }

  print '
' . PHP_EOL; print $context['section_content'] . PHP_EOL; print '
' . PHP_EOL; }

For a more advanced example we could allow:

{% section content.sidebar_first|strip_tags('html')|trim %}
{# This whole section will only be shown if the rendered variable filtered by the filters is not empty #}

{# section_attributes and section_content are required to be present #}
{{ section_content }} {# This contains the rendered content. #}
{% endsection %}

Remaining tasks

- Discuss technical solution

User interface changes

API changes

Data model changes

Comments

Fabianx created an issue. See original summary.

Fabianx’s picture

Overall it feels similar to the inline template approach, because in the end the twig template itself it mostly feels like a wrapper around the inner section content.

Section attributes are needed, because for a JS solution to work, we need a data- attribute to work with.

e.g. Thinking about it as a render / filter chain it is like the rendered output being the input to the template:

render | template

However for 3) it is needed that we know if the render result contained placeholders or not.

e.g. code would need to look more like:


function renderIfNotEmpty($build) { 
  $markup = $this->renderer->render($build);
  if (!isset($build['#attached']['placeholders'])) {
    return [ 'section_content' => $markup, 'section_attributes' => [] ];
  }

  // Special code to wrap the section_content.  
}

But that is still not ideal, more in the next issue.

Fabianx’s picture

Issue summary: View changes

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.