Skip to main content
Fixed a typo of twig syntax of filters without using pipe instead of dot
Source Link

The problem is, that the cache tag block_content:[id] does not bubble up and the tag is missing in the cache entry. Without this cache tag the cache entry can't be invalidated when saving a modified custom block.

TwoHere are two workarounds:

Twig template (Workaround 1)

If you theme a block template and you render single fields

{{ content.field_field1 }}
{{ content.field_field2 }}

then you also need to render the rest of content:

{{ content.withoutcontent|without('field_field1', 'field_field2') }}

That's because content contains the cache tag of the block content entity, which otherwise won't bubble up.

Preprocess (Workaround 2)

As an alternative option for rendering {{ content }} you can add the cache tag at the top of variables in preprocess.

mytheme.theme

function mytheme_preprocess_block(&$variables) {
  if ($variables['base_plugin_id'] == 'block_content') {
    $renderer = \Drupal::service('renderer');
    $renderer->addCacheableDependency($variables, $variables['content']['#block_content']);
  }
}

Then you no longer depend on the twig template to render all of content.

You'll find in Drupal\block\BlockViewBuilder::preRender() more workarounds for issues with bubbling up data from the content render array. You could use this code, which there is only applied in special circumstances, for all cache data from block content to bubble up to the top level:

use Drupal\Core\Cache\CacheableMetadata;

function mytheme_preprocess_block(&$variables) {
  $content = $variables['content'];
  CacheableMetadata::createFromRenderArray($variables)
          ->merge(CacheableMetadata::createFromRenderArray($content))
          ->applyTo($variables);
}

But I don't know which side effects that would have in other places. If it would be that easy the block view builder would do this already. So it's better to tackle only that specific problem with the one missing tag and use the first version of the preprocess function.

The problem is, that the cache tag block_content:[id] does not bubble up and the tag is missing in the cache entry. Without this cache tag the cache entry can't be invalidated when saving a modified custom block.

Two workarounds:

Twig template

If you theme a block template and you render single fields

{{ content.field_field1 }}
{{ content.field_field2 }}

then you also need to render the rest of content:

{{ content.without('field_field1', 'field_field2') }}

That's because content contains the cache tag of the block content entity, which otherwise won't bubble up.

Preprocess

As an alternative option for rendering {{ content }} you can add the cache tag at the top of variables in preprocess.

mytheme.theme

function mytheme_preprocess_block(&$variables) {
  if ($variables['base_plugin_id'] == 'block_content') {
    $renderer = \Drupal::service('renderer');
    $renderer->addCacheableDependency($variables, $variables['content']['#block_content']);
  }
}

Then you no longer depend on the twig template to render all of content.

You'll find in Drupal\block\BlockViewBuilder::preRender() more workarounds for issues with bubbling up data from the content render array. You could use this code, which there is only applied in special circumstances, for all cache data from block content to bubble up to the top level:

use Drupal\Core\Cache\CacheableMetadata;

function mytheme_preprocess_block(&$variables) {
  $content = $variables['content'];
  CacheableMetadata::createFromRenderArray($variables)
          ->merge(CacheableMetadata::createFromRenderArray($content))
          ->applyTo($variables);
}

But I don't know which side effects that would have in other places. If it would be that easy the block view builder would do this already. So it's better to tackle only that specific problem with the one missing tag and use the first version of the preprocess function.

The problem is, that the cache tag block_content:[id] does not bubble up and the tag is missing in the cache entry. Without this cache tag the cache entry can't be invalidated when saving a modified custom block.

Here are two workarounds:

Twig template (Workaround 1)

If you theme a block template and you render single fields

{{ content.field_field1 }}
{{ content.field_field2 }}

then you also need to render the rest of content:

{{ content|without('field_field1', 'field_field2') }}

That's because content contains the cache tag of the block content entity, which otherwise won't bubble up.

Preprocess (Workaround 2)

As an alternative option for rendering {{ content }} you can add the cache tag at the top of variables in preprocess.

mytheme.theme

function mytheme_preprocess_block(&$variables) {
  if ($variables['base_plugin_id'] == 'block_content') {
    $renderer = \Drupal::service('renderer');
    $renderer->addCacheableDependency($variables, $variables['content']['#block_content']);
  }
}

Then you no longer depend on the twig template to render all of content.

You'll find in Drupal\block\BlockViewBuilder::preRender() more workarounds for issues with bubbling up data from the content render array. You could use this code, which there is only applied in special circumstances, for all cache data from block content to bubble up to the top level:

use Drupal\Core\Cache\CacheableMetadata;

function mytheme_preprocess_block(&$variables) {
  $content = $variables['content'];
  CacheableMetadata::createFromRenderArray($variables)
          ->merge(CacheableMetadata::createFromRenderArray($content))
          ->applyTo($variables);
}

But I don't know which side effects that would have in other places. If it would be that easy the block view builder would do this already. So it's better to tackle only that specific problem with the one missing tag and use the first version of the preprocess function.

added 923 characters in body
Source Link
4uk4
  • 101.7k
  • 7
  • 173
  • 217

