1

I've built a custom block using BlockBase and as the content this block displays is different depending on the URL it's accessed via (a query parameter is passed in the URL) this block needs to either not cache, or cache relative only to the specific URL it's accessed using.

I've tried the following:

return array(
    '#theme' => 'testing_block',
    '#testBlockData' => $testBlockData,
    '#cache' => array(
        'contexts' => array('url.path'),
    ),
);

Which doesn't work. So then I tried this:

return array(
    '#theme' => 'testing_block',
    '#testBlockData' => $testBlockData,
    '#cache' => array(
        'max-age' => 0,
    ),
);

This also didn't work, so I tried the two cache settings combined together:

return array(
    '#theme' => 'testing_block',
    '#testBlockData' => $testBlockData,
    '#cache' => array(
        'contexts' => array('url.path'),
        'max-age' => 0,
    ),
);

None of these work, and I can't for the life of my figure out why. According to everything I've read, this is the right way to do it.

Is it actually possible to set a block like this not to cache in Drupal? And if so, what am I doing wrong?

  • Is this with anonymous of authenticated users? – mpdonadio Jun 5 '17 at 15:46
  • Sorry I should have specified that. This is with anonymous users, I haven't actually tested it with authenticated users. – Sean Jun 5 '17 at 15:57
5

This is a known problem for anonymous requests, see this issue PageCache caching uncacheable responses (violating HTTP/1.0 spec) + D8 intentionally disabling HTTP/1.0 proxies = WTF.

Until this is resolved, put this trigger in your block build():

\Drupal::service('page_cache_kill_switch')->trigger();
  • I think the issue you wanted to reference is drupal.org/node/2352009 – Berdir Jun 5 '17 at 19:12
  • @Berdir, yes, this issue is about all aspects around this. But I linked the WTF issue intentionally, because it's straight to the point. If the internal page cache behaved like any proxy, then this would no longer be Drupal specific. You need to get the response headers right for anonymous traffic anyway to pass any kind of cache, server or client side. And like in the WTF issue mentioned, if this is resolved, you can do this in the site performance settings. – 4k4 Jun 5 '17 at 19:50
  • I've put this trigger immediately before the return statement, and this block still appears to be caching. I've also tried it at the start of the build method to no avail ... is there anything else I could be doing wrong? I'm using \Drupal::request()->query->get(...), \Drupal::entityTypeManager()->getStorage('node') and \Drupal::service('path.alias_manager')->getAliasByPath(...) are these utilising caching in any way that might be breaking this? – Sean Jun 6 '17 at 9:35
  • No, max-age = 0 and the kill switch is all you need to disable caching of blocks. But I think you have misspelled max-age, then this should work. – 4k4 Jun 6 '17 at 11:18
  • facepalm yes, that was it. Thanks for your help! – Sean Jun 7 '17 at 11:13
1

we can implement this method in blockbase

/**
   * {@inheritdoc}
   */
  public function getCacheMaxAge() {
    return 0;
  }
0

I solved it mixing both solutions:

  /**
   * {@inheritdoc}
   */
  public function getCacheMaxAge() {
    \Drupal::service('page_cache_kill_switch')->trigger();

    return 0;
  }

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.