1

I have a twig template that must be rendered differently on smaller displays (mobile devices) or a larger displays. For example, my breakcrumb is moved to the footer for mobile devices.

In order to check the device type, i use Mobile Detect module and i have created a new cache_context named "mobile_detect". I want to use this cache_context in my "node--page.html.twig".

Currently the cache context seems to work only when i'm logged in as "super user" but when i'm not logged in, the node is cached once and the cache context is not used.

Do you have any ideas why this doesn't work ?

Thanks a lot and Sorry for my bad English :(

My preprocess :

function theme_preprocess_node(&$variables)
{
    //mobile detect variable
    $mobileDetector = \Drupal::service('krs.mobile_detect');
    $variables['isMobile'] = $mobileDetector->isMobile();

    //cache context
    $variables['#cache']['contexts'][] = 'mobile_detect';

}

My twig :

{% if isMobile %}
  {# content for mobile device #}
{% endif %}

My cache_context service :

file located in my module modules/custom/customCacheContext/src/Cache

<?php

namespace Drupal\customCacheContext\Cache;

use Drupal\Core\Cache\Context;
use Drupal\Core\Cache\Context\CacheContextInterface;
use Drupal\Core\Cache\CacheableMetadata;

/**
 * Defines the MobiledetectCacheContext service, for mobile or desktop caching.
 *
 * Cache context ID: 'mobile_detect'.
 */
class MobiledetectCacheContext implements CacheContextInterface  {


    /**
     * Constructor
     */
    public function __construct(MobileDetect $mobileDetector)
    {
        $this->mobileDetector = $mobileDetector;
    }

    /**
     * {@inheritdoc}
     */
    public static function getLabel() {
        return t('Mobile Detect');
    }

    /**
     * {@inheritdoc}
     */
    public function getContext($parameters = NULL) {

        if($this->mobileDetector->isMobile()) {
            return 'mobile';
        }

        return 'desktop';

    }

    /**
     * {@inheritdoc}
     */
    public function getCacheableMetadata($parameters = NULL) {

        return new CacheableMetadata();

    }

}

My cache_context service.yml:

services:
  cache_context.mobile_detect:
    class: Drupal\customCacheContext\Cache\MobiledetectCacheContext
    arguments: ['@krs.mobile_detect']
    tags:
      - { name: cache.context }
1

I finally found the solution. My scripts work pretty well, i just forgot one little thing about the cache modules Drupal enable by default in core.

I needed to disable "internal page cache" module and only keep "dynamic page cache" enabled. In fact "internal page cache" works for anonymous users only and caches the whole page in order to get better performance. It is therefore not possible to create dynamic parts and "max-age" or "cache context" doesn't work. So if you disable the module, drupal uses by default "dynamic page cache" and "max-age" or "cache context" will work then.

I hope this helps you.

More infos here : http://wimleers.com/article/drupal-8-dynamic-page-cache

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.