web-dev-qa-db-ja.com

参照されるエンティティが段落ごとに個別にキャッシュされるようにするにはどうすればよいですか?

1つのページの2つの段落が同じエンティティを参照する可能性がある状況があります。

影響を受ける段落には、色を変更するフィールドがあり、この色の値は、テンプレートで使用するために(hook_preprocess_ [entity-type]を介して)参照されるエンティティに渡されます。

  • Node

    • field_paragraph

      • 段落1

        • field_colour
        • field_entity_reference(references entity:1234
      • 段落2

        • field_colour
        • field_entity_reference(references entity:1234

Paragraph 1を更新して色を変更すると、現在Paragraph 2(エンティティは、前処理されたカラー値を含めてキャッシュされるため)。

(hook_preprocess_ [entity-type]に)キャッシュ可能な依存関係を追加して、段落のキャッシュタグをエンティティに転送しようとしました。これにより、段落が更新されると、参照しているエンティティのキ​​ャッシュが無効になります。

$renderer = \Drupal::service('renderer');
$renderer->addCacheableDependency($variables, $referring_entity);

上記の$variables$variables['elements']$variables['content']に置き換えてみましたが、どちらの方法でも期待どおりに動作しないようです。

助言を歓迎します。

3
autopoietic

したがって、最も簡単なオプションは、埋め込みエンティティのキ​​ャッシュを完全に無効にすることです。

Hook_entity_view()で、$build['cache']['keys']の設定を解除します。その後も、段落レンダーキャッシュの一部としてキャッシュされますが、独自のキャッシュエントリはありません。

それらが別の場所に表示されているときにそれらをキャッシュしないようにするには、それらを段落に統合するときに特別な表示モードを使用し、そのためのキャッシュのみを無効にする必要があります。

Max-age = 0を設定することもできますが、これは「このコンテンツをまったくキャッシュしてはならない」ことを意味します。その情報は段落とホストエンティティにバブルアップし、それらはキャッシュされなくなります。それはあなたが望むものではありません。

または、アプローチを変更し、埋め込みエンティティのHTMLを変更せずに、段落レベルで設定されたクラスを通じてその色を適用することもできます。すべてに対して機能するわけではありませんが、単純な色の変更の場合は、おそらく実装が簡単です。

6
Berdir

受け入れられた回答は私にとってはうまくいきましたが、私の場合にも機能し、レンダリングされたエンティティをキャッシュしたままにする別の方法で更新したいと思います:

function hook_preprocess_paragraph(&$variables) {
  foreach (Element::children($variables['content']['field_your_field']) as $index) {
    $child = &$variables['content']['field_your_field'][$index];

    if (your view switching logic) {
      $child['#view_mode'] = 'your_new_view_mode';

      // Update cache keys
      array_pop($child['#cache']['keys']);
      $child['#cache']['keys'][] = $child['#view_mode'];
    }    
  }
}
1
Karl