0

I try to check if my sidebar second if empty. If it is not empty, I add a class col-md-8 on my section-main. To check if the sidebar is empty I use this code in the page.html.twig template of my custon theme:

{% if page.sidebar_second and page.sidebar_second is not empty and 
page.sidebar_second|render|striptags|trim is not empty %}

My problem is that sometimes the sidebar second if considered as empty but it is not. In the sidebar second, I have a views block that the content depends on the current node taxonomy or book id. The query to get the content of this views block if altered in my_custom_module_views_query_alter(ViewExecutable $view, QueryPluginBase $query) function. When I checked for sidebar_second in page.html.twig, the content of this block is always empty, but if I have another block in sidebar_second (so the column is displayed), this block has actually some content and is displayed.

So to check if my sidebar is really empty or not, I tried to check that in the my_custom_theme_preprocess_page() function in my_custom_theme.theme, like this :

  $rendered_sidebar_second = \Drupal::service('renderer')->renderRoot($variables['page']['sidebar_second']);
  $with_sidebar_second = !empty(trim(strip_tags($rendered_sidebar_second)));
  $variables['with_sidebar_second'] = $with_sidebar_second;

Then , in my page.html.twig, I check the variable with_sidebar_second to know if sidebar_second is empty o not. This gives the right results, but induces a problem for assets : PHP Exception LogicException: 'A stray renderRoot() invocation is causing bubbling of attached assets to break.. Using renderPlain() gives the same result. Using render($variables['page']['sidebar_second'], false) does not give the good result.

Is there a solution to have the good result for the sidebar_second and have all assets too ?

2 Answers 2

1

In theming the use of render() is correct, you can't use a different render method. The problem is that many blocks are placeholdered and you can't determine at the point the page template is rendered in which context the placeholdered block might be rendered in future. Probably then with a different user logged in because blocks cached per user are placeholdered by default.

The code in your question thinks the region is empty because striptags removes placeholders which usually are formatted as HTML tag.

You can change this at the expense of cache performance by adjusting the cacheablity of the blocks involved or customizing the auto-placerholder condition site-wide.

See https://www.drupal.org/docs/8/api/render-api/auto-placeholdering

3
  • Thanks for your response. If I don't add 'striptags', the block is considered as not empy even there is no content in the block. To adjust the cache, I have tried to set Block CachingI to cache tags in my advanced view configuration, and add a cache tag node:nid in a custom module in hook_views_pre_view() function, but this doesn't work, the block is now always displayed, with the same content for all pages.
    – Lucuhb
    Commented Dec 15, 2020 at 14:08
  • Yes, the page template can't tell what happens in the future when the placeholder gets replaced. Either way you get false positives or false negatives.
    – 4uk4
    Commented Dec 15, 2020 at 14:23
  • So there is no solution, that's it ?
    – Lucuhb
    Commented Dec 15, 2020 at 14:58
0

In twig you can test if any content exists in a region in the following way:

{% if page.sidebar_second|render|striptags|trim|length %}
   <div class="section-main col-md-8">
{% else %}
   <div class="section-main">
{% endif %}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.