Шаблоны и чанки в MODX: организация файловых элементов и синтаксис Fenom

Шаблоны и чанки в MODX: организация файловых элементов Курс

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

Что такое шаблоны MODX?

Шаблон (template) — это «скелет» страницы, с помощью которого контролируется базовая разметка, подключаются общие стили и скрипты, задаются места для динамических блоков (чанков, сниппетов, данных из TV).

  • Каждый ресурс (страница) может использовать свой шаблон — это удобно для многоуровневых сайтов и интернет-магазинов.
  • В шаблоне размещаются вызовы чанков, сниппетов, TV-переменных и системных тегов MODX/Fenom.
  • Шаблон — основа для дальнейшей интеграции HTML-шаблона/дизайна.

Что такое чанки?

Чанк (chunk) — это мини-шаблон или фрагмент кода, который удобно использовать для сборки повторяющихся частей сайта: меню, подвал, боковые панели, формы, карточки и т.д.

Основные плюсы:

  • Вся разметка лежит централизованно, редактируется в одном месте и минимизируются ошибки.
  • Легко вынести в файл для лучшей структуризации и ускорения разработки (особенно в крупных проектах).
  • Идеально интегрируются через Fenom —
    например {include 'chunks/header.tpl'}

Краткий разбор синтаксиса Fenom

Для тех кто забыл или не делал ДЗ из прошлого урока, да и повторение — мать учения.

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

Плейсхолдеры в чанках сохраняют свою функциональность, но записываются иначе. Сравним синтаксис родного парсера MODX (modParser) и Fenom.

MODX (modParser) Fenom
[[+id]] {$id}
[[+id:default=`test`]] {$id ?: 'test'}
[[+id:is=``:then=`test`:else=`[[+pagetitle]]`]] {$id == ''? 'test': $pagetitle}

Для работы с ресурсами, настройками и другими элементами MODX в Fenom используется служебная переменная $_modx, предоставляющая безопасный доступ к основным методам и свойствам.

MODX (modParser) Fenom
[[*id]] {$_modx->resource.id}
[[*tv_param]] {$_modx->resource.tv_param}
[[%lexicon]] {$_modx->lexicon('lexicon')}
[[~7]] {$_modx->makeUrl(7)}
[[~[[*id]]]] {$_modx->makeUrl($_modx->resource.id)}
[[++system_setting]] {$_modx->config.system_setting}

Fenom и MODX-теги могут использоваться вместе в одном шаблоне, но обработка происходит в два этапа — сначала выполняются теги Fenom, затем MODX.

Организация файловых элементов: где что хранить?

В первом уроке мы говорили, что будем использовать файловые элементы (шаблоны, чанки, сниппеты, плагины), чтобы проект был структурированным и удобным для разработки.

По умолчанию каталог для файловых элементов{core_path}elements/ — т.е. в папке с ядром системы.  Лично мне это не нравится, поэтому давайте изменим к ним путь, делается это в системной настройке pdotools_elements_path: замените ее значение с {core_path}elements/ на {assets_path}elements/.

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

Далее нам нужно создать папку elements (в директории assets) — это место хранения наших файловых чанков, шаблонов и т.д. Далее для удобства в assets/elements/ создайте отдельные папки для каждого типа элементов вашего сайта:

  • Шаблоны: assets/elements/templates/
  • Чанки: assets/elements/chunks/
  • Сниппеты: assets/elements/snippets/

В итоге ваша структура должна выглядеть так:

/assets/elements/
 ├── templates/
 ├── chunks/
 ├── snippets/
Структура папок

Интеграция (перенос) готовой верстки

Делать все будем на основе готового HTML шаблона. Я буду использовать официально купленный шаблон Porto. Вы можете использовать любой (логика разработки от этого не меняется). Ну или на свой страх и риск поискать nulled версию данного шаблона (попадаются не самые свежие но все же).

Давайте сначала рассмотрим из чего вообще состоят шаблоны:

Файлы html шаблона

По факту это html файлы и папки с css, js и изображениями + различные php обработчики и т.п. Нам нужно перенести только css, js и изображения (у кого есть шрифты, то их тоже переносим). В общем берем и заливаем их в корень сайта (в моем случае, это папки css, js, vendor). Сделать это можно через файловый менеджер хостинга или ftp клиент.

Важно. Часто вижу шаблоны у которых все нужные папочки находятся в папке assets — тогда также переносите их в assets.

Создание файловых шаблонов

Это все можно делать как с админки, так и при помощи IDE, но статей о настройке IDE здесь пока нет, поэтому держите с ресурса web-revenue.ru: MODX: Работа с файловыми элементами (настройка нескольких способов: через IDE — PhpStorm, бесплатный редактор кода — Visual Studio Code (тоже можно назвать IDE, т.к. есть терминал и т.п.) и админку самого движка).
PS. Я буду использовать PhpStorm.

Создаём базовый шаблон base.tpl

