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