Drupal 8 предоставляет мощные инструменты для создания и управления формами. Если вам нужно вывести форму в блоке и прикрепить к ней AJAX, следуйте этому руководству.

Шаг 1: Создание модуля Drupal

Первым шагом будет создание модуля Drupal, который будет содержать код для вывода формы в блоке. Создайте каталог для модуля в каталоге «modules/custom» вашей Drupal установки и назовите его, например, «custom_contact_form». Внутри данного каталога создайте файл «custom_contact_form.info.yml» со следующим содержимым:

name: 'Custom Contact Form'
type: module
description: 'Adds a contact form with AJAX to a block.'
core_version_requirement: ^8 || ^9
package: Custom
dependencies:
  - drupal:contact

Здесь мы объявляем имя и описание модуля, указываем, что он является модулем Drupal 8/9, указываем зависимость от модуля «contact» (который поставляется вместе с Drupal) и привязываем модуль к нашему пользовательскому пакету.

Далее, создайте файл «custom_contact_form.module» в этом же каталоге. В нем мы определим наш контроллер и блок. Вот содержимое файла:

use Drupal\contact\Entity\ContactForm;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;

/**
 * Implements hook_help().
 */
function custom_contact_form_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'help.page.custom_contact_form':
      $output = '';
      // Generate the documentation for help page.
      return $output;

    default:
	return;
  }
}

/**
 * Implements hook_block_info().
 */
function custom_contact_form_block_info() {
  $blocks = [];

  $blocks['custom_contact_form'] = [
    'info' => t('Custom Contact Form'),
    'cache' => DRUPAL_NO_CACHE,
  ];

  return $blocks;
}

/**
 * Implements hook_block_access().
 */
function custom_contact_form_block_access(Block $block, $operation, AccountInterface $account) {
  // Set the permissions for accessing the block.
  return AccessResult::allowedIfHasPermission($account, 'access content');
}

/**
 * Implements hook_block_view().
 */
function custom_contact_form_block_view($delta = '') {
  $block = [];

  switch ($delta) {
    case 'custom_contact_form':
      $block['subject'] = t('Custom Contact Form');
      $block['content'] = custom_contact_form_block_content();
      break;
  }

  return $block;
}

/**
 * Builds the content of the custom contact form block.
 */
function custom_contact_form_block_content() {
  $contact_form_entity = ContactForm::load('contact_form_id'); // Замените "contact_form_id" на идентификатор вашей контактной формы.

  if ($contact_form_entity) {
    $contact_form = \Drupal::entityTypeManager()
      ->getFormObject('contact_message', 'default')
      ->setEntity($contact_form_entity);

    $form = \Drupal::formBuilder()->getForm($contact_form);

    // Enable AJAX for
    // the contact form.
    $form['#attached']['library'][] = 'core/drupal.ajax';

    // Add the AJAX behavior
    // to the form submission.
    $form['actions']['submit']['#ajax'] = [
      'callback' => 'custom_contact_form_submit',
      'event' => 'click',
    ];

    $content['form'] = $form;
  }

  return $content;
}

/**
 * Form submission callback
 * for the custom contact form.
 */
function custom_contact_form_submit(array $form, FormStateInterface $form_state) {
  $response = new AjaxResponse();

  $response->addCommand(
    new HtmlCommand('#custom-contact-form-messages', 'Thank you for your submission!')
  );

  return $response;
}

Здесь мы определяем несколько хук-функций Drupal, которые реализуют необходимую функциональность. Функция «custom_contact_form_block_content» отображает форму контакта в блоке. Мы загружаем соответствующую контактную форму используя ее идентификатор, затем строим форму и включаем AJAX обработку для неё. Функция «custom_contact_form_submit» является обработчиком отправки формы и возвращает AJAX-ответ с командой для замены содержимого контейнера «#custom-contact-form-messages» на странице.

Шаг 2: Размещение блока на сайте

Теперь, когда у нас есть наш модуль и блок с контактной формой, нам нужно разместить этот блок на странице включая его в соответствующую область.

1. Войдите в административную панель Drupal, перейдите в «Structure» — «Block layout».

2. Найдите область вашего блока (например, «Content») и щелкните на ссылке «Place block».

3. В открывшемся окне введите «Custom Contact Form» в поисковую строку блоков.

4. Выберите наш блок «Custom Contact Form» и щелкните на кнопке «Place block».

5. Нажмите кнопку «Save blocks».

