1

This issue is on a Drupal 8 site. I have no reason to think it would behave any different on Drupal 9.

We have a scenario where we are having trouble with caching of a custom block.

This block replicates the behaviour of the Login block in that it checks for an authentication state and presents either the user.login or user.logout route.

This looks to be working.

We also have a login state happening where a user account can be "Not Quite Logged In" (NQLI). We are extending Terms with an IP field and adding an IP Login User user reference field. When a user hits the site and they are not logged in we check if their IP matches one mentioned on the Terms and if one matches the referenced user is programatically logged in.

When a NQLI user is logged in the Login block still presents a "Log in" link. This is the desired behaviour so the user can still access the login page to log in as an actual personal account.

This is working also.

When a user has accessed the site from a known IP and is logged in as a NQLI user, clicks the "Log in" link, logs in as their own account and is redirected back to the page they came from they are successfully logged in as that personal account.

This process works.

What doesn't work is that the "Log in" menu item is still present in that block on this page. If you click off to any other page the "My account" and "Log out" links are there as expected. If you click back to the page you logged in from it still holds the "Log in" link.

We've tried clearing the cache with \Drupal::service('cache.render')->invalidateAll(); in hook_user_login() and hook_preprocess_html().

This is one of my first Drupal 8+ projects. I've been working with Drupal since 4.6 and am very much feeling like a junior dev once again. I'm hoping that there is an obvious place or process to do this that I've just not been able to find. My google-fu has reached its limit on this one.

4
  • 1
    You need to add cache contexts to your block. Cache contexts tell Drupal that the block needs to be cached differently for different circumstances. In your case, whether or not the user is logged in drupal.org/docs/drupal-apis/cache-api/cache-contexts
    – Jaypan
    Commented Mar 15, 2021 at 4:53
  • Thanks @Jaypan. Digging into that now.
    – Gold
    Commented Mar 15, 2021 at 19:09
  • Thanks @Jaypan, that did the trick. Once I figured those out things just fell into place. If you would like to post that comment as an answer that would get my upvote.
    – Gold
    Commented Mar 15, 2021 at 22:57
  • 1
    Done. And it's a nice system once you understand it, it just takes a bit of time to understand how it works. Now that you have understood cache contexts, you should look at cache tags. Cache tags allow you to say which content your block is dependent upon, so that if/when they are altered (re-saved), your block cache is expired and regenerated the next time it is requested. For example, if you were outputting the username, you could add a cache tag for that user, so that if/when they update their username, anything with the cache tag for that user is expired - including your block.
    – Jaypan
    Commented Mar 15, 2021 at 23:23

1 Answer 1

2

You need to add cache contexts to your block. Cache contexts tell Drupal that the block needs to be cached differently for different circumstances. In your case, whether or not the user is logged in. you can read more about it here: https://www.drupal.org/docs/drupal-apis/cache-api/cache-contexts

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.