Для организации сквозных элементов сайта заведите главный базовый файл base.tpl. В нём размещаются общие части для всех страниц — хедер, футер, основная структура, подключение CSS/JS.

И поместите в него пока весь код главной страницы (в моем случае это код из файла demo-seo-2.html).

Создание базового шаблона в IDE

Сохраняем и отправляем файл

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

Файл появился

Появился, все норм, едем далее.

Шаблоны для отдельных страниц: home.tpl, blog.tpl и другие

Для главной страницы создайте файл home.tpl, со следующим кодом:

{extends 'file:templates/base.tpl'} 
{block 'content'}

{/block}

Здесь, через {extends ...} мы подключаем базовый шаблон, а в  block 'content' нужно подключить остальной контент так сказать. Сейчас нам нужно вырезать не сквозные элементы и поместить их в block 'content'.

В моем случае, это все что внутри:

<div role="main" class="main"> здесь все вырезаем </div>

Вырезаем код

И вставляем его в шаблон домашней страницы. Должно получится примерно следующее:

Код главной

Сохраняем его и снова возвращаемся в base.tpl и на месте вырезанного кода пишем конструкцию:

{block 'content'}
        
{/block}

Наш базовый шаблон

Соответственно все сохраняем и давайте подключим наш файловый шаблон к MODX. Делать это будем через админку: идем на вкладку Элементы — Шаблоны (там у нас сейчас 1 шаблон — начальный), открываем его и вместо родного кода подключаем шаблон главной страницы, вот такой конструкцией:

{include 'file:templates/home.tpl'}

После можно переименовать его например в home, далее сохраняем его и переходим на главную страницу.

Сохраняем и переходим на главную

Если в место главной увидели просто белый лист — не пугайтесь, где то какие то фигурный скобки (у Fenom с ними конфликт, т.к. он сам их использует), в общем открываем  журнал ошибок и смотрим на что ругается.

Переход в журнал ошибок

Далее находим эти строчки (CTRL + F):

Находим строки

и правим: после { ставим пробел, и перед } тоже ставим пробел, проще всего это сделать через поиск и замену (Ctrl + F / R)

Поиск и замена

И по такой же логике для закрывающихся фигурных скобок.

Поиск и замена закрывающейся скобки

Сохраняем и снова проверяем главную (CTRL + F5), если она снова пустая. Идем снова в журнал ошибок и смотрим новые.

Новые ошибки

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

домашняя страница

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

Идем далее, нам еще нужно создать 5 шаблонов: services.tpl, services_detail.tpl, contacts.tpl, blog.tpl, blog_post.tpl (это столько у нас демок так сказать).

Внимательные думаю заметили — в именах файлов не -, а _. Это еще одна особенность Fenom, он не всегда дружит с -.

Demo шаблона

Логика как у home.tpl, т.е. создаем файловый шаблон, помещаем в него:

{extends 'file:templates/base.tpl'} 
{block 'content'}
Здесь код не сквозных элементов, которые внутри <div role="main" class="main">...</div>
{/block}

Создаем еще один шаблон

Сразу правим конфликты с фигурными скобками — если они присутствуют в коде. Сохраняем и так создаем остальные файловые шаблоны.

Созданы все файловые шаблоны

После этого создаем в админке новые шаблоны и вызываем в них наши файловые.

{include 'file:templates/services.tpl'}
{include 'file:templates/services_detail.tpl'}
{include 'file:templates/contacts.tpl'}
{include 'file:templates/blog.tpl'}
{include 'file:templates/blog_post.tpl'}

Создание шаблонов в админке

Можно сделать все на 1м шаблоне, с помощью специальных конструкций, или даже просто блоков (будем создавать в одном из следующих уроков).

Вынос общих блоков из base.tpl в чанки

Вообще я как то не очень люблю дробить шаблоны на отдельные чанки и т.п. (и делать этого не буду). Но вдруг вам так удобнее (хотите сократить код базового шаблона. путем его дробления), тогда можете к примеру создать вот такие чанки:

  • Меню → chunks/menu_main.tpl
  • Хедер → chunks/header.tpl
  • Футер → chunks/footer.tpl
  • Боковые панели, подвал, кнопки — отдельными чанками

Перенести код к них, а затем в шаблоне (base.tpl) для подключения чанка используйте:

{include 'chunks/header.tpl'} 
{include 'chunks/menu_main.tpl'} 
{include 'chunks/footer.tpl'}

Такой подход позволяет хранить каждый элемент разметки сайта отдельно и централизованно. Например:

/assets/elements/templates/
  - base.tpl
  - home.tpl
  - blog.tpl
/assets/elements/chunks/
  - header.tpl
  - menu-main.tpl
  - footer.tpl

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

Добавляем динамику

Сейчас у нас по факту статические шаблоны и управлять ими можно пока только, через код. Давайте частично исправим (это пока) и добавим немного синтаксиса Fenom в базовый шаблон (base.tpl). Только мета теги так сказать для начала и вот так начальный код преобразится.

