Drupal → Тюнинг кэширования блоков с формой

12.10.2020

По умолчанию блоки с формами кэшируются только для анонимных пользователей. Для залогинённых же друпал добавляет во все формы элемент form_token со свойством '#cache' => ['max-age' => 0] (тырк), который запрещает кэшировать блок. Чтобы этого избежать и включить кэширование блока для всех, нужно отключить генерацию form_token:

public function buildForm(array $form, FormStateInterface $form_state) {
  $form['#token'] = FALSE;
  ...
}

Это не очень безопасно, но других вариантов пока не знаю.

Если в форме будут элементы со свойством #ajax, то появится ещё одна проблема — друпал автоматически добавит для таких элементов кэш-контекст route, который заставит блок с формой генериться заново на каждой новой странице. Например, если блок выводится на 1000 страницах, то в cache_render будет 1000 вариантов этого блока. Решается добавлением в #ajax свойства url с адресом на страницу где точно будет форма, плюс специально сформированное свойство options:

public function buildForm(array $form, FormStateInterface $form_state) {
  $form['submit'] = [
    '#type' => 'submit',
    '#value' => 'Submit',
    '#ajax' => [
      'callback' => '::ajaxSubmit',
      'url' => Url::fromRoute('<front>'), // <-- new
      'options' => [ // <-- new
        'query' => [
          FormBuilderInterface::AJAX_FORM_REQUEST => 1,
        ],
      ],
    ],
    '#id' => 'submit-my-form', // <-- new
  ];

  $form['#token'] = FALSE;
  ...
}

Плюс, нужно добавить уникальный #id кнопке, чтобы не было конфликта с другими элементами.

Важное замечание — свойство ['#ajax']['url'] должно быть объектом \Drupal\Core\Url. Если передать строку, то опция будет игнорироваться.

Готовый модуль для проверки.

Написанное актуально для
Drupal 8+
Похожие записи

Добавить комментарий