Пользовательская форма используя пользовательский шаблон, отправьте форму, не вызывайте ее обработчики проверки и отправки
Я создал простой пользовательский модуль, в котором я создал форму класса, используя форму пользовательского шаблона. Если я не использую свой пользовательский шаблон (я комментирую свой крючок _theme из своего .module), когда я отправляю свою форму, вызываются обработчики методов класса validate и submit. Но когда я использую свой пользовательский шаблон формы, если я отправляю свою форму, обработчики методов проверки и отправки классов не вызываются, я не понимаю, почему.
Это мой код; Я начинаю с моего шаблоны/форма--myformtest-шаблон form.html.twig.
<h1>TEST</h1>
<form{{ element }}></form>
Мой код myformtest.module следующий.
/**
* Implements hook_theme().
*/
function myformtest_theme($existing, $type, $theme, $path)
{
return array(
'form__myformtest_form' => array(
'render element' => 'form',
'template' => 'form--myformtest-form',
),
);
}
Если я прокомментирую этот крючок, в моей форме будет использоваться шаблон формы темы по умолчанию. В этом случае отправьте вызов формы, проверьте и отправьте методы обработчиков классов. Если я не прокомментирую этот крючок, моя форма использует мой собственный шаблон. Затем, когда я получаю доступ к своей странице пользовательской формы и проверяю форму, обработчик проверки и отправки никогда не вызывается.
Это простой код из моего src/Form/MyformtestForm.php класс.
class MyformtestForm extends FormBase {
//...
public function buildForm(array $form, FormStateInterface $form_state) {
$form['textfieldtest'] = [
'#type' => 'textfield',
'#title' => $this->t('textfieldtest'),
'#maxlength' => 64,
'#size' => 64,
];
$form['submit'] = [
'#type' => 'submit',
'#value' => t('Submit'),
];
return $form;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
ksm("MyformtestForm Validate handler!");
// logs never displayed when I use my custom template. If I don't use the custom template, this log appears.
}
public function submitForm(array &$form, FormStateInterface $form_state) {
ksm("MyformtestForm Submit handler");
// logs never displayed when I use my custom template. If I don't use the custom template, this log appears.
}
Почему обработчики не вызываются, когда моя форма использует мое пользовательское переопределение? Как я могу их назвать?
Это переменные, существующие в моем пользовательском шаблоне при загрузке страницы формы.
4 answers
Я полагаю, вам нужен "базовый крюк" там.
Вот пример:
/**
* Implements hook_theme().
*/
function formcustomtemplate_theme() {
return array(
'form__my_form_test' => array(
'render element' => 'form',
'template' => 'form--myformtest-form',
'base hook' => 'form',
),
);
}
Если вы используете пользовательскую тему, и вам не нужен шаблон в вашем модуле, подход создания нового крючка темы для вашей пользовательской формы не нужен.
Вместо того, чтобы создавать новый хук темы, используйте hook_theme_suggestions_alter в своей теме:
/**
* Implements hook_theme_suggestions_alter().
*/
function mytheme_theme_suggestions_alter(array &$suggestions, array $variables, $hook) {
if ($hook == 'form' & !empty($variables['element']['#theme'])) {
$suggestions[] = 'form__' . $variables['element']['#theme'][0];
}
}
Затем создайте шаблон приложения в своей теме.
Затем, чтобы увидеть вывод предложений по теме на страницу, включите отладка ветки:
Https://drupalize.me/blog/201405/lets-debug-twig-drupal-8
Вы увидите предложения по шаблонам в разметке:
<!-- FILE NAME SUGGESTIONS:
* form--myformtest-form.html.twig
x form.html.twig
-->
Вы можете видеть, что он еще не использует ваш шаблон, поэтому создайте файл шаблона, скопировав файл form.html.twig и переименовав его.
Чтобы проверить, где Drupal ищет шаблоны с помощью крючка "форма", вы можете распечатать реестр тем из hook_theme_registry_alter:
"form" => array:6 [▼
"template" => "form"
"path" => "themes/custom/mycustomtheme/templates/form"
"type" => "theme_engine"
"theme path" => "themes/custom/mycustomtheme”
"render element" => "element"
"preprocess functions" => array:4 [ …4]
Это позволяет вам знать, что вы нужно поместить шаблон в этот каталог.
Это может оказаться полезным для людей, которые хотят стилизовать каждый элемент формы.
/**
* Implements hook_form_BASE_FORM_ID_alter().
*/
function MODULE_NAME_form_YOUR_FORM_ID_alter(&$form, FormStateInterface &$form_state) {
$form['#theme'] = ['CUSTOM_NAME'];
}
После этого я настроил свой крючок с нужным элементом.
/**
* Implements hook_theme().
*/
function MODULE_NAME_theme($existing, $type, $theme, $path) {
return [
'CUSTOM_NAME' => [
'render element' => 'form',
],
];
}
Я назвал свой шаблон соответствующим образом (CUSTOM_NAME.html.twig).
Здесь вы можете соответствующим образом отобразить свои элементы $form
(например: {{ form.name }}
, исходя из $form['name']
).
И последнее, но ПОВЕРЬТЕ МНЕ, не в последнюю очередь, и самое главное, не забудьте включить переменные form_build_id и form_token.
{{ form.form_build_id }} {# required #}
{{ form.form_id }} {# required #}
{{ form.form_token }} {# required #}
Ответ на вопрос уже выбран, этот вопрос просто прост, так как он дает объяснение того, как более тщательно оформить вашу форму.
Приветствия
Я также думаю, что проблема заключается в отображении вашей формы. Взгляните на шаблоны форм по умолчанию в core, такие как form.html.twig.
Https://api.drupal.org/api/drupal/core!modules!system!templates!form.html.twig/8.2.x
Можете ли вы попробовать сделать это таким образом и использовать {{дети}} или отображать поля шаг за шагом с помощью чего-то вроде {{element.textfieldtest}}.
Поэтому я бы использовал этот код
<h1>TEST</h1>
<form{{ attributes }}>
{{ children }}
</form>
Вы также можете сбросить выходные данные в шаблоне с помощью {{ dump }}
и посмотрите, какие переменные у вас есть. Вот ссылка для включения отладки ветки https://www.drupal.org/docs/8/theming/twig/debugging-twig-templates
Если вы работали с drupal 7, в drupal 7 мы визуализируем drupal_render_children($form);
в наших наценках на drupal отображаются скрытые и csrf поля,
Согласно с.html.twig
Доступные переменные
attributes: A list of HTML attributes for the wrapper element. children: The child elements of the form.
Если вы хотите сначала отобразить элементы так, как вы хотите, то вы должны, наконец, отобразить {{ children}}
как метод drupal 7.
Итак, сначала визуализируйте элементы вашего желания, затем визуализируйте {{ children }}
, вам следует попробовать что-то вроде
<h1>TEST</h1>
<div class="myclass">{{ element }} </div>
// other elements
// and finally
{{ children }}