14

I'm working on a module in Drupal 8 which retrieves time sensitive data from an external REST api. The data is processed and forwarded to a Block. The final data is sent to a Twig template like so:

...

public function build() {
  $build = [];

  $build['ticker_block'] = [
    '#theme' => 'module_theme',
    '#data' => $myService->data(),
  ];

  return $build;
}

This doesn't work on the production environment where cache is enabled and the rendered data shows up as stale. How do I disable cache for my module only, and do I have to do it for both the Twig template and Block plugin?

26

You can control the cache in the render array with the #cache element.

To disable the cache add:

$build['#cache']['max-age'] = 0;

In this case the block will not be cached for logged in users or anonymous users with a session.

If you want to disable the cache for anonymous users without a session:

Disable it either by uninstalling the page_cache module completely or by triggering the kill switch, see How can I prevent a particular page being cached? for example.

The caching of the twig code is not connected to this, the twig code is only cached once, the first time it is used after you cleared the cache.

(edit acc. to comments of Berdir)

  • I suppose a cache context won't help in this specific case, but maybe you want to use an actual max-age instead of 0 which disabled caching completely, like 60. Not sure how time sensitive your data is, but usually, things can be cached for a minute or a few. Also, note that max-age does not affect the anonymous page cache. If you need this for anonymous users, you need to disable that completely or fetch the data using javascript. – Berdir Dec 29 '15 at 16:51
  • @Berdir: I use the max-age=0 for anonymous users, but with sessions. This is working now in dev. Do you think this is OK for production? What do you mean with disable completely? – 4k4 Dec 29 '15 at 17:36
  • It's fine if you have sessions, then it works. Disable it either by uninstalling the page_cache module completely or by triggering the kill switch, see drupal.stackexchange.com/questions/151254/… for example. – Berdir Dec 29 '15 at 17:38
  • Thank you for the great info, i've added this in the answer. – 4k4 Dec 29 '15 at 17:52
  • 1
    $build['#cache']['max-age'] = 0; did the trick !!! Beers all round! :) – Sorin Jan 12 '16 at 16:18
6

To stop caching a specific block:

/**
 * Implements hook_preprocess_HOOK() for block.html.twig.
 */
function template-name_preprocess_block(&$vars) {
  if($vars['derivative_plugin_id'] == 'add-block-id-name') {
    //-- This stops the block being cache in drupal 8
    $vars['#cache']['max-age'] = 0;

  }
  • Excellent answer. – Pupil Mar 18 at 5:15
2

Disable cache for a specific page/content type/controller

Disable cache for a custom page from route declaration.

If you want to disable cache for a custom controller (Custom module), You have no_cache option (YOUR_MODULE.routing.yml). Example : File : mymodule.routing.yml

mymodule.myroute:
  path: '/mymodule/mypage'
  defaults:
    _controller: '\Drupal\mymodule\Controller\Pages::mypage'
    _title: 'No cache page'
  requirements:
    _access: 'TRUE'
  options:
    no_cache: 'TRUE'

Added 'no_cache' route option to mark a route's responses as uncacheable

0

To prevent caching of a particular block:

add the below code in theme_name.theme file

function theme_name_preprocess_block(&$variables) {
  if ($variables['plugin_id'] == 'block_id') {
    $variables['#cache']['max-age'] = 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.