Зачем нужен кастомный плагин для Pico CMS
Представьте: вам нужно добавить на все страницы Pico CMS кастомную форму обратной связи, которая отправляет данные во внешнюю CRM. Штатными средствами — только Twig-партиалы и ручная обработка. Без плагина придётся править ядро, что чревато конфликтами при обновлении. Правильное решение — написать изолированный PHP-плагин, подключаемый через Composer. Мы занимаемся этим более чем в 50 проектах — от простых редиректов до полноценных корпоративных порталов.
Редактирование ядра Pico напрямую — путь к техническому долгу. При следующем обновлении CMS ваши изменения перезапишутся, а если вы забудете, что правили, — сайт сломается. Плагин же живёт в отдельной директории, подключается через Composer и не трогает ядро. Это стандартная практика в современной PHP-разработке.
Согласно официальной документации Pico, "плагины являются основным способом расширения функциональности" (https://github.com/picocms/Pico).
Как работает система событий Pico
Каждый плагин Pico — это класс, наследующий AbstractPicoPlugin. Он подписывается на события, которые CMS генерирует в строгом порядке: от загрузки конфига до рендеринга Twig-шаблона. Методы-обработчики получают аргументы по ссылке (&$variable), что позволяет модифицировать данные на лету.
<?php class MyPlugin extends AbstractPicoPlugin { const API_VERSION = 3; protected $enabled = true; public function onConfigLoaded(array &$config): void { if (!isset($config['my_plugin'])) { $config['my_plugin'] = ['option' => 'default']; } } public function onMetaHeaders(array &$headers): void { $headers['redirect'] = 'Redirect'; $headers['auth_required'] = 'AuthRequired'; } public function onPageRendering(string &$templateName, array &$twigVariables): void { $meta = $twigVariables['meta']; if (!empty($meta['redirect'])) { header('Location: ' . $meta['redirect'], true, 302); exit; } } } Файл кладётся в plugins/MyPlugin/MyPlugin.php. Стандартная структура директории:
plugins/ └── MyPlugin/ ├── MyPlugin.php ├── config.yml.template └── README.md Какие события используются чаще всего?
Вот ключевые точки входа для Pico 3.x. Мы используем их в 90% проектов.
| Событие | Описание | Типовое применение |
|---|---|---|
| onPluginsLoaded | Все плагины загружены | Доступ к другим плагинам |
| onConfigLoaded | Конфиг разобран | Изменение параметров |
| onRequestUrl | URL запроса известен | Редиректы, ограничения |
| onMetaHeaders | Список YAML-заголовков | Добавление метаполей |
| onContentParsed | Markdown → HTML | Вставка шорткодов |
| onPageRendering | Перед Twig-рендерингом | Добавление переменных |
Пример из практики: плагин авторизации по IP
public function onConfigLoaded(array &$config): void { $this->allowedIps = $config['ip_restrict']['allowed'] ?? []; $this->restrictedPaths = $config['ip_restrict']['paths'] ?? []; } public function onRequestUrl(string &$url): void { $clientIp = $_SERVER['REMOTE_ADDR'] ?? ''; foreach ($this->restrictedPaths as $path) { if (str_starts_with($url, $path)) { if (!in_array($clientIp, $this->allowedIps, true)) { header('HTTP/1.1 403 Forbidden'); echo 'Access denied'; exit; } } } } Такой плагин полезен для закрытия админ-панели или staging-окружения. Он работает на раннем этапе — onRequestUrl — и блокирует доступ до начала обработки контента, что экономит ресурсы.
Шорткоды в Pico: как добавить?
Pico не поддерживает шорткоды из коробки — их реализуют через onContentParsed:
public function onContentParsed(string &$content): void { $content = preg_replace_callback( '/\[youtube\s+id="([a-zA-Z0-9_-]+)"\]/', static function (array $matches): string { $id = htmlspecialchars($matches[1], ENT_QUOTES); return sprintf( '<div class="video-embed"><iframe src="https://www.youtube.com/embed/%s" ' . 'allowfullscreen loading="lazy" title="YouTube video"></iframe></div>', $id ); }, $content ); } Типы плагинов: что мы умеем?
| Тип плагина | Сложность | Примеры |
|---|---|---|
| Обработчик одного события | 1-2 дня | Редирект по мета-полям, добавление Google Analytics |
| Кастомные Twig-функции | 2-3 дня | Форма обратной связи, слайдер на основе YAML |
| Интеграция с внешним API | 3-5 дней | импорт из CRM, WebHook на обновление контента |
| Комплексная бизнес-логика | от 5 дней | Каталог с фильтрацией, управление доступом |
Плагин на Pico разрабатывается в 3 раза быстрее, чем аналогичное расширение для WordPress, за счёт простой архитектуры событий и минималистичного ядра.
Какие ошибки допускают при разработке плагинов Pico?
- Неправильный порядок событий: например, попытка использовать onContentParsed до onPageRendering — контент ещё не обработан.
- Отсутствие проверки на существование массива:
$config['my_plugin']может не быть — используйте??. - Использование глобальных переменных вместо переданных по ссылке: это ломает изоляцию.
- Забытый exit после редиректа: скрипт продолжает выполнение, и вы получите ошибку заголовков.
- Отсутствие тестов: плагин может сломаться при обновлении Pico.
Процесс разработки
Мы следуем чёткому регламенту, чтобы вы получили предсказуемый результат:
- Анализ — вы описываете задачу, мы уточняем детали и оцениваем сроки.
- Проектирование — определяем список событий, структуру конфига и Twig-переменные.
- Разработка — пишем код на PHP 8.1+ с учётом PSR-12, покрываем тестами PHPUnit.
- Интеграционное тестирование — проверяем плагин на вашем хостинге или в среде, приближенной к продакшену.
- Сдача — передаём исходный код с лицензией MIT, документацию, конфиг-шаблон и отчёт о тестировании.
Что входит в работу
- Исходный код плагина с поддержкой Composer-установки
- README с описанием установки и настройки
- Пример конфига в YAML
- Юнит-тесты (PHPUnit) с покрытием не менее 80%
- 30 дней бесплатной поддержки: исправление багов, консультации
Гарантии и поддержка
Мы гарантируем совместимость с последними версиями Pico и PHP, отсутствие конфликтов с другими плагинами благодаря изолированной архитектуре. Каждый плагин проходит код-ревью и статический анализ. Если у вас есть нестандартная задача — напишите нам, обсудим решение. Получите консультацию по вашему проекту — определим необходимые события и сроки за 1 час.
Закажите разработку плагина — мы проанализируем вашу задачу и предложим оптимальное решение в течение дня. Свяжитесь с нами, чтобы обсудить детали.