The problem is, that the cache tag block_content:[id] does not bubble up and the tag is missing in the cache entry. ThenWithout this cache tag the cache entry can't be invalidedinvalidated when saving a modified custom block.

Two workarounds:

Twig template

If you theme a block template and you render single fields

{{ content.field_field1 }}
{{ content.field_field2 }}

You havethen you also need to render the rest of the content without the fieldscontent:

{{ content.without('field_field1', 'field_field2') }}

The reason is, thatThat's because content contains the cache tag of the block content is in the variable content and you need to render it so that it canentity, which otherwise won't bubble up.

Preprocess

As an alternative option if you don't want to render the variablefor rendering {{ content }}, you can add the cache tag at the top of the variablesvariables in preprocess.

mytheme.theme

function mytheme_preprocess_block(&$variables) {
  if ($variables['base_plugin_id'] == 'block_content') {
    $renderer = \Drupal::service('renderer');
    $renderer->addCacheableDependency($variables, $variables['content']['#block_content']);
  }
}

Then you no longer depend on the twig template to render all of content.

You'll find in Drupal\block\BlockViewBuilder::preRender() more workarounds for issues with bubbling up data from the content render array. You could use this code, which there is only applied in special circumstances, for all cache data from block content to bubble up to the top level:

use Drupal\Core\Cache\CacheableMetadata;

function mytheme_preprocess_block(&$variables) {
  $content = $variables['content'];
  CacheableMetadata::createFromRenderArray($variables)
          ->merge(CacheableMetadata::createFromRenderArray($content))
          ->applyTo($variables);
}

But I don't know which side effects that would have in other places. If it would be that easy the block view builder would do this already. So it's better to tackle only that specific problem with the one missing tag and use the first version of the preprocess function.

The problem is, that the cache tag block_content:[id] does not bubble up and the tag is missing in the cache entry. Then the cache entry can't be invalided when saving a modified custom block.

Two workarounds:

Twig template

If you theme a block template and you render single fields

{{ content.field_field1 }}
{{ content.field_field2 }}

You have also to render the rest of the content without the fields

{{ content.without('field_field1', 'field_field2') }}

The reason is, that the cache tag of the block content is in the variable content and you need to render it so that it can bubble up.

Preprocess

As an alternative option if you don't want to render the variable content, you can add the cache tag at the top of the variables in preprocess.

mytheme.theme

function mytheme_preprocess_block(&$variables) {
  if ($variables['base_plugin_id'] == 'block_content') {
    $renderer = \Drupal::service('renderer');
    $renderer->addCacheableDependency($variables, $variables['content']['#block_content']);
  }
}

The problem is, that the cache tag block_content:[id] does not bubble up and the tag is missing in the cache entry. Without this cache tag the cache entry can't be invalidated when saving a modified custom block.

Two workarounds:

Twig template

If you theme a block template and you render single fields

{{ content.field_field1 }}
{{ content.field_field2 }}

then you also need to render the rest of content:

{{ content.without('field_field1', 'field_field2') }}

That's because content contains the cache tag of the block content entity, which otherwise won't bubble up.

Preprocess

As an alternative option for rendering {{ content }} you can add the cache tag at the top of variables in preprocess.

mytheme.theme

function mytheme_preprocess_block(&$variables) {
  if ($variables['base_plugin_id'] == 'block_content') {
    $renderer = \Drupal::service('renderer');
    $renderer->addCacheableDependency($variables, $variables['content']['#block_content']);
  }
}

Then you no longer depend on the twig template to render all of content.

You'll find in Drupal\block\BlockViewBuilder::preRender() more workarounds for issues with bubbling up data from the content render array. You could use this code, which there is only applied in special circumstances, for all cache data from block content to bubble up to the top level:

use Drupal\Core\Cache\CacheableMetadata;

function mytheme_preprocess_block(&$variables) {
  $content = $variables['content'];
  CacheableMetadata::createFromRenderArray($variables)
          ->merge(CacheableMetadata::createFromRenderArray($content))
          ->applyTo($variables);
}

But I don't know which side effects that would have in other places. If it would be that easy the block view builder would do this already. So it's better to tackle only that specific problem with the one missing tag and use the first version of the preprocess function.

Source Link
4uk4
  • 101.7k
  • 7
  • 173
  • 217

The problem is, that the cache tag block_content:[id] does not bubble up and the tag is missing in the cache entry. Then the cache entry can't be invalided when saving a modified custom block.

Two workarounds:

Twig template

If you theme a block template and you render single fields

{{ content.field_field1 }}
{{ content.field_field2 }}

You have also to render the rest of the content without the fields

{{ content.without('field_field1', 'field_field2') }}

The reason is, that the cache tag of the block content is in the variable content and you need to render it so that it can bubble up.

Preprocess

As an alternative option if you don't want to render the variable content, you can add the cache tag at the top of the variables in preprocess.

mytheme.theme

function mytheme_preprocess_block(&$variables) {
  if ($variables['base_plugin_id'] == 'block_content') {
    $renderer = \Drupal::service('renderer');
    $renderer->addCacheableDependency($variables, $variables['content']['#block_content']);
  }
}