Block with Failed Condition produce PHP Warning

Created on 24 July 2023, over 1 year ago
Updated 30 April 2024, 7 months ago

First off, this is a great module for quickly configuring when things are to show in a layout.

Problem/Motivation

When a block has a failed condition from Context it produces a PHP Warning. If a Content Type's Layout has 6 blocks with Context Visibility set and 5 fail to pass their conditions then you'll see 5 PHP Warnings.

I've noticed that blocks and sections are still rendered even when they have failed conditions; please note that sections with failed conditions do not produce any PHP Warnings.

Warning: Undefined array key "content" in template_preprocess_block() (line 251 of /home/account/docroot/core/modules/block/block.module)

#0 /home/account/docroot/core/includes/bootstrap.inc(347): _drupal_error_handler_real(2, 'Undefined array...', '/home/account/...', 251)
#1 /home/account/docroot/core/modules/block/block.module(251): _drupal_error_handler(2, 'Undefined array...', '/home/account/...', 251)
#2 [internal function]: template_preprocess_block(Array, 'block', Array)
#3 /home/account/docroot/core/lib/Drupal/Core/Theme/ThemeManager.php(287): call_user_func_array('template_prepro...', Array)
#4 /home/account/docroot/core/lib/Drupal/Core/Render/Renderer.php(433): Drupal\Core\Theme\ThemeManager->render('block', Array)
#5 /home/account/docroot/core/lib/Drupal/Core/Render/Renderer.php(446): Drupal\Core\Render\Renderer->doRender(Array)
#6 /home/account/docroot/core/lib/Drupal/Core/Render/Renderer.php(204): Drupal\Core\Render\Renderer->doRender(Array, false)
#7 /home/account/docroot/core/lib/Drupal/Core/Template/TwigExtension.php(479): Drupal\Core\Render\Renderer->render(Array)
#8 /home/account/docroot/sites/default/files/php/twig/64bec8f83bffd_bs-2col.html.twig_8FciBnmm6CaS_77rcBJ9sxzFc/0erVCbaYelXjEhKJlt6KpWrpIjgmV-9eRs8198BlHVQ.php(78): ... 

Steps to reproduce

  1. Add a Context
  2. For a Content Type, Manage the Layout of a Display
  3. In a Layout that uses Layout Builder, configure a block's Context Visibility with a Context.
  4. Save Layout
  5. View page that uses the Layout
  6. Warnings will appear for blocks that are not to show content.

Proposed resolution

Unsure

Remaining tasks

Need to review code to see why the block is still trying to render. I need to test this on a new install with just Layout Builder, Context and Layout Builder Context Integration

πŸ› Bug report
Status

Active

Version

1.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States GreenSkunk Great Valley, NY

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @GreenSkunk
  • Assigned to kevinquillen
  • πŸ‡ΊπŸ‡ΈUnited States kevinquillen

    Thank you for that report.

  • πŸ‡ΊπŸ‡ΈUnited States kevinquillen

    Instead of unset the array, using #access FALSE should prevent it from showing when rendered:

    
            if (!$visible && $all_must_pass) {
              $build['content']['#access'] = FALSE;
            }
    

    I've updated tests to account for this, and items were not visible to me in manual testing and no logs issues were present. Give the dev release a try.

  • πŸ‡ΊπŸ‡ΈUnited States kevinquillen

    I checked to see if I could locate how Context handles blocks normally but could not find much. I think template_preprocess_block will be called no matter what since nothing is actually preventing the execution of that code, its tagging the render array as not being displayed. I need to review the preRenderBlock method of the Blocks ContextReaction plugin for some insight.

    Previously, the logs were occurring because 'content' was being unset from the array which resulted in "Warning: Undefined array key "content" in template_preprocess_block() ".

  • πŸ‡ΊπŸ‡ΈUnited States GreenSkunk Great Valley, NY

    Kevin it's a good start! This worked for the blocks but any sections with context do not seem to follow any context rules now.

    Messed with Pre_Render

    In /src/Utility/Visibility.php, I replaced $build['content']['#access'] = FALSE with $build['#pre_render']['#printed'] = TRUE but elements are still rendering. Maybe something else is in the pre_render array?

    Stuff that I've been reading

    Render Arrays section of the Render API docs β†’
    Code Blocks.php ContextReaction - Context

  • πŸ‡ΊπŸ‡ΈUnited States kevinquillen

    I am a little lost. I have put back $build['content'] = [] instead of unset it in the dev branch, the context rules all appear to work for section or block. hook_preprocess_block was only called for visible blocks.

  • πŸ‡ΊπŸ‡ΈUnited States amanire

    I hope this isn't forgotten. The commit is an improvement but results in a couple of nested empty divs, which were visible in my theme. I'm not sure what a better solution is though. It kind of seems like a core bug to assume the existence of the content key? As a workaround, I added this to the theme's theme_preprocess_block():

      if (isset($variables['content']['#access']) && $variables['content']['#access'] === false) {
        $variables['attributes']['class'][] = 'hidden';
      }
    
  • πŸ‡ΊπŸ‡ΈUnited States kevinquillen

    That could be part of it, yes. "content" is typically the property name for render array data, but it could be whatever a developer specifies it as in contrib.

    I added this to the theme

    What theme?

  • πŸ‡ΊπŸ‡ΈUnited States amanire

    Sorry that wasn't clear. My site's custom theme. I think with core, it would just result in <div></div>. In my particular case, we have an additional div in the block template which monkeyed with the spacing.

Production build 0.71.5 2024