Теперь блок с контактной формой будет отображаться в указанной области на вашем сайте.

Шаг 3: Добавление AJAX к контактной форме

Теперь нам нужно добавить AJAX-обработку отправки формы, чтобы обновлять только нужные части страницы.

Добавьте следующий код в файл «custom_contact_form.module» после функции «custom_contact_form_submit»:

use Drupal\Core\Ajax\ReplaceCommand;

/**
 * Preprocess function
 * for the custom contact form block.
 */
function template_preprocess_block(&$variables) {
  // Add the container for
  // displaying messages.
  $variables['content']['#suffix'] = '
'; } /** * Implements hook_form_alter(). */ function custom_contact_form_form_alter(&$form, FormStateInterface $form_state, $form_id) { if ($form_id === 'contact_message_default_form') { // Add the AJAX behavior // to the form submission. $form['actions']['submit']['#ajax'] = [ 'callback' => 'custom_contact_form_submit', 'event' => 'click', ]; } } /** * Form submission callback * for the custom contact form. */ function custom_contact_form_submit(array $form, FormStateInterface $form_state) { $response = new AjaxResponse(); $response->addCommand( new ReplaceCommand('#custom-contact-form-messages', 'Thank you for your submission!') ); return $response; }

В этом коде мы определяем функцию «template_preprocess_block», которая добавляет контейнер для отображения сообщений от формы. Затем мы используем хук «hook_form_alter», чтобы добавить AJAX-обработку отправки формы к контактной форме по ее идентификатору «contact_message_default_form». Здесь мы также меняем класс команды с «HtmlCommand» на «ReplaceCommand», чтобы заменить содержимое контейнера «#custom-contact-form-messages» на странице.

Теперь контактная форма будет отправляться посредством AJAX, и содержимое контейнера «#custom-contact-form-messages» будет обновляться после отправки формы.

Вопросы и ответы

1. Как можно настроить электронное письмо с данными из контактной формы?

Чтобы настроить отправку электронной почты с данными из контактной формы, вам нужно создать настраиваемое действие отправки формы. Добавьте следующий код в функцию «custom_contact_form_submit» перед командой «return $response;»:

$values = $form_state->getValues();
$to = 'your-email@example.com';
$subject = 'New contact form submission';
$body = 'Name: ' . $values['name'][0]['value'] . "\n" .
  'Email: ' . $values['mail'][0]['value'] . "\n" .
  'Message: ' . $values['message'][0]['value'];

$mailManager = \Drupal::service('plugin.manager.mail');
$mailManager->mail('contact', 'page_mail', $to, 'en', [
    'subject' => $subject,
    'message' => $body,
]);

$response->addCommand(new HtmlCommand('#contact-form-messages', 'Thank you for your submission!'));

Замените «your-email@example.com» на вашу электронную почту. Этот код получает значения полей формы, собирает их в сообщение и отправляет электронное письмо.

2. Как добавить поля в контактную форму?

Вы можете добавить поля в контактную форму в административной панели Drupal:

1. Войдите в административную панель Drupal, перейдите в «Structure» — «Contact forms».

2. Найдите и отредактируйте нужную контактную форму.

3. Нажмите на кнопку «Add field» и следуйте инструкциям для добавления нового поля.

3. Как настроить страницу «Спасибо» после отправки формы?

Чтобы настроить страницу «Спасибо» после отправки формы, вам нужно создать соответствующий маршрут и контроллер. Добавьте следующий код в файл «custom_contact_form.routing.yml»:

custom_contact_form.thank_you:
  path: '/custom-contact-form/thank-you'
  defaults:
    _controller: '\Drupal\custom_contact_form\Controller\CustomContactFormController::thankYou'
  requirements:
    _permission: 'access content'

Теперь создайте файл контроллера «CustomContactFormController.php» и добавьте следующий код:

namespace Drupal\custom_contact_form\Controller;

use Drupal\Core\Controller\ControllerBase;

/**
 * Controller for the thank you page.
 */
class CustomContactFormController extends ControllerBase {

  /**
   * Renders the thank you page.
   *
   * @return array
   *   A render array representing the thank you page.
   */
  public function thankYou() {
    return [
      '#markup' => $this->t('Thank you for your submission!'),
    ];
  }

}

Теперь, когда форма отправляется успешно, пользователь будет перенаправлен на страницу «/custom-contact-form/thank-you», где будет отображаться текст «Thank you for your submission!».