Когда MODX установлен, настроен и загружены основные пакеты, можно приступать к разработке сайта.

Для начала давайте разберем архитектуру системы MODX и ее основные сущности, с которыми будем работать, и как они друг с другом связаны.

Сущности

Ресурсы

Ресурс — это условное представление страницы, карточка, где мы сможем редактировать данные страницы и ее содержимое. Ресурсом будет и статья в блоге, и товар в магазине, и страница лэндинга - любая страница на сайте. Далее в статье могу называть ресурс страницей, это нормально.

Ресурс может быть и обычной HTML страницей, и другим файлом - .css, .js, .php и так далее.

Есть 4 типа ресурсов:

  • документ
  • ссылка
  • символическая ссылка
  • файл

При разработке мы будем работать в основном с первым типом - документ, который представляет на выходе простую html страницу. Но остальные типы тоже могут быть полезны — например, при создании карты сайта MODX мы создаем ресурс типа «Файл» с расширением «XML».

У ресурса есть базовые поля, заложенные разработчиками:

  • заголовок pagetitle
  • расширенный заголовок longtitle
  • описание
  • аннотация
  • содержимое

Посмотреть название поля можно наведя курсор на его заголовок.

Все эти поля можно редактировать на странице изменения ресурса.

Для создания дополнительных полей, например, цены товара или просмотров статьи — используются TV поля. Принцип их работы разберем дальше.

Шаблоны

За внешний вид ресурса отвечает шаблон. Если у ресурса не будет шаблона, то при открытии этой страницы в браузере выведется поле ресурса «содержимое».

Таким образом можно создавать любые страницы просто на HTML, CSS и JS, не вникая в синтаксис MODX.

Тогда в поле content ресурса будет полностью страница, условно:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <header>Шапка</header>
        <main>Контент</main>
        <footer>Подвал</footer>
    </body>
</html>

Вопрос только, зачем тогда использовать шаблоны? Чтобы разобраться, давайте пойдем от совсем простого.

У нас есть элементы, которые повторяются на каждой странице сайта: шапка и подвал. Если размещать код страницы в поле «содержимое», то для изменения шапки или подвала придется заходить и редактировать каждый ресурс. При большом количестве страниц это будет слишком долго и неудобно.

И тут на помощь приходят шаблоны. Создадим базовый шаблон с шапкой и подвалом, а между ними укажем поле "содержимое". Тогда шапку и подвал мы сможем редактировать один раз — в шаблоне, а контент страницы уже отдельно в ресурсах.

<!-- Код шаблона -->
<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <header>Шапка</header>
        <main>[[*content]]</main>
        <footer>Подвал</footer>
    </body>
</html>

Шаблон - это заранее сформированный код страницы, в котором мы указываем, где вывести поля ресурса, переменные шаблона, чанки или сниппеты.

У большинства сайтов есть типовые страницы: статья, раздел, каталог, товар, вопрос-ответ и подобное. Каждый такой тип страницы — это отдельный шаблон.

Для создания шаблона мы возьмем условную верстку статьи, и вместо конкретного заголовка и текста просто укажем, где нужно вывести поля ресурса "заголовок" и "содержимое".

<!-- Код шаблона -->
<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>[[*longtitle:default=`[[*pagetitle]]`]]</title>
    </head>
    <body>
        <header>Шапка</header>
        <main>
            <h1>[[*pagetitle]]</h1>
            <div>[[*content]]</div>
        </main>
        <footer>Подвал</footer>
    </body>
</html>

Теперь нужно «привязать» шаблон к ресурсу. Для этого на странице ресурса выберите в поле «Шаблон» подходящий вариант. При генерации страницы MODX заменит указанные в шаблоне переменные на их значения у конкретного ресурса.

Можно также создать базовый шаблон страницы, где будет только шапка и подвал, а между ними будет выводиться содержимое ресурса. Это полезно для создания отдельных страниц, которые встречаются на сайте в единственном экземпляре: «о нас», «контакты», «правила», «доставка» и подобные, где шаблон как таковой не нужен, но общие элементы должны быть как на всем сайте.

