PageBlocks 2.3.0

pbResource
pbResource — это расширение стандартной таблицы ресурсов в MODX, которое позволяет добавлять кастомные поля для ресурсов и управлять ими в отдельной, настраиваемой таблице.
Преимущества:
- Максимальная гибкость: Возможность добавлять любые поля для ресурсов. Больше никаких TV полей.
- Удобство управления: Ресурсы отображаются в специально созданной таблице, что упрощает их редактирование и исключает избыточность в стандартном дереве.
- Фильтрация и кастомизация: Полный контроль над отображением и управлением данными с помощью кастомных таблиц и фильтров.

Relationship Field
Данное поле позволяет устанавливать связи между таблицами PageBlocks или ресурсами (pbResources). Оно обеспечивает гибкость и удобство в управлении связанными данными.
Настройка:

Доступные отношения:
- One to One — Один к одному
- One to Many — Один ко многим
- Many to One — Многие к одному
- Many to Many — Многие ко многим
[[!pbRelationship?
&relation_type=`one_to_one` // Тип отношения
&primary_table=`pbTable` // Основная таблица: pbTable или pbResources
&primary_id=`1` // ID основной записи
&tpl=`relation` // Чанк для вывода результатов. Доступны все поля связанного объекта
]]
Dependent Field
Dependent Field — это настройка поля, которая позволяет скрывать или отображать другие поля в зависимости от значения одного из полей формы. Это обеспечивает динамическое изменение интерфейса и упрощает ввод данных пользователями.
Пример использования:
Допустим, у вас есть таблица товаров, где есть два типа товаров: Холодильники и Телефоны. В зависимости от выбранной категории, нужно отображать разные характеристики:
- Для холодильников: объём, количество камер, класс энергопотребления.
- Для телефонов: диагональ экрана, объём оперативной памяти, поддержка 5G.

Imask Field
Imask Field — это текстовое поле, в котором можно использовать различные опции маскировки, обеспечивая удобный ввод данных в нужном формате. Маскировка настраивается с помощью библиотеки iMask.js

Настройки из примера:
1. Телефонный номер
{
mask: '+{38} (000) 000-00-00'
}
2. Дата
{
mask: Date,
pattern: 'd{.}`m{.}`Y',
blocks: {
d: { mask: IMask.MaskedRange, from: 1, to: 31 },
m: { mask: IMask.MaskedRange, from: 1, to: 12 },
Y: { mask: IMask.MaskedRange, from: 1900, to: 2099 }
}
}
3. Сумма
{
mask: Number,
thousandsSeparator: ' ',
radix: ',',
scale: 2
}
4. Номер кредитной карты
{
mask: '0000 0000 0000 0000'
}
Больше пример на сайте https://imask.js.org/
Map Field
Map Field — это поле, которое позволяет интегрировать карты на вашу страницу. В данный момент доступны два типа карт: Leaflet и Yandex. В будущем планируется добавить поддержку Google Maps.
Выбор типа карты осуществляется через системную настройку pageblocks_map_type, а все остальные настройки можно произвести непосредственно в настройке этого поля.

Для отображение карты на фронте используется сниппет pbMap:
{'!pbMap' | snippet: [
'markers' => $map_coords, // координаты карты
'options' => $map_options // опции карты
]}
Gallery Field
В этой версии улучшен интерфейс галереи, а также добавлена функция автоматической генерации превьюшек.

