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)

8
  • Is this really about invalidating the whole page cache or is it more about displaying a certain message at certain times?
    – leymannx
    Commented Aug 6, 2019 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.
    – 4uk4
    Commented Aug 6, 2019 at 6:40
  • @leymannx: it is about invalidating the whole cache page
    – Baud
    Commented Aug 6, 2019 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
    Commented Aug 6, 2019 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().
    – 4uk4
    Commented Aug 6, 2019 at 8:22

1 Answer 1

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.

2
  • 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
    Commented Aug 6, 2019 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
    – 4uk4
    Commented Aug 6, 2019 at 11:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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