drupal_block() in drupal view's custom text field's render array not refreshed when extra cache tags are added via preprocess.

Created on 2 September 2022, almost 2 years ago
Updated 6 January 2024, 6 months ago

Problem/Motivation

In a Drupal view's custom text using {{ drupal_block('block_content:' ~ uuid) }} and in theme layer add extra cache tag.
Clear said cache tas \Drupal\Core\Cache\Cache::invalidateTags() (in a module's settings page though not sure if that matters).
Expect render array to be refreshed e.g. preprocess rerun again.
What happens: hook_preporcess_book__BLOCK_ID() isn't re run again.

HOWEVER

If the twig block builder is manually run in preprocess via code for views field, the extra cache tag(s) is cleared correctly.

/**
 * Implements hook_preprocess_views_view_field__VIEW_ID__DISIPLAY_ID__FIELD_NAME().
 */
function mytheme_preprocess_views_view_field__view_id__block_1__nothing(&$variables) {
  $variables['output'] = \Drupal::service('twig_tweak.block_view_builder')->build('block_content:my-uuid');
}

Steps to reproduce

Create Custom block type (/admin/structure/block/block-content/types) or use the default e.g. 'basic'
Create an instance of the block.
Create a Drupal view block of which show Drupal core custom block of type 'basic'
Add a uuid field, set to hidden
Add a custom text field with content {{ drupal_block('block_content:' ~ uuid) }}
Add the view block to the drupal block layout
Add a preprocess function in the theme layer
Use the page (see the preprocess block function run)
Clear the cache tag(s)
- e.g. config:shortcut.set.default
- @ /admin/config/user-interface/shortcut/manage/default
Refresh the page, notice the preprocess block function isn't run again

use Drupal\Core\Cache\CacheableMetadata;

/**
 * Implements hook_preprocess_block().
 */
function mytheme_preprocess_block(&$variables) {
  // Content blocks.
  if (isset($variables['elements']['#base_plugin_id']) && $variables['elements']['#base_plugin_id'] == 'block_content') {
    $block_type = $variables['elements']['content']['#block_content']->bundle();
    if ($block_type == 'basic') {
      // I'm not rerun again???????!!
      logic();
      \Drupal::messenger()->AddStatus(date('now'));
        // Add tags, both both levels just in case?
      CacheableMetadata::createFromRenderArray($variables)
        ->addCacheTags(['my_extra_tag'])
        ->applyTo($variables);
      CacheableMetadata::createFromRenderArray($variables['content'])
        ->addCacheTags(['my_extra_tag'])
        ->applyTo($variables['content']);
    }
  }
}

What I have tried but didn't work

Add extra tags in the views custom text twig.
[ This did refresh the views twig but not the block :-( ]

{% set drupal_block = drupal_block('block_content:' ~ uuid) %}
{% set drupal_block = drupal_block|merge(
  {'content': drupal_block['content']|merge(
    {'#cache': drupal_block['content']['#cache']|merge(
      {'tags': drupal_block['content']['#cache']['tags']|merge(
        ['config:shortcut.set.default']
      )}
    )}
  )}
) %}
{% set drupal_block = drupal_block|merge(
  {'content': drupal_block['content']|merge(
    {'#cache': drupal_block['content']['#cache']|merge(
      {'tags': drupal_block['content']['#cache']['tags']|merge(
        ['config:shortcut.set.default']
      )}
    )}
  )}
) %}
{{ {'#cache': {tags: ['config:shortcut.set.default']}}  }}
{{ drupal_block }}

Add extra tags in the block.html.twig

{{ {'#cache': {tags: ['config:shortcut.set.default']}} }}

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Closed: works as designed

Version

3.0

Component

Code

Created by

πŸ‡¦πŸ‡ΊAustralia silverham

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

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡·πŸ‡ΊRussia Chi

    Steps to reproduce are still very complected. If you are still capable to reproduce this, please write a test to prove the issue.

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

    I'm running into something similar, with some easier reproduction steps. In conjunction with the twig_tweak code, we are using Varnish.

    1. Create a node type, for example "US State".
    2. Create a node type, "news" with a reference field to "US State".
    3. Add a "US State" node.
    4. Add a "News" node, and set the reference to the "US State" created in step 3.
    5. Add the view that shows "News" nodes, with a contextual filter for a NID of a state.
    6. Add the following Twig to the node template for a "US State".

    {% set news_results = drupal_view_result('news', 'block_1', node.id)|length %}
    {% if news_results > 0 %}
      {{ drupal_view('news', 'block_1', node.id) }}
    {% endif %}
    

    7. View the "US State" node. You will see the block rendered with the related News item.
    8. Edit the "News" node and remove the reference to the "US State".
    9. View the "US State" node again, you will no longer see the view, as there are no results.
    10. Edit the "News" node again and add the reference to the "US State" again.
    11. View the "US State" node again, you will not see the view, even though there is a result.

    I'm assuming that this is because the node template does not have the proper cache tag after step 9, since the view doesn't render.

    In my case in particular, using drupal_view_result doesn't add cache tags. I have to first check for results as the view I am using shows a "view all" link, and it will render that always, as well as some extra HTML markup I want to only add when it makes sense.

    Full Example:

    {% set news_results = drupal_view_result('news', 'block_1', node.id)|length %}
    {% if news_results > 0 %}
      <section class="news">
        <div class="grid-container">
          <div class="grid-row">
            <div class="grid-col">
              <div class="news-list--block">
                <h3 class="news-list--title">{{ 'Recent News'|t }}</h3>
                {{ drupal_view('news', 'block_1', node.id) }}
              </div>
            </div>
          </div>
        </div>
      </section>
    {% endif %}
    
  • πŸ‡¦πŸ‡ΊAustralia gordon Melbourne

    I am not sure if this is same problem I am having but when I reversed commit 14e6be6 it solved my problem when running during testing (phpunit) on one of our custom blocks.

  • πŸ‡¦πŸ‡ΊAustralia gordon Melbourne

    I continued to investigate this and I managed to solve the problem.

    Because of the commit above I found that the caching is a bit more strict. I found that I needed to add context to the block.

    Basically my offending block was was grabbing the node from the route and using that to render. So by adding context to the block so it knows that it is using the node then fixed my issues.

    I found the resolution to the issue from #2980324 πŸ“Œ Document how to use block contexts Fixed which solved the issue of the and then everything worked as required.

  • Status changed to Closed: works as designed 6 months ago
  • πŸ‡·πŸ‡ΊRussia Chi

    Added an example of rendering block with context to Cheat Sheet.
    Closing this issue as there is nothing doable here.

Production build 0.69.0 2024