{set $site_name = 'site_name' | config}
{set $site_url = 'site_url' | config}
{set $culture   = 'cultureKey' | config}
{set $title = ($_modx->resource.longtitle ?: $_modx->resource.pagetitle) | notags}
{set $description = $_modx->resource.description | replace :' "':' «' | replace :'"':'»'}
<!DOCTYPE html>
<html lang="{$cultureKey}">
<head>
    <base href="{$site_url}">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{$title}</title>
    <meta name="description" content="{$description}">
    <meta name="author" content="fastdevlab.com">
    <!-- Favicon --> и далее весь остальной

Давайте расшифрую его:

{set $site_name = 'site_name' | config}
{set $site_url = 'site_url' | config}
{set $culture   = 'cultureKey' | config}

Что делает:

  • Берёт значения системных настроек site_name, site_url и cultureKey.
  • Сохраняет их в переменные $site_name, $site_url и $cultureKey

Эквивалент в PHP:

$site_name = $modx->getOption('site_name');
$site_url  = $modx->getOption('site_url');
$cultureKey  = $modx->getOption('cultureKey');
Зачем сохранять системные настройки в переменные?

Это делается не для того, чтобы «заработало», а чтобы код был чище, быстрее и удобнее.

1) Производительность (небольшая, но есть)

Каждый обычный вызов вызов:

{'cultureKey' | config}

или

{$_modx->config.cultureKey}

— это обращение к конфигу.

Если ты вызываешь одно и то же значение 5–20 раз — ты 5–20 раз дергаешь MODX.

Когда сохраняешь в переменную:

{set $culture = 'cultureKey' | config}

то дальше используешь значение из памяти Fenom:

<html lang="{$culture}">

— уже без обращения к MODX.

2) Читаемость

Вместо длинных и визуально тяжелых конструкций:

{$_modx->config.site_name}
{'site_url' | config}

ты пишешь:

{$site_name}
{$site_url}

Читается быстрее и проще.

3) Единая точка управления

Если нужно поменять источник, фильтры или логику — меняется только строка с set.

Например:

  • хочешь фильтр trim добавить
  • хочешь fallback сделать
  • хочешь заменить кавычки

Достаточно изменить 1 строку, а не искать 10 вызовов по шаблону.

4) Упрощает условия

Например, в условии проще использовать:

{if $culture == 'ru'}

чем:

{if ('cultureKey' | config) == 'ru'}

5) Так делают во всех профессиональных Fenom-шаблонах

Просто потому что это:

  • чище;
  • короче;
  • поддерживаемее;
  • быстрее;

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

2. Формируем заголовок страницы (<title>)

{set $title = ($_modx->resource.longtitle ?: $_modx->resource.pagetitle) | notags}

Что делает: берёт longtitle, если он заполнен. Иначе использует pagetitle + удаляет HTML-теги через | notags

Эквивалент PHP:

$title = strip_tags($resource->get('longtitle') ?: $resource->get('pagetitle'));

3. Формируем description (мета-описание)

{set $description = $_modx->resource.description
| replace :' "':' «'
| replace :'"':'»'
}

Что делает:

  • Берёт поле description у ресурса;
  • Меняет комбинацию пробел + кавычка ( «) на пробел + «;
  • Меняет все двойные кавычки («) на русскую закрывающую кавычку »;

То есть текст Мой "текст" станет Мой «текст».

4. Устанавливаем язык страницы

<html lang="{$cultureKey}">

Берёт системную настройку cultureKey, например: ru, en, de.

5. Base URL

<base href="{$site_url}">
  • Устанавливает корень сайта;
  • Избегает путаницы с относительными ссылками.

6. Вставляет meta-теги

<title>{$title}</title>
<meta name="description" content="{$description}">
<meta name="author" content="fastdevlab.com">

Тут всё очевидно: вывод переменных $title и $description.

Человеческая расшифровка одним абзацем.
Код берет настройки MODX (site_name, site_url, cultureKey), формирует SEO-оптимизированный заголовок и description страницы, конвертирует кавычки в русские, устанавливает язык страницы, выводит мета-теги и ставит <base href>, чтобы все ссылки в шаблоне работали предсказуемо.

Ну давайте сразу испытаем работает наш немного обновленный код или нет. Идем в нашу пока единственную страницу, заполняем поля longtitle, description, сохраняем и смотрим.

Заполняем поля

В яндекс браузере сразу вижу, то подтянулся title.

title

Давайте откроем код: CTRL + U. Все должно быть заполнено.

Все работает

На сегодня думаю достаточно. В следующий урок будет попроще и покороче, будем выносить повторяющиеся поля (ну или сквозные: телефоны, соц сети и т.п. в системные настройки (при помощи компонента ClienConfig), и затем выводить их в нашем базовом шаблоне.

Если вам что-то не понятно, welcome в комментарии)

Оцените статью
MODX 3
Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.