{"webp":{"w":120,"h":90,"q":90,"zc":"1","bg":"000000","f":"webp"}}
Эта настройка будет генерировать превьюшки размером 120x90 пикселей и сохранять их в папке webp в формате webp.Другие поля
Помимо прочего, в компонент были добавлены еще новые типы полей, а также улучшено старое поле:
- TableMultiCombo Field
- MultiCombo Field
- Currency Field
- Heading Field
- Tag Field
- KeyValue Field (улучшенно)
Routing
В компоненте PageBlocks появилась поддержка роутинга, благодаря чему теперь можно создавать маршруты, обрабатывать запросы и возвращать данные в различных форматах. Это делает разработку API-интерфейсов для MODX проще и интуитивно понятнее.
При установке компонента в папке core создается директория App, которая предназначена для настройки и управления различными аспектами работы компонента:
- Маршруты: App/routes
- Контроллеры: App/Http/Controllers
- Мидлвары: App/Http/Middleware
- Шаблоны для Fenom: App/elements
- Модификаторы для Fenom: App/Helpers/modifiers.php
Примеры маршрутов:
Использование функции, возвращающей текст:
Route::get('/hello', function () {
return 'Hello World';
});
Использование контроллера:
Route::get('/resource', [ResourceController::class, 'index']);
Route::get('/resource/{id}', 'ResourceController@show');
Пример контроллера
namespace PageBlocks\App\Http\Controllers;
class ResourceController extends Controller
{
public $classKey = \modResource::class;
public function index(string $key, array $request)
{
$resources = $this->modx->getIterator($this->classKey, [
'context_key' => $key,
'published' => 1,
]);
return $resources;
}
public function show($key, $id, array $request)
{
return $this->modx->getObject($this->classKey, $id);
}
}
Объекты будут автоматически преобразованы в JSON.Response
Контроллеры могут возвращать не только текст или массив, но и объекты класса Response. Это позволяет гибко управлять выводом данных.
Пример:
public function view($id, array $request)
{
$resource = $this->modx->getObject($this->classKey, $id);
$data = ['resource' => $resource];
return response()->view('templates/index', $data);
}
Методы класса Response:
1. Выводит текстовый ответ.
text($text, int $status = 200, array $headers = [])
- $text — текст ответа.
- $status — HTTP-статус (по умолчанию 200).
- $headers — дополнительные заголовки.
return response()->text('Hello World', 200, ['Content-Type' => 'text/plain']);
// или тоже самое:
return response()->text('Hello World');
2. Возвращает данные в формате JSON.
json(array $data, int $status = 200, array $headers = [])
- $data — массив данных для преобразования.
- $status — HTTP-статус (по умолчанию 200).
- $headers — дополнительные заголовки.
return response()->json(['message' => 'Success']);
3. Рендерит шаблон и возвращает HTML.
view(string $template, array $data = [])
- $template — путь к шаблону, который должен находиться в папке App/elements.
- $data — массив данных, передаваемых в шаблон.
Пример:
return response()->view('templates/resource', ['title' => 'My Resource']);
4. Выполняет перенаправление на указанный URL.
redirect(string $url, int $status = 302, array $headers = [])
- $url — адрес для редиректа.
- $status — HTTP-статус (по умолчанию 302).
- $headers — дополнительные заголовки.
return response()->redirect('/new-url', 301);
5. Возвращает файл для скачивания.
download(string $file, string $name = null, array $headers = [])
- $file — путь к файлу, от корня сайта.
- $name — имя файла для загрузки (необязательно).
- $headers — дополнительные заголовки.
return response()->download('path/to/file.zip', 'myfile.zip');
Без контроллера:
Для выполнения редиректов не обязательно вызывать контроллер, это можно сделать прямо в маршруте:
Route::redirect('/here', '/there');
Вывод шаблона
Route::get('/', function () {
return view('templates/welcome');
});
// или еще короче
Route::view('/', 'templates/welcome');
Редирект на именованный роут
Route::get('/', function () {
return view('templates/welcome');
})->name('welcome');
// теперь мы можем сделать редирект по названию маршрута
Route::get('/wel_come', function () {
return redirect()->route('welcome');
});
Примеры роутов:
С префиксом, группой и мидлваром.
use Boshnik\PageBlocks\Routing\Route;
use PageBlocks\App\Http\Controllers\ConfigController;
use PageBlocks\App\Http\Controllers\ContextController;
use PageBlocks\App\Http\Controllers\ResourceController;
Route::prefix('api')->middleware(['Authenticate'])->group(function () {
Route::get('/context/', [ContextController::class, 'index']);
Route::get('/config/', [ConfigController::class, 'index']);
Route::prefix('{key}')->group(function () {
Route::get('/menu', [ResourceController::class, 'menu']);
Route::get('/resource', [ResourceController::class, 'index']);
Route::get('/resource/{id}', [ResourceController::class, 'show']);
});
});
Данный роутинг API создает следующую структуру ссылок:
- Контроллер ContextController:
- /api/context/
- Контроллер ConfigController:
- /api/config/
- Контроллер ResourceController:
- /api/{key}/menu
- /api/{key}/resource
- /api/{key}/resource/{id}
Получаем все роуты
Route::get('/route/list', function () {
return Route::getRoutes();
});
Интеграция, вдохновленная Laravel
Роутинг в PageBlocks максимально приближен к синтаксису и подходам Laravel. Это позволяет легко адаптировать примеры из документации Laravel для использования в PageBlocks.
На данный момент реализованы основные возможности, но функционал будет расширяться в будущем.
Эта тема заслуживает отдельной статьи, в которой можно будет более детально рассмотреть все возможности компонента. Пока что я изложил основные идеи и ключевые функции для общего понимания.
Ключевые преимущества PageBlocks:
- Отказ от избыточности TV: Забудьте о множестве TV-полей, засоряющих интерфейс и усложняющих структуру. PageBlocks позволяет создавать собственные поля с любыми необходимыми настройками.
- Гибкость и настраиваемость: Вы сами определяете структуру данных, создавая таблицы с необходимыми полями и устанавливая связи между ними.
- Улучшенный интерфейс: Управление данными становится удобнее благодаря табличному представлению, фильтрации и динамическому отображению полей.
- Расширенные возможности ввода: Imask Field, Dependent Field и другие типы полей делают ввод данных более удобным и интуитивным для контент-менеджеров.
- Интеграция с внешними сервисами: Map Field позволяет легко интегрировать карты, а галерея с генерацией превьюшек упрощает управление изображениями.
- Разработка API: Благодаря системе роутинга, создание RESTful API становится простым и интуитивно понятным процессом. Синтаксис, вдохновленный Laravel, позволяет с легкостью применять готовые решения и ускорить разработку.
- Постоянное развитие: Компонент активно развивается и пополняется новыми функциями и возможностями.
PageBlocks — это не просто дополнение, это полноценная платформа для управления данными в MODX, которая выводит ваши возможности на новый уровень. Благодаря ей вы сможете создавать более сложные и гибкие проекты, с легкостью настраивая структуру контента и интерфейс управления.
Поддержка:
- MODX: 2 / 3
- PHP: ^7.4
- Поля: 37 разнообразных полей
Поблагодарить автора
Отправить деньги
Комментарии: 8
Это безумно круто. Я в восторге
Отличное обновление!
Выглядит очень-очень круто!
Уже второй месяц работаю с PageBlocks. До этого городил что-то похожее на MIGX.
Автор всегда на связи и при появлении каких-либо сложностей, связанных с компонентом, реагирует быстро. PageBlocks — это мощь!
Автор всегда на связи и при появлении каких-либо сложностей, связанных с компонентом, реагирует быстро. PageBlocks — это мощь!
Уже ни один проект собран на PageBlocks, доп. шикарный!
Радует, что вернулась поддержка PHP 7.4
Радует, что вернулась поддержка PHP 7.4
Version 2.3.1
Added
Added
- support MySQL 5.7
- description for ready blocks
- support for custom parameters for snippets
Жаба душит. Но посмотрел состав и подумал что оно стоит того.
Как реализовано управление мультиязычности немного не понял.
Я использую Localizator и немного дорабатываю под себя. Не будет конфликтовать? Как реализовано управление переводами элементов и доп. полей (все таки они могут использоваться, и надо бы их Вашим компонентом тоже поддерживать?), а также как реализовано управление лексиконами и словарями?
Как реализовано управление мультиязычности немного не понял.
Я использую Localizator и немного дорабатываю под себя. Не будет конфликтовать? Как реализовано управление переводами элементов и доп. полей (все таки они могут использоваться, и надо бы их Вашим компонентом тоже поддерживать?), а также как реализовано управление лексиконами и словарями?
Про мультиязычность напишу отдельную статью. Вкратце: есть комбо-поле, которое переключает контекст для блоков, которые можно переводить вручную или с помощью сторонних сервисов (DeepL, ChatGPT). Также есть отдельная вкладка для перевода текущего ресурса — по принципу Локализатора. Конфликтов не должно быть. Дополнительные поля я не использую с этим компонентом — ни разу не пригодились. Вся информация находится в блоках, поэтому отдельной вкладки для лексиконов, как в Локализаторе, тоже нет.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.