Dans mon projet actuel, je dois modifier les modèles de nœuds en fonction de la page de destination précédemment visitée. Mon idée est que, lorsqu'un visiteur visite l'une de ces pages de destination, un cookie est défini et les modèles de nœuds suivants sont modifiés en fonction de ce cookie.
J'ai trois pages de vue servant de points d'entrée pour mes visiteurs:
myproject.com/tv
myproject.com/mobile
myproject.com/infopoint
Dans le prétraitement du thème, je vérifie/configure un cookie et attribue une variable de modèle. Les modèles Twig font des modifications mineures en fonction de cette variable:
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'];
}
}
}
Dans services.yml, j'ai activé le contexte de cache des cookies
parameters:
renderer.config:
required_cache_contexts: ['languages:language_interface', 'theme', 'user.permissions', 'url.site', 'cookies:Drupal.visitor.device']
Dans mes modèles Twig j'ai plusieurs morceaux de code comme celui-ci:
{% if MYTHEME.device == 'tv' %}
<!-- code here -->
{% else %}
<!-- other design here -->
{% endif %}
Malheureusement, le code ne fonctionne pas vraiment. Sur les pages d'entrée, la variable de thème device
est toujours correcte, mais le cookie n'est pas mis à jour (il semble que seule la première occurrence non mise en cache définit le cookie. J'ai même la situation étrange que le cookie et twig variable are not equal.). Sur les modèles de nœuds, la variable de thème n'est pas définie correctement.
Des idées sur la façon de faire fonctionner le code ci-dessus?
PS: En raison des vues lentes avec des calculs de géo-distance, la désactivation du cache n'est pas une option, je dois également fournir des pages en cache pour les utilisateurs anonymes.
J'ai mis à jour le code dans la question, le code fonctionne maintenant. C'était presque terminé, j'avais cependant fait quelques erreurs simples:
Internal page cache
. Seul le module Internal dynamic page cache
Est autorisé.user_cookie_save()
préfixe le nom du cookie avec Drupal.visitor.
C'est le vrai nom que vous verrez également dans la console de développement de votre navigateur. Mais lors de la vérification des noms de cookies en PHP, les points et les espaces sont convertis en traits de soulignement. Cela signifie que l'utilisation de user_cookie_save(['mycookie' => 'some_value']);
crée un cookie avec un "vrai" nom de Drupal.visitor.mycookie
, Mais en 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'])