По умолчанию блоки с формами кэшируются только для анонимных пользователей. Для залогинённых же друпал добавляет во все формы элемент 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
. Если передать строку, то опция будет игнорироваться.
Добавить комментарий