Урок по созданию плагина¶
Плагины обычно создают, когда задачу нельзя решить средствами ядра Grav.
В этом уроке мы создадим плагин, который помогает Grav отдавать пользователю случайную страницу. Вы наверняка видели похожую функциональность на сайтах блогов: кнопку, по нажатию на которую открывается случайная запись.
Предупреждение
Поскольку для этой задачи уже есть плагин Random, мы назовём наш тестовый плагин Randomizer.
Эту фичу нельзя получить из коробки, но её легко реализовать с помощью плагина. Как и во многих аспектах Grav, здесь нет единственного способа. Наоборот, есть много вариантов. Мы рассмотрим только один подход…
Обзор плагина Randomizer¶
В нашем плагине мы выберем следующий подход:
-
Активировать плагин, если URI совпадает с настроенным «маршрутом-триггером» (например,
/random). -
Создать фильтр, чтобы в пул случайных страниц попадали только настроенные таксономии (например,
category: blog). -
Найти случайную страницу из отфильтрованного пула и указать Grav использовать её для контента страницы.
Хорошо! Звучит достаточно просто, правда? Тогда приступим!
Шаг 1 — Установка плагина DevTools¶
Внимание
В предыдущих версиях урока требовалось создавать плагин вручную. Весь этот процесс можно пропустить благодаря новому плагину DevTools.
Первый шаг в создании нового плагина — установить плагин DevTools. Это можно сделать двумя способами.
Установка через CLI GPM¶
- Перейдите в командной строке в корень установки Grav.
Установка через админку¶
- После входа перейдите в раздел Плагины в боковой панели.
- Нажмите кнопку Добавить в правом верхнем углу.
- Найдите DevTools в списке и нажмите Установить.
Шаг 2 — Создание плагина Randomizer¶
Для следующего шага вам действительно понадобится командная строка, потому что DevTools предоставляет несколько CLI-команд, которые значительно упрощают создание нового плагина!
Из корня установки Grav выполните команду:
В процессе вас спросят несколько вопросов, необходимых для создания нового плагина:
bin/plugin devtools new-plugin
Enter Plugin Name: Randomizer
Enter Plugin Description: Sends the user to a random page
Enter Developer Name: Acme Corp
Enter Developer Email: contact@acme.co
SUCCESS plugin Randomizer -> Created Successfully
Path: /www/user/plugins/randomizer
Make sure to run I4 to initialize the autoloader
Предупреждение
На этом этапе нужно выполнить composer update в только что созданной папке плагина.
Команда DevTools сообщает, где создан новый плагин. Созданный плагин полностью рабочий, но в нём не будет логики, выполняющей то, что нам нужно. Нам придётся изменить его под свои нужды.
Шаг 3 — Основы плагина¶
Теперь у нас есть новый плагин, который можно изменять и развивать. Давайте разберём, из чего состоит плагин. Если заглянуть в папку user/plugins/randomizer, вы увидите:
.
├── CHANGELOG.md
├── LICENSE
├── README.md
├── blueprints.yaml
├── randomizer.php
└── randomizer.yaml
Это примерная структура, но некоторые элементы обязательны:
Обязательные элементы для работы¶
Эти элементы критичны, и плагин не будет надёжно работать без них.
blueprints.yaml— файл конфигурации, из которого Grav получает информацию о плагине. В нём также можно определить форму, которую админка показывает при просмотре сведений о плагине. Эта форма позволяет сохранять настройки плагина. Этот файл описан в главе о формах.randomizer.php— имя этого файла соответствует вашему плагину, и в нём может находиться любая логика плагина. Можно использовать любой хук события плагина, чтобы выполнить логику практически на любом этапе жизненного цикла Grav.randomizer.yaml— конфигурация, используемая плагином для задания параметров. Имя должно совпадать с именем файла.php.
Обязательные элементы для выпуска¶
Эти элементы нужны, если вы хотите выпустить плагин через GPM.
CHANGELOG.md— файл, следующий формату списка изменений Grav, где показаны изменения в релизах.LICENSE— файл лицензии; вероятно, MIT, если у вас нет особой необходимости в другой.README.md— «Readme», который должен содержать документацию по плагину: как установить, настроить и использовать.
Шаг 4 — Конфигурация плагина¶
Как описано в обзоре плагина, нам нужны несколько параметров конфигурации, поэтому файл randomizer.yaml должен выглядеть примерно так:
Это позволяет задать несколько фильтров, если нужно, но пока мы хотим, чтобы в случайный выбор попадал только контент с таксономией category: blog.
У всех плагинов должна быть опция enabled. Если в конфигурации сайта она равна false, ваш плагин никогда не будет инициализирован Grav. У всех плагинов также есть опция active. Если в конфигурации сайта она равна false, каждой странице нужно будет активировать плагин. Обратите внимание: многие плагины также поддерживают enabled/active в метаданных страницы через mergeConfig, как описано ниже.
Совет
В установке Grav по умолчанию таксономии category и tag уже определены. Эту конфигурацию можно изменить в файле user/config/site.yaml.
Конечно, как и с любой другой конфигурацией Grav, для повседневного управления не рекомендуется трогать конфигурацию по умолчанию. Вместо этого создайте переопределение в файле /user/config/plugins/randomizer.yaml для пользовательских настроек. Файл randomizer.yaml, поставляемый с плагином, действительно предназначен для разумных значений по умолчанию.
Шаг 5 — Базовая структура плагина¶
Базовая структура класса плагина уже будет выглядеть примерно так:
Нам нужно добавить несколько инструкций use, потому что мы будем использовать эти классы в плагине. Это экономит место и делает код читаемее, если не указывать полное пространство имён каждого класса внутри кода.
Измените инструкции use так:
Две ключевые части этой структуры класса:
- В верхней части PHP-файла плагина должно быть
namespace Grav\Plugin. - Плагины следует называть в TitleCase на основе имени плагина с добавлением строки
Pluginв конце, и они должны расширятьPlugin; отсюда имя классаRandomizerPlugin.
Шаг 6 — Подписка на события¶
Grav использует сложную систему событий, и для оптимальной производительности Grav проверяет все плагины, чтобы определить, на какие события они подписаны.
В этом плагине мы сообщим Grav, что подписываемся на событие onPluginsInitialized. Так мы сможем использовать это событие (первое доступное плагинам), чтобы решить, подписываться ли на другие события.
Примечание
Примечание: первый слушатель события autoload нужен только в Grav 1.6. Grav 1.7 вызывает этот метод автоматически.
Шаг 7 — Определение, должен ли плагин работать¶
Следующий шаг — добавить в класс RandomizerPlugin метод обработки события onPluginsInitialized, чтобы плагин активировался, только когда пользователь пытается перейти по маршруту, настроенному в файле randomizer.yaml. Замените текущую «примерную» логику плагина на следующую:
Сначала мы получаем объект Uri из контейнера внедрения зависимостей. Он содержит всю информацию о текущем URI, включая информацию о маршруте.
Метод config() уже есть в базовом классе Plugin, поэтому его можно просто использовать, чтобы получить значение конфигурации для настроенного route.
Затем мы сравниваем настроенный маршрут с текущим путём URI. Если они равны, мы сообщаем диспетчеру, что плагин также будет слушать новое событие: onPageInitialized.
Такой подход гарантирует, что мы не выполним лишний код, если он не нужен. Подобные практики помогают сайту работать максимально быстро.
Шаг 8 — Показ случайной страницы¶
Последний шаг нашего плагина — показать случайную страницу. Это делается добавлением следующего метода:
Этот метод немного сложнее, поэтому разберём, что происходит:
-
Сначала мы получаем объект Taxonomy из DI-контейнера Grav и присваиваем его переменной
$taxonomy_map. -
Затем получаем массив фильтров из конфигурации плагина. В нашей конфигурации это массив с 1 элементом:
['category' => 'blog']. -
Проверяем, что фильтры есть, затем создаём новую
Collectionв переменной$collectionдля хранения страниц. -
Добавляем в
$collectionвсе страницы, соответствующие фильтру. -
Удаляем текущий объект
page, известный Grav. -
Устанавливаем текущую
pageв случайный элемент коллекции.
Шаг 9 — Очистка¶
Пример плагина, созданный плагином DevTools, использовал событие onPageContentRaw(). В нашем новом плагине это событие не используется, поэтому функцию можно смело удалить.
Шаг 10 — Итоговый класс плагина¶
Вот и всё! Плагин готов. Итоговый класс плагина должен выглядеть примерно так:
Если вы всё повторяли, у вас должен быть полностью рабочий плагин Randomizer, включённый на сайте. Просто откройте в браузере http://my-site.example/random, и вы увидите случайную страницу. Также можно скачать оригинальный плагин Random в разделе Plugins Download на сайте getgrav.org.
Расширение схем¶
Если плагину нужно расширять схемы, например default.yaml из /system/blueprints/pages/default.yaml, регистрировать схему через хуки не нужно, если соблюдать структуру папок, разместив расширяемую схему в [your-plugin-directory]/blueprints/pages/default.yaml. Grav объединит ваши расширенные определения схемы, а темы смогут сделать то же самое позже.
наследование system, если создать такую структуру папок внутри плагина
- blueprints
- pages
- default.yaml
наследование admin, если создать такую структуру папок внутри плагина
- blueprints
- admin
- pages
- raw.yaml
В админке нужно наследовать raw или другие, и схемы тем, расширяющие default, не попадут в вашу конфигурацию.
Если это не страницы, делайте то же самое для других наследований… Так вы сможете свести изменения при расширении к минимуму — в этом и смысл расширения :-).
Объединение конфигурации плагина и страницы¶
Одна популярная техника, используемая в разных плагинах, — объединение конфигурации плагина (по умолчанию или переопределённой пользователем) с конфигурацией уровня страницы. Это значит, что можно задать конфигурацию для всего сайта, а затем при необходимости задать отдельную конфигурацию для конкретной страницы. Это даёт плагину много мощности и гибкости.
В последних версиях Grav добавлен вспомогательный метод, выполняющий эту функциональность автоматически, чтобы вам не приходилось писать эту логику самим. Плагин SmartyPants — хороший пример такой функциональности в действии:
Реализация CLI в плагине¶
Плагины также могут интегрироваться с командной строкой bin/plugin для выполнения задач. Если хотите реализовать такую функциональность, следуйте документации по CLI для плагинов.