1

I have a block plugin that displays different dynamic content depending on whether you're logged in or not. I attempted enabling this by setting the max-age setting in the #cache attribute of my render array to 0 like so

    if ($user->hasRole('anonymous')) {
            if ($loginrequired) {
                $content = [
                    '#markup' => '<p> Login required. <a href="/user/login">Click Here to Login</a></p>',
                ];
                return $content;
            }
    }
    $content = [
        'header'   => [
            '#markup' => $header_text,
        ],
        '#cache'   => [
            'max-age' => 0,
        ],
        $webform,
    ];
    return $content;

The dynamic content updates for logged in users, but for anonymous users it just displays exactly what the logged in user saw, instead of showing the login required message.

After doing some research it seems that drupal ignores max-cache for anonymous visitors and cache contexts would be required, according to this page

Disable form or block cache for anonymous users?

So I changed my code to reflect this

        '#cache'    => [
            'max-age'  => 0,
            'contexts' => ['user.roles']
        ],

I used user.roles since the content depended on whether the user was logged in or not. This had no effect. I then tried.

        '#cache'    => [
            'max-age'  => 0,
            'contexts' => ['user.roles:anonymous']
        ],

This also had no effect. Why does my method not work? What cache settings are required in order for the cache to be disabled even for anonymous users? Or is there a completely different method I should be using?

Note: I do not want to disable caching site wide. I would like to be able to disable caching on a plugin to plugin basis.

UPDATE: Looking at examples I also tried

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

but that didn't work either.

1 Answer 1

0

The issue was that I had different render arrays set depending on whether the user was logged in or not, but the cache context only applied to one of the render arrays but not the other. If I have different possible render arrays being returned every single one needs to have the cache settings added.

I resolved the issue by changing my code to

if ($user->hasRole('anonymous')) {
        if ($loginrequired) {
            $content = [
                '#markup' => '<p> Login required. <a href="/user/login">Click Here to Login</a></p>',
                '#cache'   => [
                     'max-age' => 0,
                     'contexts' => ['url.path']
                 ],
            ];
            return $content;
        }
}
$content = [
    'header'   => [
        '#markup' => $header_text,
    ],
    '#cache'   => [
        'max-age' => 0,
        'contexts' => ['url.path']
    ],
    $webform,
];
return $content;

Your Answer

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

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