Я обычно делаю шаблоны под повторяющиеся страницы, и один «пустой», в котором есть только шапка и футер, как раз для таких целей. Единичным страницам назначаю его, а контент верстаю прямо в поле "содержимое".

Запомнили: ресурс — это страница или файл, шаблон — это верстка страницы, где указаны переменные, которые MODX заменяет на конкретные значения при генерации страницы.

Ресурсу мы назначаем шаблон, но при этом ресурс может быть и без шаблона. Тогда при просмотре этого ресурса выведется контент поля «содержимое».

Чанки

Чанк — это дословно "кусок" кода. В чанках мы можем использовать только html, js, css и теги MODX. Чистый PHP в чанках работать не будет, но его можно вызывать через сниппеты, которые мы разберем дальше.

Зачем нужны чанки, если у нас уже есть шаблоны? Давайте представим, что нужно сделать 3 шаблона: «пустая страница», «товар» и «категория». В каждом из шаблонов нам нужна будет одинаковая шапка сайта и подвал, а также форма обратной связи.

По логике, шаблон — это верстка, поэтому мы верстаем страницы в html, и создаем 3 разных шаблона, правильно?

Но тут замечаем, что код шапки и подвала снова повторяется в 3 разных местах — в 3 шаблонах. Пробема та же самая, которую раньше мы пытались решить с помощью шаблонов — редактировать неудобно, долго, повышается вероятность ошибки.

Было бы неплохо хранить и редактировать код этих элементов в одном месте, а вызывать в нужных местах как переменную. Как раз для этого нужны чанки.

Мы создадим 2 чанка, например, tplHeader и tplFooter, и в каждом разместим соответствующий html код этого элемента.

<!-- tplHeader -->
<header>Шапка</header>
<!-- tplFooter -->
<footer>Подвал</footer>

Потом вернемся в шаблоны, удалим код элементов и вызовем вместо него эти чанки.

<!-- Код шаблона -->
<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>[[*longtitle:default=`[[*pagetitle]]`]]</title>
    </head>
    <body>
        [[$tplHeader]]
        <main>
            <h1>[[*pagetitle]]</h1>
            <div>[[*content]]</div>
        </main>
        [[$tplFooter]]
    </body>
</html>

В итоге весь код сокращается до простой переменной. И задача решена: менять код элемента можно в одном месте — чанке. А изменения сразу будут отражаться во всех шаблонах у всех ресурсов.

Или, например, нам нужно вывести список статей. Айтем статьи в списке имеет определенную верстку, а их должно быть много. Размножать вручную, что ли? Нет - мы создаем чанк с разметкой превью статьи, и при вызове списка статей указываем его как шаблон. Как это делается, разберем позже, пока просто принцип работы чанков.

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

TV поля (поля шаблонов)

Temlate Value, в обиходе "TV поля". Как уже писал выше, в разделе про ресурсы, TVs - это дополнительные поля для хранения информации о ресурсе. Например, цена товара, просмотры статьи, изображение товара и подобные.

Важный момент — TV поле привязано к шаблонам, а не конкретным ресурсам. И уже ресурсы, которые имеют соответствующий шаблон, имют доступ к TV. Например, TV картинка превью может быть привязана к шаблону товара, статьи и новости. Тогда в ресурсах с этими шаблонами будет выводится это поле.

TV поля могут быть разных видов: текстовое, даты, числа и тд. Соответственно, мы можем настроить и их вывод.

Например, нам нужно создать поле "цена товара". Давайте разберем процесс пошагово.

Для начала создаем шаблон страницы товара, "Товар". Затем создаем ресурс и указываем у него в настройках шаблон "Товар". После создаем TV поле "Цена товара" и привязываем его к шаблону "Товар".
Теперь у созданного ресурса появится дополнительное поле "Цена". Создавать можно и в другом порядке, я просто хочу показать связи.

Сниппеты

В отличие от чанков, где мы могли использовать только html, css и js, сниппеты — это блоки PHP кода, которые могут либо просто выполнять какое-то действие, либо возвращать результат.

Зачастую сниппет возвращает HTML код или какое-то значение. Для использования большинство пакетов (дополнений) реализованы в виде сниппетов, которые можно вызывать в шаблонах и чанках.

