🖼️ View
Класс View в PageBlocks — это обёртка над шаблонизатором Fenom, которая предоставляет простой и мощный способ рендерить шаблоны: чанки MODX, .tpl-файлы, @INLINE-шаблоны и другие.
🚀 Быстрый старт
Вы можете рендерить шаблон с передачей данных:
use Boshnik\PageBlocks\Facades\View;
View::make('@INLINE <p>{$title}</p>', ['title' => 'Главная']);Или с помощью хелпера:
view('file:templates/base.tpl', ['title' => 'Главная']);💡 Пример с контроллером
Route::get('/', function () {
return view('file:templates/base', ['name' => 'PageBlocks']);
// => ищет: core/App/elements/templates/base.tpl
});🔧 Пример со сниппетом
Допустим, у вас есть сниппет MyProfile, который выводит профиль текущего пользователя:
<?php
$user = $modx->user;
return view('file:blocks/profile.tpl', [
'username' => $user->get('username'),
'email' => $user->getOne('Profile')->get('email'),
]);Чанк core/App/elements/blocks/profile.tpl:
<div class="profile">
<h2>{$username}</h2>
<p>Email: {$email}</p>
</div>📄 Tипы шаблонов
| Где ищется | Пример |
|---|---|
Инлайновый код шаблона (@INLINE) | view('@INLINE Hello, {$name}') |
Файловый шаблон (@FILE, file:) | view('@FILE blocks/card.tpl') |
MODX-шаблон (template:) | view('template:base') |
По умолчанию: сначала modChunk, потом файл | view('header') |
Если расширение не указано, по умолчанию добавляется .tpl для файлов.
⚙️ Настройки
| Настройка | Описание | Значение по умолчанию |
|---|---|---|
pageblocks_elements_path | Путь к файловым шаблонам от папки core/. Используется для @FILE и file: шаблонов. | App/elements/ |
pageblocks_file_elements_only | Если true, шаблоны берутся только из файлов, MODX чанки игнорируются. Повышает производительность. | false |
pageblocks_fenom_auto_reload | Автоматическая перекомпиляция шаблонов при изменении файлов. В продакшене можно выключить для лучшей производительности. | true |
📁 Где хранятся шаблоны
Если вы используете file: или @FILE, путь указывается относительно директории pageblocks_elements_path.
Пример:
view('file:blocks/article.tpl');
// => ищет: core/App/elements/blocks/article.tpl📦 Доступные данные
🧠 $modx
В шаблонах доступен глобальный объект $modx, такой же, как в PHP-коде. Это позволяет обращаться к ресурсам, текущему пользователю и другим системным данным прямо из шаблонов:
🔹 Текущий документ
{$modx->resource->id} {* ID текущей страницы *}
{$modx->resource->pagetitle} {* Заголовок документа *}
{$modx->resource->get('template')} {* Получение произвольного поля *}🔹 Текущий пользователь
{$modx->user->username}
{$modx->user->id}
{$modx->user->get('email')}
{$modx->user->getGravatar()}💬 Flash-сообщения
Передаются через сессию $_SESSION['pageblocks']['flash']. В шаблоне доступны:
old_input— предыдущие значения полей формыerrors— сокращённые ошибки по каждому полю (одга ошибка на каждое поле)errors_full— все ошибки по каждому полюsuccess_message— сообщение об успешном действииerror_message— сообщение об ошибке
Примеры:
{if $errors.email}
<p class="error">{$errors.email}</p>
{/if}
<input type="text" name="email" value="{$old_input.email}">
{if $success_message}
<div class="alert alert-success">{$success_message}</div>
{/if}
{if $error_message}
<div class="alert alert-danger">{$error_message}</div>
{/if}Если нужно вывести все ошибки:
{foreach $errors_full as $field => $list}
{foreach $list as $msg}
<p class="error">{$msg}</p>
{/foreach}
{/foreach}💡 Все flash-данные очищаются после первого отображения.
🧩 Модификаторы
PageBlocks расширяет возможности шаблонов Fenom с помощью модификаторов — небольших функций, которые можно применять прямо в шаблонах. Они делают шаблоны лаконичнее и гибче.
🛠 Как добавить свои модификаторы
Вы можете добавить пользовательские модификаторы в файл:
core/App/Helpers/fenom/modifiers.phpЭтот файл должен возвращать массив вида:
return [
'upper' => function($value) {
return mb_strtoupper($value);
},
'users' => function () {
return query('modUser')
->alias('user')
->select('user.*,profile.*')
->where(['active' => 1])
->join('modUserProfile', 'profile', 'user.id = profile.internalKey')
->get();
},
];Вызов модификаторов в шаблоне
- Как фильтр для значения:
<h2>{$title|upper}</h2>- Как функция:
{users()}Это вернёт список всех активных пользователей с их профилями.
Внутри функции доступна переменная
$this->modx— текущий экземпляр MODX.
🔧 Модификаторы по умолчанию
PageBlocks уже содержит множество полезных модификаторов из коробки:
| Название | Описание |
|---|---|
route | Получить путь по названию маршрута: {route('home')} |
lang | Получить перевод строки из словаря: {lang('title')} |
config | Получить конфиг из Config или MODX: {'site_name'|config} |
url | Сгенерировать ссылку по ID ресурса: {1|url} |
lexicon | Получить фразу из лексикона MODX |
resource | Получить поле или все данные ресурса по ID |
user | Получить поле пользователя по ID или текущего |
chunk | Вставить чанк MODX: {'header'|chunk} |
snippet | Выполнить сниппет MODX: {'getResources'|snippet: ['parents' => 1]} |
button | Автоматическая генерация кнопки по данным |
notags | Удаление HTML-тегов: {notags($text)} |
isloggedin | Проверка на авторизацию |
ismember | Проверка, состоит ли пользователь в группе |
phone | Очистка строки до телефонного номера |
pbJson | Упрощённый вызов сниппета pbJson для сериализации |
cssToHead | Подключение CSS в <head> |
jsToBottom | Подключение JS в конец документа |
preg_replace | Регулярная замена по шаблону |
print | Вывод отладочной информации в <pre> |
⚡ Псевдо-теги
Вы можете создавать собственные псевдо-теги (линейные функции), которые вызываются как обычные функции Fenom:
{icon 'edit' class='icon-sm'}Такие теги удобно использовать вместо длинных вставок с insert или include, особенно для повторяемых HTML-фрагментов, как, например, иконки, кнопки или бэйджи.
📁 Где хранить
Создайте файл:
core/App/Helpers/fenom/inline_tags.phpВ него возвращается массив из имён и функций:
return [
'icon' => function($params) {
$name = array_shift($params);
$attrs = [];
foreach ($params as $key => $value) {
$attrs[] = htmlspecialchars($key).'="'.htmlspecialchars($value).'"';
}
$attrStr = $attrs ? ' ' . implode(' ', $attrs) : '';
$path = MODX_BASE_PATH . "assets/icons/{$name}.svg";
if (!file_exists($path)) {
return "<!-- icon '{$name}' not found -->";
}
$svg = file_get_contents($path);
return preg_replace('/<svg\b(.*?)>/', '<svg$1' . $attrStr . '>', $svg, 1);
},
];✨ Примеры в шаблонах
{icon 'edit' class='icon-sm text-muted'}
{icon 'user' class='icon-lg' aria-hidden='true'}Такие функции не требуют объявления через
insertилиinclude, проще читаются и легко масштабируются.
🧱 Блочные теги
Блочные теги (block functions) позволяют оборачивать содержимое шаблона в условный блок. Контент внутри такого блока будет отображён только если выполнится заданное условие.
Это особенно полезно, когда нужно контролировать доступ к определённым частям шаблона — например, показывать меню только авторизованным пользователям или только администраторам.
✅ Пример использования
{auth}
<a href="/profile">Профиль</a>
{/auth}
{guest}
<a href="/login">Вход</a>
{/guest}В этом примере:
- Блок
{auth}сработает только для авторизованных пользователей. - Блок
{guest}— только для гостей.
🧩 Как добавить свой блочный тег
Блочные теги подключаются из файла:
core/App/Helpers/fenom/block_tags.phpВ этот файл можно добавить новый тег, например superadmin, который будет отображать контент только для пользователя с ID = 1:
return [
'superadmin' => function (array $params, $content) {
if ($this->modx->user->id === 1) {
return $content;
}
},
];📦 Как это использовать
{superadmin}
<div class="alert alert-danger">
Вы супер-админ!
</div>
{/superadmin}Контент внутри блока будет показан только если пользователь — супер-администратор.
📘 Как это работает
Блочный тег — это функция, которая получает:
$params— параметры, переданные в теге (можно использовать, если нужно),$content— содержимое между открывающим и закрывающим тегом.
🌍 Глобальные переменные
В Fenom можно подключать глобальные переменные, доступные из любого шаблона. Это удобно для хранения статичных данных, настроек или общих значений, например: название проекта, email поддержки, путь до ассетов и т.п.
🛠 Как это работает
Файл core/App/Helpers/fenom/data.php должен возвращать массив с нужными данными:
return [
'package' => 'PageBlocks',
'support_email' => 'support@example.com',
];Этот массив будет доступен в шаблонах как глобальный объект $.pb.
📦 Пример использования в шаблоне
{$.pb.package} {* Выведет: PageBlocks *}
{$.pb.support_email} {* Выведет: support@example.com *}Глобальные переменные находятся в области pb, поэтому для доступа к ним нужно писать {$.pb.ключ}.
🔐 Функции PHP
По умолчанию Fenom поддерживает ограниченный набор безопасных PHP-функций, которые можно вызывать прямо в шаблонах:
✅ Доступные по умолчанию функции
| Функция | Назначение |
|---|---|
count() | Подсчёт количества элементов массива |
is_string() | Проверка, является ли переменная строкой |
is_array() | Проверка, является ли переменная массивом |
is_numeric() | Проверка, является ли переменная числом |
is_int() | Проверка на целое число |
constant() | Получение значения константы |
is_object() | Проверка, является ли переменная объектом |
gettype() | Получение типа переменной |
is_double() | Проверка на число с плавающей точкой |
strtotime() | Преобразование строки в метку времени |
json_encode() | Преобразование данных в JSON |
json_decode() | Декодирование JSON-строки |
ip2long() | IP → integer |
long2ip() | Integer → IP |
strip_tags() | Удаление HTML-тегов |
nl2br() | Перевод \n в <br> |
explode() | Разбиение строки по разделителю |
implode() | Склеивание массива в строку |
🧠 Пример использования
{count($items)} элементов
{json_encode(['foo' => 'bar'])}
{strtotime("2025-01-01")}
{strip_tags($html)}➕ Разрешение дополнительных функций
Вы можете разрешить другие безопасные функции:
core/App/Helpers/fenom/php_functions.php:
return [
'lcfirst',
'mb_strlen',
'htmlspecialchars',
];⚠️ Безопасность
Никогда не разрешайте опасные функции, такие как:
eval,exec,system,shell_execfile_get_contents,fopen,unlink
Они могут привести к утечке данных или удалённому выполнению кода.
Разрешайте только чистые и предсказуемые функции, которые не взаимодействуют с файловой системой, сетью или окружением.
🧪 Обработка результата
Третий аргумент метода View::make() или хелпера view() — это обработчик скомпилированного вывода.
Полезно для:
🔹 Удаления HTML
view('user-card.tpl', ['user' => $user], function ($buffer) {
return strip_tags($buffer);
});📄 Результат: чистый текст без
<div>,<a>и других тегов — удобно для текстовых писем.
🔹 Минификация HTML
view('page.tpl', [], function ($buffer) {
return preg_replace('/\s{2,}|\n/', '', $buffer);
});📉 Убирает пробелы и переносы — ускоряет загрузку страницы.
🔹 Автоматическая цензура
view('comment.tpl', ['text' => $comment], function ($buffer) {
return str_ireplace(['дурак', 'идиот'], '[цензура]', $buffer);
});🛡️ Применяется при модерации пользовательского контента.
🔹 Замена абсолютных путей
view('page.tpl', [], function ($buffer) {
return str_replace('https://example.com/assets/', '/assets/', $buffer);
});🔁 Удобно при переносе сайта между окружениями.
🔹 SEO: добавление rel="nofollow" ко всем ссылкам
view('page.tpl', [], function ($buffer) {
return preg_replace('/<a (.*?)href="(.*?)"(.*?)>/i', '<a $1href="$2" rel="nofollow"$3>', $buffer);
});🔍 Защищает от SEO-спама, особенно в комментариях или гостевом контенте.
🧮 Конструктор запросов
В шаблонах доступен хелпер query() — хелпер для pbQuery. Вы можете выполнять запросы к базе данных прямо из шаблонов Fenom.
📊 Подсчёт записей
{query('modResource')->where(['published' => 1])->count()}📋 Получить список ресурсов
{set $resources = query('modResource')
->where(['template' => 4])
->sortBy('menuindex')
->limit(5)
->fetchAll()
}
<ul>
{foreach $resources as $res}
<li><a href="{$res.uri}">{$res.pagetitle}</a></li>
{/foreach}
</ul>🔀 Использовать join
{set $users = query('modUser')
->alias('u')
->where(['u.active' => 1])
->join('modUserProfile', 'p', 'u.id = p.internalKey')
->select('u.username, p.fullname')
->sortBy('u.username')
->fetchAll()
}
{foreach $users as $user}
<p>{$user.username} ({$user.fullname})</p>
{/foreach}🔍 Найти запись по ID
{set $resource = query('modResource')->find(10)}
{if $resource}
<h2>{$resource->pagetitle}</h2>
{/if}📂 Получить массив категорий
{set $categories = query('modCategory')->fetchAll()}
<ul>
{foreach $categories as $cat}
<li>{$cat.category}</li>
{/foreach}
</ul>🔧 Использовать value() или pluck()
{query('modResource')->where(['id' => 5])->value('pagetitle')}{set $titles = query('modResource')
->where(['parent' => 0])
->pluck('pagetitle')
}
<pre>{$titles|print}</pre>📁 Структура файлов
App/
└── Helpers/
└── fenom/
├── modifiers.php ← Модификаторы
├── inline_tags.php ← Псевдо-теги
├── block_tags.php ← Блочные функции
├── data.php ← Глобальные данные
└── php_functions.php ← Разрешённые PHP-функции🧼 Очистка кэша
Когда вы очищаете кэш через админку MODX, автоматически вызывается:
View::clearCache();Это очищает все скомпилированные шаблоны Fenom.