Как отключить Twig и заблокировать кеш для определенного модуля?

15

Я работаю над модулем в Drupal 8, который получает чувствительные ко времени данные из внешнего REST API. Данные обрабатываются и отправляются в блок. Окончательные данные отправляются в шаблон Twig следующим образом:

...

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

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

  return $build;
}

Это не работает в производственной среде, в которой включен кэш, и отображаемые данные отображаются как устаревшие. Как отключить кеш только для моего модуля, и нужно ли это делать как для шаблона Twig, так и для блочного плагина?

estrar
источник

Ответы:

27

Вы можете управлять кешем в массиве рендеринга с помощью элемента #cache.

Чтобы отключить кеш, добавьте:

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

В этом случае блок не будет кэшироваться для зарегистрированных пользователей или анонимных пользователей с сеансом.

Если вы хотите отключить кеш для анонимных пользователей без сеанса:

Отключите его, полностью удалив модуль page_cache или с помощью переключателя kill, см. Как предотвратить кэширование определенной страницы? например.

Кэширование кода ветки не связано с этим, код ветки кэшируется только один раз, при первом использовании после очистки кеша.

(редактировать в соответствии с комментариями Бердира)

4k4
источник
Я полагаю, что контекст кеша не поможет в этом конкретном случае, но, возможно, вы захотите использовать фактический максимальный возраст вместо 0, который полностью отключил кэширование, например 60. Не уверен, насколько чувствительны ваши данные ко времени, но обычно вещи могут быть кэшированным на минуту или несколько. Также обратите внимание, что max-age не влияет на кеш анонимных страниц. Если вам это нужно для анонимных пользователей, вам необходимо полностью отключить это или получить данные с помощью javascript.
Бердир
@Berdir: я использую max-age = 0 для анонимных пользователей, но с сессиями. Это работает сейчас в Dev. Как вы думаете, это нормально для производства? Что вы имеете в виду с отключить полностью?
4k4
Это нормально, если у вас есть сессии, то это работает. Отключите его, либо полностью удалив модуль page_cache, либо с помощью переключателя kill, см., Например , drupal.stackexchange.com/questions/151254/… .
Бердир
Спасибо за отличную информацию, я добавил это в ответ.
4k4
1
$ build ['# cache'] ['max-age'] = 0; сделал трюк !!! Пиво со всех сторон! :)
Сорин
6

Чтобы остановить кэширование определенного блока, используйте следующую функцию:

/**
 * 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;
  }
}
эхо
источник
Отличный ответ.
Ученик
2

Отключить кеш для конкретной страницы / типа контента / контроллера

Отключить кэш для пользовательской страницы из объявления маршрута.

Если вы хотите отключить кэш для пользовательского контроллера (Custom module), у вас есть no_cacheопция (YOUR_MODULE.routing.yml). Пример: Файл: 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'

Добавлена ​​опция маршрута no_cache, чтобы пометить ответы маршрута как не кэшируемые

Владислав
источник
0

Чтобы предотвратить кеширование определенного блока:

добавьте приведенный ниже код в файл theme_name.theme

function theme_name_preprocess_block(&$variables) {
  if ($variables['plugin_id'] == 'block_id') {
    $variables['#cache']['max-age'] = 0;
  }
}
Рими Б
источник
0

Чтобы отключить кэш для типа блока, предварительно обработайте блок этого типа и установите для max_age значение 0.

   /**
     * Implements hook_preprocess_HOOK() for Block document templates.
     */
    function THEMENAME_preprocess_block(array &$variables) {

      //disbale cache from spotlight
      $content = $variables['elements']['content'];
      //dump($content); //check the contents
      if (isset($content['#block_content']) && $content['#block_content'] instanceof BlockContentInterface) {

        if ($content['#block_content']->bundle() == 'BLOCK_TYPE') {
          $variables['#cache']['max-age'] = 0;
        }

      }


    }
Васим Хан
источник