Drupal 8. Создание модуля

В преддверии официального релиза Drupal 8, перед разработчиками существующих модулей все явственней вырастает неизбежная проблема - адаптация своих творений к кординально новым принципам разработки под Drupal. Обьектно-ориентированный подход, связанный с внедрениеи в 8-е ядро Drupal компонентов фреймворка Symfony 2, помимо очевидных преимуществ, несет в себе для многих неизбежную головную боль. Перестройка мышления для программиования на обьектно-ориентированных принципах, вместо привычного функционального подхода, дело не самое легкое. Особенно, если концепции MVC и ООП известны лишь в теории.

1. Структура файлов модуля

При первом взгляде вовнутрь папки с инсталляцией Drupal 8 изменения в файловой структуре. Все гораздо более прямым. Каждая из папок в корневом каталоге, ядро, модули, профили, сайты и темы, дома его соответствующим компонентам. С этим, как говорится, вы начнете путем размещения модуля внутри папки корневого каталога модулей;

Если заглянуть внутрь дирректории с инсталляцией Drupal 8, то первое, что бросается в глаза - измененная, ставшая более логичной, файловая структура. Теперь каждая из папок в корневом каталоге - ядро, модули, профили, сайты и темы - соответствует компонентам, в ней содержащимся. Для модулей, не входящих в ядро, отныне отведена дирректория modules в самом корне.

Соответственно, файлы нашего тестового модуля с именем, first, будут находится по адресу: modules/first.

2. Создание файлов .INFO и .MODULE

Метод использования .info файлов в Drupal претерпел некоторые изменения. Отныне его содержимое записывается в формате Symfony YAML. С расширением .yml в конце.

Для нашего подопытного модуля, перво-наперво следует создать два ключевых файла: first.module и first.info.yml.

Содержание first.info.yml будет таким:

name: First
type: module
description: First module.
package: My
version: 8.x-1.0
core: 8.x
hidden: false

Как мы видим, изменился синтаксис в описании параметров модуля. Новый параметр hidden сообщает системе, будет или нет отображаться наш модуль в списке модулей на соответствующей административной странице.

3. Создание контроллеров для модуля

Сперва немного теории по MVC:

  • Модель (Model) - предоставляет некую информацию: данные и методы работы с этими данными, реагирует на запросы, изменяя своё состояние. Не содержит информации, как эти знания можно визуализировать.
  • Представление (View) - отвечает за отображение информации (визуализацию). Часто в качестве представления выступает форма (окно) с графическими элементами.
  • Контроллер (Controller) - обеспечивает связь между пользователем и системой: контролирует ввод данных пользователем и использует модель и представление для реализации необходимой реакции.

Для нашего модуля, в качестве примера, мы напишем совсем простенький контроллер. Файл, содержащий его код (FirstController.php), должен находиться по следующему пути:

ПАПКА_ИНСТАЛЛЯЦИИ_DRUPAL
-- modules
---- first
------ lib
-------- Drupal
---------- first
------------ Controller
-------------- FirstController.php

Структура должна быть именно таковой. В противном случае Symfony ваш контроллер попросту не найдет.
Содержание нашего FirstController.php будет следующим:

namespace Drupal\first\Controller;
use Drupal\Core\Controller\ControllerBase;

class FirstController extends ControllerBase {

  public function firstIndex() {
   return array(
      '#markup' => t('This is the demo first page.'),
    );
  }

}

Код, написанный выше, как раз и формирует то, что мы увидим на страничке, создаваемой нашим модулем.

4. Описываем маршрутизацию для контроллера

Для того, чтобы передать в контроллер путь(URL), по переходу на который он будет возвращать нужные данные, создадим еще один файл в корне нашего модуля - first.routing.yml (modules/first/first.routing.yml). Со следующим кодом:

first:
  path: '/first-page'
  defaults:
    _content: '\Drupal\first\Controller\FirstController::firstIndex'
  requirements:
    _permission: 'access content'

5. Регистрируем пункт меню

Помимо указания путей-маршрутов для контроллера, в Drupal 8 требуется так же отдельно зарегистрировать путь и для системы меню. В этом деле нам помогут ранее созданный файл first.module и старый знакомый - hook_menu().

Открываем first.module, и помещаем в него код:

/**
* Implements hook_menu().
*/
function first_menu() {
  $items['first-page'] = array(
    'title' => 'Hello First page',
    'description' => 'The first page',
    'route_name' => 'first',
  );

  return $items;
}

6. Заключительная стадия

Теперь мы можем включить наш модуль. На странице, /first-page будет текст - 'This is the demo first page'. Или белый экран, если прочитали вышеописанное без должного внимания.

Эпилог

Кстати сказать, все изложенные безобразия с контроллерами и роутингами, можно было бы обойти написанием кода по-старинке. Игнорируя многочисленные преимущества Symfony, и используя, как и раньше, добрые, понятные хуки. Однако... Такой путь хоть и допустим, но имеет логичный финиш - тупик. Drupal изменился, и прежним никогда не станет. И тут без вариантов: или мы идем с ним в одном направлении, тоже меняясь, или посылаем все это к черту, во избежание сожалений о бесцельно прожитом. И выбирать пора уже вчера.)