1

Let say I have a webshop open from 9am to 11am (data coming from config). When the shop is closed, I would like to display a message (shop closed) and when the shop is open, my commerce product should be available. (only for 'lunch' bundle)

I have tried to update the following code: https://cornel.co/article/drupal8/page-cache-cookies-or-anything-available-http-request

Here is my try (edited with a comment from 4k4:

protected function getCacheId(Request $request)
{
    if (! isset($this->cid)) {
        $cid_parts = [
            $request->getSchemeAndHttpHost() . $request->getRequestUri(),
            $request->getRequestFormat(NULL)
        ];
        // Only cache by State of Store for some path
        if (strpos($request->getPathInfo(), '/lunches/') != false) {
            $store_state = get_store_state(); 
            $cid_parts[] = $store_state['context']; //return a string like 'open' or 'close:9:30:11:00' if closed (like before 9:30 am or after 11:00am)
        }
        $this->cid = implode(':', $cid_parts);
    }
    return $this->cid;
}

As stated by 4k4, I must create a new context which will bubble up and will invalidate the Internal Cache page.

Here is the code of

class StateStoreCacheContext implements CacheContextInterface

stored in mymodule/src/CacheContext/StateStoreCacheContext.php

public function getContext()
{
    $storeState=get_store_state();
    return $storeState['context']; //return a string like 'open' or 'close:9:30:11:00' if closed (like before 9:30 am or after 11:00am)
}

And here is mys service declaration:

services:
   cache_context.state_store_context:
    class: Drupal\mymodule\CacheContext\StateStoreCacheContext
    arguments: []
    tags:
      - { name: cache.context }

And here is the way I add my context to my page (in mythem_preprocess_node(&$vars))

$vars['#cache']['contexts'][] = 'state_store_context';

Unfortunately, my page cache is not invalidate for anonymous users (but it is ok for logged-in users)

  • Is this really about invalidating the whole page cache or is it more about displaying a certain message at certain times? – leymannx Aug 6 '19 at 4:53
  • 2
    The cache context doesn't exist, you have to create a custom one and add it to the node, a preprocess hook is OK for this. BTW you can't rely on the route name being present in the middleware, it's only there when storing the cache item but not when retrieving it. So better use the path to check the node type. – 4k4 Aug 6 '19 at 6:40
  • @leymannx: it is about invalidating the whole cache page – Baud Aug 6 '19 at 7:46
  • @4k4 I have 2 issues regarding creating a context: 1-I will have to implement get_context() with exactly the same logic as in getCacheId() (see upper)=>looks weird 2-My idea is to keep the internal page cache module, I have read somewhere else that it doesn't deal with context. Thank you for the route not being present, I will update the code – Baud Aug 6 '19 at 7:54
  • Yes, a custom cache context with exactly the same logic. You need the cache context for all other caches in Drupal like the entity render cache and the dynamic page cache and if you add the context to the node it will bubble up to all cache levels. With one exception, the Internal Page Cache, for which you are trying to find a solution in getCacheId(). – 4k4 Aug 6 '19 at 8:22
1

You have to add a cache context as well. See both answers in this topic:

How do I create a cache context in Drupal 8 that varies on user/node field data?

You add a variation to the CID of the Internal Page Cache and a custom cache context to the node, so that it can bubble up to all elements which are dynamically cached. The difference is, CIDs can't bubble up, contexts can, and so vary all render elements no matter how deep they are nested.

  • I have tried what you say (also tried to add a cache key as described in your link) but unfortunately, this is not working for anonymous. I have updated my question with all your comments. – Baud Aug 6 '19 at 10:41
  • What do you mean by not working. Did you check the database for the cache items, whether they vary by the cache keys/contexts you've added? Or the result in the browser? This is not so easy to debug because the browser caches anonymous requests, too. For debugging (and production as well) you have to adjust the browser and proxy cache max-age: /admin/config/development/performance – 4k4 Aug 6 '19 at 11:21

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.