web-dev-qa-db-ja.com

2つのビューを同じtwigテンプレートでレンダリングする方法

同じtwigテンプレートで2つのビューをレンダリングしたいのですが、そのうちの1つだけがレンダリングされ、2番目のビューは常に最初のビューと同じコンテンツでオーバーライドされます。
「連絡先」というコンテンツタイプがあり、そのノードが表示されている場合(フルビュー)、ノードフィールドの後の同じページに2つのビューをレンダリングしたいと考えています。 twig template node--contacts.html.twigを使用します:

_.....  node fields twig template .... 
{{ viewCalls }}  
....  
{{ viewAppointments }}  
....
_

そして、私の.themeファイルのfunction my_theme_preprocess_node(&$variables)

_....  
$view = \Drupal\views\Views::getView('view_calls');
$view->setDisplay('default');
$view->setArguments(array($variables['node']->id()));
$view->setOffset(0);
$view->execute();
$variables['viewCalls'] = $view->render();

$view2 = \Drupal\views\Views::getView('view_appointments');
$view2->setDisplay('default');
$view2->setArguments(array($variables['node']->id()));
$view2->setOffset(0);
$view2->execute();
$variables['viewAppointments'] = $view2->render();
.....
_

すでに述べたように、2番目のビューには常に最初のビューと同じコンテンツが表示されます。レンダリングの順序を逆にすると、コンテンツも逆になり、最初にレンダリングされたものが唯一表示され、常に2回表示されます。 _{{ viewCalls }}_と_{{ viewAppointments }}_は常に同じコンテンツを取得するためです。

6
briast

同じコンテンツを取得する理由は、render()メソッドを呼び出すときに取得するレンダー配列の_#cache_プロパティが原因です。

具体的には、コードの前半でsetOffset()を呼び出すことにより、レンダー配列にキャッシュキーを暗黙的に設定しています( ここ を参照)。

_$this->element['#cache']['keys'][] = 'offset:' . $offset;
_

このキャッシュキー設定は、レンダー配列の_#theme_プロパティと組み合わせて(_views_view_)両方のビューで同じであり、2番目のビューを含めると、最初のビューのキャッシュバージョンが取得されます。 1つは、[_#theme_] + [_#cache_] [keys]の組み合わせが両方のビューで同一であるためです。

それを回避するには、次のことができます。

  1. これらのビューのキャッシュを完全に削除する、または
  2. setOffset()の使用を避ける、または
  3. より具体的なキーをキャッシュに追加して、ビューごとに異なるキャッシュを作成します。例えば。

    _$variables['viewCalls']['#cache']['keys'] = 
      array_merge(
        $variables['viewCalls']['#cache']['keys'], 
        array('viewCalls')
      );
    ...
    $variables['viewAppointments']['#cache']['keys'] = 
      array_merge(
        $variables['viewAppointments']['#cache']['keys'],
        array('viewAppointments')
      );
    _

私は3.オプションを使用してケースをテストしましたが、期待どおりに機能しました。別のモジュールを使用する前に、元のコードに固執し、両方のレンダー配列の_#cache_プロパティを適切に変更してみてください。

幸運を!

10

同じ2つのビューをレンダリングするTwigテンプレートでrender要素viewを使用:

$variables['viewCalls'] = [
  '#type' => 'view',
  '#name' => 'view_calls',
  '#display_id' => 'default',
  '#arguments' => [$variables['node']->id()],
];

$variables['viewAppointments'] = [
  '#type' => 'view',
  '#name' => 'view_appointments',
  '#display_id' => 'default',
  '#arguments' => [$variables['node']->id()],
];
4
user89751

コードに少なくとも1つのタイプミスがあります。 _$variables['viewAppointments ']_のスペースを削除します。


あるいは、 Twig Tweak を使用することもできます。これは、テンプレートに直接ビューを配置するために使用できる機能を提供します。

_{{ drupal_view('who_s_new', 'block_1', arg_1, arg_2, arg_3) }}`
_

Twig Tweakは、Twig拡張機能を提供する小さなモジュールであり、開発エクスペリエンスを改善できるいくつかの便利な関数とフィルターを備えています。

Twig Tweak and Views の完全なガイドをお読みください。

Twig Tweakのdrupal_view()メソッドは、Twigコード内の埋め込みビューへのアクセスを提供します。これには、別のビューの各行内からの動的なものも含まれます。この機能は、提供されたネストを実現する代替メソッドを提供します ビューフィールドビュー モジュール。

3
leymannx