Jak wyłączyć Twig i zablokować pamięć podręczną dla określonego modułu?

15

Pracuję nad modułem w Drupal 8, który pobiera dane wrażliwe na czas z zewnętrznego interfejsu API REST. Dane są przetwarzane i przekazywane do bloku. Ostateczne dane są wysyłane do szablonu Twig, takiego jak:

...

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

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

  return $build;
}

Nie działa to w środowisku produkcyjnym, w którym włączona jest pamięć podręczna, a renderowane dane są przestarzałe. Jak wyłączyć pamięć podręczną tylko dla mojego modułu i czy muszę to zrobić zarówno dla szablonu Twig, jak i wtyczki Block?

estrar
źródło

Odpowiedzi:

27

Możesz kontrolować pamięć podręczną w tablicy renderowania za pomocą elementu #cache.

Aby wyłączyć pamięć podręczną, dodaj:

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

W takim przypadku blok nie będzie buforowany dla zalogowanych użytkowników lub anonimowych użytkowników z sesją.

Jeśli chcesz wyłączyć pamięć podręczną dla anonimowych użytkowników bez sesji:

Wyłącz go albo całkowicie odinstalowując moduł page_cache, albo uruchamiając przełącznik kill, zobacz Jak mogę zapobiec buforowaniu określonej strony? na przykład.

Buforowanie kodu gałązki nie jest z tym związane, kod gałązki jest buforowany tylko raz, przy pierwszym użyciu po wyczyszczeniu pamięci podręcznej.

(edytuj zgodnie z komentarzami Berdira)

4k4
źródło
Przypuszczam, że kontekst pamięci podręcznej nie pomoże w tym konkretnym przypadku, ale być może chcesz użyć rzeczywistego maksymalnego wieku zamiast 0, który całkowicie zablokował buforowanie, np. 60. Nie jestem pewien, jak wrażliwe są twoje dane, ale zazwyczaj rzeczy mogą być w pamięci podręcznej przez minutę lub kilka. Pamiętaj też, że maksymalny wiek nie wpływa na anonimowy bufor strony. Jeśli potrzebujesz tego dla anonimowych użytkowników, musisz to całkowicie wyłączyć lub pobrać dane za pomocą javascript.
Berdir
@Berdir: Używam max-age = 0 dla anonimowych użytkowników, ale z sesjami. Działa to teraz w dev. Czy uważasz, że jest to w porządku w przypadku produkcji? Co masz na myśli przez wyłączenie całkowicie?
4k4
W porządku, jeśli masz sesje, to działa. Wyłącz go albo całkowicie odinstalowując moduł page_cache, albo uruchamiając przełącznik kill, patrz na przykład drupal.stackexchange.com/questions/151254/ ...
Berdir
Dziękuję za wspaniałe informacje, dodałem to w odpowiedzi.
4k4
1
$ build ['# cache'] ['max-age'] = 0; zrobił lewę !!! Piwa dookoła! :)
Sorin
6

Aby zatrzymać buforowanie określonego bloku, użyj następującej funkcji:

/**
 * 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;
  }
}
Echo
źródło
Doskonała odpowiedź.
Uczeń
2

Wyłącz pamięć podręczną dla określonej strony / typu zawartości / kontrolera

Wyłącz pamięć podręczną niestandardowej strony z deklaracji trasy.

Jeśli chcesz wyłączyć pamięć podręczną dla kontrolera niestandardowego (moduł niestandardowy), masz no_cacheopcję (YOUR_MODULE.routing.yml). Przykład: Plik: 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'

Dodano opcję trasy „no_cache”, aby oznaczyć odpowiedzi trasy jako nieusuwalne

Vladislav
źródło
0

Aby zapobiec buforowaniu określonego bloku:

dodaj poniższy kod w pliku theme_name.theme

function theme_name_preprocess_block(&$variables) {
  if ($variables['plugin_id'] == 'block_id') {
    $variables['#cache']['max-age'] = 0;
  }
}
Rimi B.
źródło
0

Aby wyłączyć pamięć podręczną dla typu bloku, należy wstępnie przetworzyć blok tego typu i ustawić max_age na 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;
        }

      }


    }
Wasim Khan
źródło