В чанке или шаблоне указывается вызов сниппета с определенными параметрами. При парсинге выполняется PHP код сниппета, сниппет вернет значение и оно подставится в место, где вызван сниппет.

В определенной степени на сниппет можно смотреть, как на функцию — он получает какие-то данные на вход и возвращает результат.

В начале знакомства с MODX и разработке простых сайтов, скорее всего, вы будете использовать только сниппеты из пакетов, потому что их вполне хватает для выполнения базовых задач.

Однако для полноценной работы, в идеале подтянуть знания PHP и изучить MODX API. Тогда Вы сможете разрабатывать нужные сниппеты самостоятельно, что сильно повышает вашу ценность, как специалиста и дает гибкость при разработке сайтов на MODX.

Сниппеты — это универсальный инструмент, так как в них можно использовать MODX API и самостоятельно прописывать гибкую логику формирования ответа. Подробнее про них можно почитать в статье.

Плагины

Плагин — это также фрагмент PHP кода, но он как раз ничего не возвращает при генерации страницы. Его нельзя вызвать из шаблонов, чанков и тд.

Плагин будет выполняться по определенным событиям. Например, при загрузке страницы на сайте, при загрузке страницы ресурса в админке, при сохранении ресурса в админке.

Для разработки простого сайта плагины также не особо нужны, но желательно как минимум знать об их существовании, а еще лучше также подтянуть PHP и уметь писать их самостоятельно, это бывает крайне полезно.

Например, плагин можно использовать, чтобы встроить на страницу админки собственные стили. Или чтобы перед рендерингом статьи на сайте прогнать текст через типограф.

Я в статьях, например, с помощью плагина автоматически заменяю изображения на чанк с обрезанием картинки под нужный размер, чтобы улучшить скорость загрузки сайта.

Подобные фишечки иногда экономят кучу времени.

Системные настройки

В MODX также есть системные настройки, которые доступны в виде тегов MODX. Это может прогодиться, например, чтобы задать в системной настройке домен сайта, и в шаблонах указывать не текст, а вызов системной настройки. Тогда при переезде на другой домен достаточно будет поменять его всего в одном месте. По сути системные настройки можно сравнить с глобальными переменными.

Синтаксис

Мы изучили основные сущности. Их можно использовать в виде тегов MODX: вызывать в шаблоне, в поле содержимого ресурса, в чанках, и с помощью API в сниппетах.

Формат вызова тегов:

[[$tplChunk]] <!-- чанк -->
[[phpSnippet]] <!-- сниппет -->
[[*pagetitle]] <!-- поле ресурса -->
[[*TVValue]] <!-- TV поле -->
[[+placeholder]] <!-- плейсхолдер -->
[[++setting]] <!-- системная настройка -->
[[~link]] <!-- Ссылка -->

Параметры и плейсхолдеры

Чанки и сниппеты можно вызывать, передавая в них параметры. Параметры отделяются от имени тега знаком вопроса, а между собой амперсандом, так же, как параметры http запроса. Далее эти параметры можно использовать внутри чанка или сниппета через плейсхолдеры в чанках, или переменные в сниппетах.

Как видите, появилась еще одна штука, плейсходер. С ними все довольно просто. Когда вы вызываете чанк с параметрами, в самом чанке можно использовать плейсхолдеры для отображения этих параметров.

<!-- Вызвали чанк с параметрами -->
[[$tplHello?name=`Олег`&age=`23`]] 
<!-- Вывод чанка tplHello -->
<p>Привет, [[+name]], тебе [[+age]]</p>
<!-- Вернет <p>Привет, Олег, тебе 23 года</p> -->

Если же мы вызовем сниппет с параметрами, то там это будет выглядеть примерно так:

<!-- Вызвали сниппет с параметрами -->
[[phpHello?name=`Олег`&age=`23`]] 

Получаем параметры в сниппете и вовращаем результат:

// Получить параметр и назначить значение по умолчанию
$name = $modx->getOption('name', $scriptProperties, 'Не указано');
// Просто получить параметр
$age = $modx->getOption('age', $scriptProperties);

$output = "<p>Привет, {$name}, тебе {$age}</p>";

