現在のプロジェクトでは、以前にアクセスしたランディングページに応じてノードテンプレートを変更する必要があります。私の考えでは、訪問者がこれらのランディングページの1つにアクセスすると、Cookieが設定され、その後のノードテンプレートはそのCookieに応じて変更されます。
訪問者のエントリポイントとして機能する3つのビューページがあります。
myproject.com/tv
myproject.com/mobile
myproject.com/infopoint
テーマの前処理では、Cookieをチェック/設定し、テンプレート変数を割り当てています。 Twigテンプレートは、その変数に応じて小さな変更を行います:
function MYTHEME_preprocess(array &$variables, $hook) {
$router = \Drupal::routeMatch();
if ($route = $router->getRouteObject()) {
$view_id = $route->getDefault('view_id');
$display_id = $route->getDefault('display_id');
$view_display_plugin = $route->getOption('_view_display_plugin_id');
if ($view_id && $view_display_plugin === 'page') {
if ($view_id == 'slide') {
user_cookie_save(['device' => 'tv']);
$variables['MYTHEME']['device'] = 'tv';
}
elseif ($view_id == 'tile' && $display_id == 'mobile') {
user_cookie_save(['device' => 'mobile']);
$variables['MYTHEME']['device'] = 'mobile';
}
elseif ($view_id == 'tile' && $display_id == 'infopoint') {
user_cookie_save(['device' => 'infopoint']);
$variables['MYTHEME']['device'] = 'infopoint';
}
}
}
// user_cookie_save prefixes all cookie names with 'Drupal.visitor.'
if (isset($_COOKIE['Drupal.visitor.device']) &&
in_array($_COOKIE['Drupal.visitor.device'], ['tv', 'mobile', 'infopoint'])) {
// I'm doing design modifications in my Twig templates depending on this variable
$variables['MYTHEME']['device'] = $_COOKIE['Drupal.visitor.device'];
}
}
}
Services.ymlでcookieキャッシュコンテキストをアクティブ化しました
parameters:
renderer.config:
required_cache_contexts: ['languages:language_interface', 'theme', 'user.permissions', 'url.site', 'cookies:Drupal.visitor.device']
私のTwigテンプレートには、次のような複数のコードがあります:
{% if MYTHEME.device == 'tv' %}
<!-- code here -->
{% else %}
<!-- other design here -->
{% endif %}
残念ながら、コードは実際には機能しません。エントリページでは、device
テーマ変数は常に正しいですが、Cookieは更新されません(最初の非キャッシュヒットだけがCookieを設定するように見えます。Cookieとtwig変数が等しくありません。)ノードテンプレートで、テーマ変数がまったく正しく設定されていません。
上記のコードを機能させる方法はありますか?
PS:キャッシュを無効にする地理距離計算でビューが遅いため、キャッシュされたページを匿名ユーザーにも提供する必要があります。
質問のコードを更新しました。コードは現在機能しています。それはほぼ完全でした、しかし私はいくつかの単純な間違いをしました:
Internal page cache
_モジュールを無効にする必要があります。 _Internal dynamic page cache
_モジュールのみが許可されています。user_cookie_save()
は、Cookie名の前に_Drupal.visitor.
_を付けます。これは、ブラウザーの開発コンソールにも表示される実際の名前です。ただし、PHPでCookie名を確認する場合、ドットとスペースはアンダースコアに変換されます。つまり、user_cookie_save(['mycookie' => 'some_value']);
を使用すると、_Drupal.visitor.mycookie
_の「実際の」名前でCookieが作成されますが、PHP if ($_COOKIE['Drupal_visitor_mycookie'])
required_cache_contexts: ['cookies:Drupal_visitor_device', '...other_stuff...']
_user_cookie_save(['mycookie' => 'new_value'])
if ($_COOKIE['Drupal_visitor_mycookie'])