Построение модуля Drupal 8: маршрутизация, контроллеры и меню ссылок
Эта статья является первой из трех частей серии о том, как построить модуль Drupal 8
Как построить модуль Drupal 8:
Построение модуля Drupal 8: маршрутизация, контроллеры и меню ссылок.
Построение модуля Drupal 8: блоки и модули.
Построение модуля Drupal 8: управление конфигурацией и служебный контейнер.
В Drupal 8 появилось много изменений, которые призваны поставить его в один ряд с другими современными PHP фреймворками. Это означает, что старый стиль процедурного программирования PHP4 в значительной степени заменен объектно-ориентированной архитектурой.
С этой целью по инициативе Proudly Found Elsewhere в Drupal 8 был включен код не разрабатывавшийся специально под Drupal.
Одним из самых важных дополнений в Drupal 8 являются компоненты Symfony, включение которых может существенно отразиться на сообществе разработчиков.
Во-первых, это потенциально может значительно увеличить количество разработчиков, которые теперь захотят развивать Drupal. Во-вторых, это немного напугало некоторых разработчиков Drupal 7, которые не имеют большого опыта работы с современными методами PHP.
Но это нормально, мы все учимся, и уроки, вынесенные из работы с Symfony (и, надеюсь, с Drupal 8), можно будет с успехом применить и в работе с другими фреймворками.
На сегодня Drupal 8 уже находится на довольно поздней стадии релизного цикла, в текущий момент написана версия alpha11. Мы будем использовать эту версию, чтобы показать некоторые из основных изменений в построении модулей по сравнению с Drupal 7, с которыми разработчики столкнутся в первую очередь, и к которым они должны быть готовы.
Я создал Git-хранилище, где вы сможете найти код, который я пишу в этой серии статей, и следовать ему, если захотите.
Как создать модуль?
Первое, что мы собираемся рассмотреть - это определение необходимой структуры файлов и папок, которые должны рассказать Drupal 8 о нашем новом модуле. В Drupal 7, мы должны были создать, по крайней мере, два файла (.info и .module), но в Drupal 8, достаточно YAML-версии.
И да, файлы .info теперь заменены на .info.yml и содержат те же данные, но имеют другую структуру.
Еще одним важным изменением является то, что папки пользовательских и контриб-модулей теперь размещаются прямо в корневой папке modules/.
Это сделано потому, что весь код ядра был перемещен в отдельную собственную папку core/. Конечно, внутри папки modules/ вам предлагается разделить модули на пользовательские и сторонние, как в Drupal 7. Давайте двигаться дальше.
Создадим модуль под названием demo (очень оригинально) и поместим его в папку modules/custom/. И как я уже говорил, внутри этой вновь созданной папки demo/ будет размещаться все, что нам нужно, чтобы начать работу с файлом demo.info.yml:
name: Drupal 8 Demo module
description: 'Demo module for Drupal 8 alpha11'
type: module
core: 8.x
Три из четырех приведенных записей должны быть вам знакомы (name, description и core). Указание type в настоящее время также является обязательным требованием, так как вы можете использовать YML-файлы и для тем.
Еще одна важная вещь, на которую вам следует обратить внимание - пробелы в YML-файлах имеют значение и соответствующие отступы используются для организации данных в структуру по образцу массивов.
Вы можете ознакомиться с этой страницей из официальной документации, чтобы получить более подробную информацию относительно других пар ключ-значение, которые могут применяться в .info.yml-файлах модуля, а также с этим отчетом об изменениях, в котором были анонсированы новые правила для этого формата.
Вот и все, нам нужен всего один файл. Теперь вы можете перейти на страницу Extend, найти модуль Demo и включить его. Как я уже говорил, нам больше не нужно создавать файл .module, чтобы подключить модуль.
С точки зрения архитектуры, суммарный размер файлов .module будет существенно меньше, за счет переноса большей части бизнес логики в служебные классы, контроллеры и плагины, но их (некоторые из них) мы рассмотрим немного позже.
Что такое ‘routing’, и что случилось с hook_menu() и его обратными вызовами?
В Drupal 7, hook_menu() являлось, вероятно, самым часто реализуемым обращением, потому что оно использовалось для определения пути к Drupal и подключения этого пути к функциям обратного вызова. Оно также отвечало за создание ссылок меню и кучу других вещей.
В Drupal 8 мы больше не будем нуждаться в hook_menu(), поскольку здесь для обработки маршрутов можно широко использовать компоненты Symfony 2.
В том числе определять маршруты в качестве конфигурации и обрабатывать обратные вызовы в контроллере (метод класса Controller). Давайте рассмотрим, как это работает, создав простую страницу, которая выводит классическое "Привет, Мир!"
Во-первых, мы должны создать файл маршрутизации для нашего модуля под названием demo.routing.yml. Этот файл размещается в корневой папке модуля (рядом с demo.info.yml). В этом файле у нас может быть следующее (простое) определение маршрута:
demo.demo:
path: '/demo'
defaults:
_content: 'DrupaldemoControllerDemoController::demo'
_title: 'Demo'
requirements:
_permission: 'access content
Первая строка означает начало нового маршрута под названием demo для модуля demo (сначала идет название модуля, затем название маршрута).
Под path, мы указываем путь, по которому хотим зарегистрировать этот маршрут. Под defaults у нас есть два элемента: заголовок страницы по умолчанию (_title) и _content, который связывает метод с классом DemoController.
Под requirements мы указываем права доступа, которые должен иметь пользователь, чтобы просматривать страницу. Советую вам ознакомиться с этой страницей официальной документации, чтобы получить больше информации относительно опций, которые возможны для этого файла маршрутизации.
Теперь, давайте создадим наш первый контроллер под названием DemoController. Он будет содержать метод demo(), вызываемый, когда пользователь запрашивает эту страницу.
В папке модуля создайте папку с именем src/, а в ней папку Controller/. В ней мы будем хранить классы контроллеров. Идем дальше. Создайте первый контроллер: DemoController.php.
Размещение контроллеров и, как мы увидим, других классов, в папке src/ является элементом соответствия стандарту PSR-4.
Изначально нам нужно было создавать больше структурных папок (стандарт PSR-0), но в данный момент функционирует переходный режим, при котором применимы оба этих стандарта. Так что если вы все еще видите код в папке под названием lib/, это стандарт PSR-0.
Внутри нашего файла DemoController.php, мы теперь можем объявить класс:
<?php
/**
* @file
* Contains DrupaldemoControllerDemoController.
*/
namespace DrupaldemoController;
/**
* DemoController.
*/
class DemoController {
/**
* Генерирует пример страницы.
*/
public function demo() {
return array(
'#markup' => t('Привет, Мир!'),
);
}
}
Это самый минимум того, что нужно сделать для того, чтобы отобразить что-то на странице. В верхней части мы определяем область имен класса, а ниже объявляем класс.
Внутри класса DemoController у нас есть только метод demo(), который возвращает массив, похожий на Drupal 7. Ничего существенного.
Все, что мы должны сейчас сделать, это очистить кэш и перейти по адресу http://example.com/demo, и там мы должны увидеть страницу Drupal с приветствием "Привет, Мир!"
Как насчет ссылок меню?
В Drupal 7, когда мы реализуем hook_menu(), мы также можем добавить в меню зарегистрированные пути, чтобы вывести на сайте ссылки меню. Опять - таки эта операция больше не обрабатывается этим обращением. Вместо него мы используем YML-файл, чтобы объявить ссылки меню в качестве конфигурации.
Давайте рассмотрим, как мы можем создать ссылку, которая отображается в меню Structure панели администрирования. Во-первых, в корне нашего модуля нам нужно создать файл с именем demo.menu_links.yml. В этом YML-файле мы определяем ссылки меню и их положение в существующих на сайте меню. Для этого, нам нужно задать следующее:
demo.demo:
title: Demo Link
description: 'This is a demo link'
parent: system.admin_structure
route_name: demo.demo
Мы снова имеем YML-структуру на основе отступов, в которой мы сначала определяем машинное имя ссылки меню (demo) для модуля demo (как мы это делали для маршрутов).
Далее, у нас есть название ссылки и описание соответствующего этой ссылке родительского элемента (куда она должна быть добавлена) и то, какой маршрут она должна использовать.
Значение parent является ссылкой родительского меню (прилагается модулем) и, чтобы найти его, вам нужно немного покопаться в файлах *.menu_links.yml. Я знаю, что ссылка Structure определяется в модуле ядра системы, поэтому, заглянув в файл system.menu_links.yml я могу определить имя этой ссылки.
route_name это машинное имя маршрута, который мы хотим использовать для этой ссылки. Мы определили маршруты ранее. И разобравшись с этим, вы можете очистить кэш и перейти по ссылке http://example.com/admin/structure. Теперь вы должны увидеть новую ссылку меню с заголовком и описанием. По этой ссылке будет осуществляться переход по пути demo/. Неплохо.
Заключение
В этой статье мы начали рассматривать построение модуля Drupal 8. На данном этапе (версия системы alpha11) уже настало время приступать к изучению особенностей работы с новыми компонентами и contrib-модулями.
С этой целью я предлагаю вашему вниманию свое исследование этих новых и существовавших ранее функций фреймворка, каковым и станет Drupal 8, чтобы мы все могли заранее подготовиться к готовящимся изменениям, и сразу приступить к работе, когда настанет день релиза.
Для начала, мы рассмотрели некоторые основы элементы: как начинается работа по созданию модуля Drupal 8 (файлы, структура папок и т.д.), все это в сравнении с Drupal 7. Вы также увидели, как определить маршруты и классы контроллеров с методами, которые вызываются этими маршрутами.
И, наконец, мы рассмотрели, как создать ссылку меню, используя маршрут, который мы определили.
В следующей статье мы продолжим построение этого модуля и рассмотрим некоторые другие интересные новые компоненты Drupal 8. Я расскажу вам, как мы можем создавать блоки и как работать с формами и системой конфигурации. Увидимся вскоре.