Свой сниппет в MODX: чек-лист перед продакшеном
Сниппет в MODX может выглядеть рабочим в админке и сломаться после включения кеша, смены контекста или обновления PHP. Проверяем код, входные данные, права, производительность и откат перед публикацией.

Сниппет в MODX Revolution 3.x может работать в тестовой странице и неожиданно вернуть пустой результат на продакшене: из-за кеша, другого контекста, отсутствующего параметра или ошибки PHP. Перед публикацией пройдите чек-лист ниже: он рассчитан на небольшой PHP-сниппет, который получает параметры, обрабатывает их и возвращает HTML или текст.
Что проверить до написания кода
Материал рассчитан на MODX Revolution 3.x. Код ниже предполагает PHP-версию, совместимую с вашей сборкой MODX; точную версию и требования к расширениям проверьте в документации и настройках хостинга.
- У вас есть отдельная тестовая копия сайта, а не только рабочий домен.
- Вы можете войти в менеджер MODX с правом создавать и редактировать элементы.
- Есть резервная копия базы данных и файлов перед изменениями.
- Понятно, где будет вызываться сниппет: в ресурсе, чанке, шаблоне или другом сниппете.
- Определены входные параметры, допустимые значения и ожидаемый результат.
Сначала зафиксируйте контракт. Например: параметр name необязателен, пустое значение даёт пустую строку, а любой выведенный текст экранируется. Такой контракт важнее короткого кода: он позволяет проверить результат и не превращать сниппет в набор скрытых исключений.
Продакшен-готовый сниппет — это не тот, который один раз вывел правильную строку. Это тот, чьё поведение понятно при пустом параметре, ошибке, включённом кеше и повторном вызове.
Чек-лист рабочего сниппета
1. Отделите входные данные от логики
Не полагайтесь на переменные из глобальной области и не зашивайте значения в код. Параметры сниппета доступны через $scriptProperties. Для каждого параметра задайте значение по умолчанию и приведите тип.
<?php
$displayName = trim((string)($scriptProperties['name'] ?? ''));
if ($displayName === '') {
return '';
}
return htmlspecialchars(
$displayName,
ENT_QUOTES | ENT_SUBSTITUTE,
'UTF-8'
);
Этот пример рассчитан на MODX Revolution 3.x и современную версию PHP, поддерживаемую вашей установкой. Проверка результата: при вызове с параметром name возвращается текст, а при пустом параметре страница не получает лишнюю разметку.
2. Проверьте экранирование результата
Значение из параметра, поля ресурса, URL или внешнего запроса нельзя бездумно вставлять в HTML. В примере текст экранируется функцией PHP htmlspecialchars. Это подходит для обычного текстового узла и атрибута, но не означает, что один и тот же результат можно безопасно вставить в JavaScript, CSS или SQL.
Если сниппет должен вернуть заранее подготовленный HTML, разделите два режима явно. Либо он принимает только безопасные данные и сам строит ограниченную разметку, либо получает доверенный фрагмент из чанка. Не добавляйте в него возможность принимать произвольные HTML-теги без отдельной проверки.
3. Сведите работу с базой к необходимому минимуму
Если сниппету нужна запись из MODX, сначала определите, можно ли передать данные уже из контекста страницы. Повторный запрос к базе на каждой карточке быстро становится узким местом. Особенно опасна конструкция, где сниппет вызывается внутри цикла и выполняет один запрос на каждый элемент.
Когда запрос нужен, задайте условия, лимит и сортировку явно. Не принимайте имя таблицы, поле сортировки или фрагмент SQL из пользовательского параметра. Для пользовательских значений используйте штатные механизмы MODX и PDO-параметры, а не склейку SQL-строк. Названия конкретных методов зависят от способа запроса и версии API, поэтому перед реализацией сверяйтесь с документацией MODX 3.x.
4. Решите, нужен ли кеш
Кешируемый вызов подходит для результата, который меняется редко и зависит только от стабильных параметров. Если вывод зависит от авторизованного пользователя, cookie, текущей сессии или свежих данных, кеш может показать одному посетителю результат другого или устаревшее значение.
| Ситуация | Решение | Цена |
|---|---|---|
| Статический блок для страницы | Обычный вызов сниппета | Быстрее после прогрева кеша, но результат может быть не мгновенно свежим |
| Результат меняется после каждого запроса | Некешируемый вызов с префиксом ! | Код выполняется чаще и потребляет ресурсы PHP |
| Вывод зависит от пользователя | Проверить кеш страницы и кеш сниппета отдельно | Нужно тестировать права и приватность, а не только внешний вид |
| Большая выборка из базы | Сначала ограничить объём и проверить запрос | Меньше данных в ответе, но потребуется продумать пагинацию или кеширование |
Префикс ! в вызове MODX отключает кеширование результата этого вызова. Это не отменяет кеш браузера, кеш страницы на сервере или кеш CDN. Проверяйте все уровни отдельно.
5. Проверьте контексты и права
Сниппет может работать в контексте web и ломаться в другом контексте из-за настроек, путей, языковых параметров или доступа к ресурсам. Откройте страницу в каждом контексте, где используется вызов. Для мультиязычного сайта отдельно проверьте отсутствие перевода, пустой ресурс и неверный идентификатор.
Не выдавайте сниппету права, которые ему не нужны. Если он только форматирует входную строку, ему не требуется доступ к административным данным. Если код читает объекты MODX, убедитесь, что запрос не раскрывает скрытые ресурсы, внутренние поля или данные другого пользователя.
6. Добавьте предсказуемое поведение при ошибке
Пустая строка иногда лучше, чем PHP-исключение, но только если отсутствие блока не ломает страницу. Для критичного результата безопаснее остановить публикацию и записать ошибку в журнал. Не показывайте посетителю трассировку, путь к файлу, SQL-запрос и содержимое конфигурации.
Перед публикацией проверьте четыре сценария:
- Параметр заполнен корректно. Должен появиться ожидаемый результат.
- Параметр отсутствует. Страница должна отобразиться без предупреждений PHP.
- Передана строка с кавычками, HTML-тегами и Unicode-символами. Разметка страницы не должна измениться.
- Запрос не находит запись. Сниппет должен вернуть согласованный пустой результат, а не случайный PHP Notice.
Как вызывать сниппет в MODX
Вызов должен быть коротким и читабельным. Если значение берётся из поля текущего ресурса, передайте его как параметр и не дублируйте бизнес-логику в шаблоне.
[[!DisplayName? &name=`[[*pagetitle]]`]]
Для кешируемого вывода уберите !, но только после проверки того, что результат не зависит от посетителя и быстро обновляется после очистки кеша. Если вызов вложен в чанк или другой сниппет, проверьте порядок разбора тегов: итоговый HTML должен содержать готовый результат, а не необработанный MODX-тег.
Что ломается перед продакшеном
- Пустой результат после публикации. Чаще всего параметр не передан, используется другое имя свойства или сработал старый кеш. Очистите кеш, проверьте вызов и временно выведите диагностическое значение только на тестовой копии.
- Notice или Warning в логах PHP. Код обращается к отсутствующему ключу массива или рассчитывает, что объект всегда найден. Используйте значения по умолчанию и проверяйте результат запроса.
- HTML ломается на кавычках. Значение вставляется без экранирования. Определите контекст вывода и примените подходящее экранирование именно для него.
- Страница стала медленнее. Сниппет выполняется в цикле, делает запрос для каждой строки или вызывает тяжёлую операцию при каждом некешируемом обращении. Посчитайте количество вызовов и запросов на один запрос страницы.
- В тесте работает, а в продакшене нет. Отличаются PHP-версия, расширения, права файлов, контекст, настройки кеша или данные. Сравните окружения, а не переписывайте код вслепую.
Где подход ломается
Небольшой сниппет удобен для локальной логики: форматирования, выбора данных, построения компактного блока. Он плохо подходит для полноценной предметной области, сложного импорта, фоновых задач и кода, который должен выполняться по расписанию. В таких случаях логику лучше вынести в отдельный компонент или сервис, а сниппет оставить тонким слоем вызова.
Не превращайте сниппет в универсальный маршрутизатор с десятком режимов. Параметр mode, который переключает SQL, HTML, отправку почты и удаление данных, усложняет права, тестирование и откат. Несколько маленьких сниппетов обычно проще проверить, чем один скрытый комбайн.
Сноска. Контекст MODX — область настроек и ресурсов сайта, например публичная часть или отдельный домен. В разных контекстах могут отличаться права, настройки URL, язык и доступные ресурсы.
Что сделать дальше
После публикации не закрывайте задачу очисткой кеша. Зафиксируйте версию MODX и PHP, сохраните код сниппета в системе контроля версий, добавьте тестовую страницу с пустыми и特殊ными входными данными и проверьте журнал ошибок после первых запросов. В продакшене измеряйте время ответа страницы, число SQL-запросов и частоту вызова сниппета. Если любой из показателей растёт после добавления логики, сначала ищите лишние вызовы и кеширование, а не оптимизируйте отдельную строку PHP.
Тендерный специалист 44-ФЗ / 223-ФЗ: Разбор PDF-документации закупки, поиск «заточек» под поставщика, чек-лист заявки.
Спросить за 20 ₽Источники: MODX Documentation: Snippets, MODX Documentation
Частые вопросы
Можно ли писать код сниппета прямо в админке MODX?
Почему сниппет возвращает старый результат?
Нужно ли всегда использовать некешируемый вызов?
Что будет, если я не успел проверить сниппет на тестовой копии?
Почему сниппет работает в одном контексте MODX, но не работает в другом?
Можно ли выводить из сниппета HTML без экранирования?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.