1

In my custom page.html.twig I have a variable that adds an alert bar to the page if the user is expired. This is based on a custom user field.

It's generated here in my custom_theme.theme file like so.

function custom_theme_preprocess_page(&$variables){
    $uid = \Drupal::currentUser()->id();
    $current_user = \Drupal\user\Entity\User::load($uid);
    $now =strtotime('now');
    $paidThrough = strtotime($current_user->field_expiration_date->value);
    if($paidThrough < $now){
         $variables['alert'] = 'Your account has expired';
    }
    $variables['#cache'] = [
        'max-age'  => 0,
        'contexts' => ['url.path']
    ];

}

and then inside my page.html.twig file I have

<div class="alert">{{ alert }}</div>
<div class="main">{{ page.content }}</div>

Even though some users have been updated to no longer see the alert, they still see it on the home page. If they click around to different pages they no longer see the report, but on the home page they always see it. I'm guessing they no longer see it on other pages because those pages were not cached for them. Also I'm using the page manager and panels plugins for many of these pages including the home page.

Why would twig variables be cached for authenticated users? Is there a way to prevent twig variables from being cached?

I did see a similar post here Twig/Drupal caching and dynamic variables But I'm not sure how that would work or how to implement that.

UPDATE: It was mentioned that using $variables['#cache']['contexts'][] = 'url'; would be problematic but if this is a dynamic alert box that appears on every page wouldn't that be necessary?

UPDATE 2: Actually it occurred to me that I'm already using

$variables['#cache']['contexts'][] = 'url'; 

in my own way here

$variables['#cache'] = [
    'max-age'  => 0,
    'contexts' => ['url.path']
];

But that didn't seem to resolve the issue. Unless 'url' and 'url.path' makes a difference.

1

This seems a bit chaotic. You don't need an url context on a page, because this is set already. You don't need other cache data, if you have max-age = 0. If your message depend on the current user, you need a user context. And always add cache data, never replace it.

I would use a block for the message which, if it depends on the current user, can be auto-placeholdered. Then you don't need to disable page caching, which is better for performance, see https://www.drupal.org/docs/8/api/render-api/auto-placeholdering

  • If I load the block from the .theme file and add it as a twig variable would that still work? – Matt Aug 21 '17 at 15:32
  • Also it doesn't just depend on the user, it can also change as soon as that user field changes. So it's not just when different users login. – Matt Aug 21 '17 at 16:19
  • For changes in the user field you need a cache tag for the user id. Or use max-age=0, if you want to recalculate the message each time, this can also be placeholdered. – 4k4 Aug 21 '17 at 16:47

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.