return $output;

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

// Получить параметр имя
$name = $modx->getOption('name', $scriptProperties);
// Получить параметр возраст
$age = $modx->getOption('age', $scriptProperties);

$output = "";
if (empty($name) || empty($age)) {
    $output = "<p>Некорректно указано имя или возраст</p>";
} else {
    $output = "<p>Привет, {$name}, тебе {$age}</p>";
}

return $output;

Здесь я указываю HTML прямо в сниппете, но вообще это считается плохой практикой. Изначально задумано, что в сниппете мы строим php массив данных, а потом вызываем чанк и передаем в него эти данные. А в чанке они подставятся в плейсхолдеры. Я думаю это стоит подробно разобрать в отдельном уроке, но вкратце давайте разберем здесь.

Вот наш чанк tplHello.

<!-- Вывод чанка tplHello -->
<p>Привет, [[+name]], тебе [[+age]]</p>

Мы вызываем сниппет phpHello, передавая в параметры имя и возраст.

<!-- Вызвали сниппет с параметрами -->
[[phpHello?name=`Олег`&age=`23`]] 

Затем в сниппете получаем параметры, и генерируем HTML код чанком.

// Получить параметр имя
$name = $modx->getOption('name', $scriptProperties);
// Получить параметр возраст
$age = $modx->getOption('age', $scriptProperties);

$output = "";

// Генерируем HTML вызовом чанка с параметрами
$output = $modx->getChunk('tplHello', array('name'=>$name, 'age'=>$age));

return $output;

Таким образом вызов чанка тегом MODX:

<!-- Вызвали сниппет с параметрами -->
[[phpHello?name=`Олег`&age=`23`]] 

Эквивалентен вызову чанка в сниппете:

$output = $modx->getChunk('tplHello', array('name'=>$name, 'age'=>$age));

В параметры вызова чанка и сниппета также можно передать значения полей ресурса и TV, плейсхолдеры, или даже вызов другого чанка или сниппета.

[[tplTest?param1=`[[*pagetitle]]`¶m2=`[[+age]]`¶m3=`[[$tplHello]]`]] 

Комментирование тегов

Если нужно временно скрыть вызов тега, можно заккоментировать его вот так:

[[--$tplChunk]]

Кэширование тегов

Фильтры и модификаторы

Подход к разработке

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

Первый вариант разработки сайта на MODX, который можно использовать сразу, и он подойдет новичку - это использование готовых пакетов из менеджера пакетов.

Из минусов - все равно нужно будет разбираться в работе пакетов и сниппетов из них, но они существуют уже достаточно давно и в сети есть куча информации, как официальной документации разработчиков, так и специалистов по MODX. И это проще, чем изучать PHP.

Второй вариант - изучить PHP и API MODX, и уметь разрабатывать все самостоятельно. Нужно понимать, что это вариант нельзя назвать более "правильным" - он скорее расширяет ваши возможности. Но для решения большинства задач хватит и обычных пакетов. Но вот когда их не хватает - знание сниппетов дает возможность написать нужное решение самостоятельно.

Переписывать решения на пакетах имеет смысл только для оптимизации нагрузки, так как пакеты - это универсальное решение, которое учитывает все возможные варианты использования и может быть "перегружено" функционалом для конкретного проекта.

Если вы собираетесь выполнять задачи по клиентским сайтам на MODX, скорее всего там будут использоваться пакеты, но могут встретиться и самописные решения, поэтому нужно уметь использовать оба варианта.

Кроме того, есть еще возможность использования других шаблонизиторов, например Fenom. Это дает дополнительное удобство при написании шаблонов, но концептуально ничего не меняется - вы все равно будете использовать чанки, сниппеты, устанавливать пакеты. Поэтому шаблонизиторы лучше изучать уже после хотя бы понимания базовых вещей.

В общем эти два варианта существуют параллельно друг с другом - разработать сайт можно и так, и так. Самым правильным, как мне кажется, будет...

Дополнительно

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

Надеюсь, эта статья объяснит основы разработки на MODX и поможет начать создавать сайты. Можете добавить ее в закладки браузера и поделиться в соцетях. Спасибо за прочтение!