In my current project I need to alter node templates depending on previously visited landing page. My idea is that, when a visitor visits one of these landing pages, a cookie will be set, and subsequent node templates will be altered depending on that cookie.
I've got three view pages serving as entry points for my visitors:
myproject.com/tv
myproject.com/mobile
myproject.com/infopoint
In theme preprocess I'm checking/setting a cookie and assigning a template variable. The Twig templates do minor modifications depending on that 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'];
}
}
}
In services.yml I've activated the cookies cache context
parameters:
renderer.config:
required_cache_contexts: ['languages:language_interface', 'theme', 'user.permissions', 'url.site', 'cookies:Drupal.visitor.device']
In my Twig templates I've got multiple code pieces like this:
{% if MYTHEME.device == 'tv' %}
<!-- code here -->
{% else %}
<!-- other design here -->
{% endif %}
Sadly the code doesn't really work. On the entry pages, the device
theme variable is always correct, but the cookie is not updated (seems as if only first uncached hit sets the cookie. I even have the weird situation that cookie and twig variable aren't equal.). On node templates the theme variable isn't set correctly at all.
Any ideas how to get the code above working?
PS: Due slow views with geo-distance calculations disabling cache is not an option, I need to provide cached pages also for anonymous users.