PageBlocks 1.2.0. Создавай сайт быстро и легко.

Всем, привет!

Документация

В первую очередь, хочу поблагодарить людей, которые внесли свой вклад в развитие компонента. Это @Олег Щавелев ,@Misha Bulic и @Андрей Шевяков. За новый логотип спасибо @DobroLab



Новые возможности:


  1. Вложенность таблиц
  2. Управление чанками
  3. Копирование блоков из ресурса
  4. Копирование блока по id
  5. Коллекции
  6. Новые поля
  7. Сниппет PageBlocks
  8. События


1. Вложенность таблиц


Добавлена поддержка любой вложенности таблиц.



2. Управление чанками


Вместе с созданием блока в конструкторе создается и чанк с названием, которое указано в соответствующем поле конструктора. Там же добавлена вкладка чанк, где указываетcя код чанка.



Соответственно при удалении блока, соответствующий чанк будет также удален.
Через системные настройки можно отключить создание или удаление чанка:
  • pageblocks_create_chunk — отключить, чтобы не создавался чанк.
  • pageblocks_remove_chunk — отключить, чтобы не удалялся чанк.
Но, обновить чанк можно не только в конструкторе, а в любом блоке на странице.


3. Копирование блоков из ресурса




4. Копирование блоков по id


Тут, все очень просто, указывает id блока, который нужно скопировать и все.

5. Коллекции


Коллекции были и раньше, но кое-что изменилось.
1. Появилась возможность управлять позицией вкладки. По умолчанию вкладка с коллекцией идет за вкладкой PageBlocks.
2. Если коллекция используется в связке с ресурсом, то все поля синхронизируются. То есть, если изменить что-то в ресурсе, то и в блоке соответствующие поля будут также изменены и наоборот.

Расширить таблицу ресурсов теперь можно на отдельной вкладке.


Пример:
Используем коллекцию как статьи блога. Нужно поле img, которое выводит главную картинку на странице статьи. Конечно, можно добавить tv, но весь смысл PageBlocks — это отказаться от тивишек, и управлять контентом в одной таблице. Так вот добавляем новое поле в ресурсы — img и при создании блока (статьи) заполняем данное поле, вспоминаем что все поля синхронизируются, поэтому данное поле будет заполнено и в ресурсе, а значит на самой странице можно вывести его как стандартное поле.
{$_modx->resource.img} или [[+img]]

6. Новые поля


Добавлены новые поля, а именно: видео,видеогалерея, список Да/Нет, ACE и логический флажок.

Видео

Может распарсить ссылку с YouTube и Vimeo. Соответственно добавлены системные настройки pageblocks_youtube_api_key (ключ Youtube API) и pageblocks_vimeo_api_key (ключ Vimeo API)

Как получить ключи можно почитать здесь:
  • Youtube (добавил свой ключ, поэтому прошу не увлекаться. Если вы парсите много видео, то укажите свой ключ, это легко и бесплатно.)
  • Vimeo


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

На фронте переменная — это массив:
{$video | print}

[0] => Array
    (
        [video] => http://www.youtube.com/watch?v=SiWeDyc867o
        [title] => Заставь свой мозг работать | Эми Брэнн
        [description] => 'Описание'
        [provider] => YouTube
        [thumbnail] => https://i.ytimg.com/vi/SiWeDyc867o/sddefault.jpg
        [thumbnail_width] => 640
        [thumbnail_height] => 480
        [embed_video] => http://www.youtube.com/embed/SiWeDyc867o
        [video_id] => SiWeDyc867o
    )
Пример:
<iframe src="{$vimeo[0]['embed_video']}" title="{$vimeo[0]['title']}" allowfullscreen></iframe>
Демо

Видеогалерея



Демо

Список Да/Нет



ACE

Если вы установили компонент ACE, то будет доступно соответствующее поле.



Логический флажок

Настройка поля:


Поле в блоке:


Xtype поле

Это поле не новое, и раньше оно называлось комбо-поле.
С помощью этого поля можно указать почти любой стандартный xtype-поле, ну и конечно можно вывести свой xtype.
Примеры:
  • modx-combo-context (список контекстов)
  • modx-combo-template (список шаблонов)
  • modx-description (описание)
  • modx-field-parent-change (выбор ресурса при клике на него в дереве ресурсов)
  • modx-combo-user (список пользователей)
  • modx-combo-country (список стран)
  • statictextfield (статическое поле, которое не редактируется)
  • label (показываем только заголовок поля)

Галерея

При создании поля галерея можно указать в какую директорию будут загружаться картинки, если поле пустое, то путь будет браться с системной настройки pageblocks_source_path. Также добавлены поля title и description при редактировании файла.

7. Сниппет PageBlocks


Используется для вывода блоков.
Параметры сниппета:
Имя Описание По умолчанию
id Id блока -
object_id Id привязанного ресурса 0
rid Id ресурса Текущий ресурс
cid Id конструктора блока -
collection Id коллекции 0
context Контекст Текущий контекст
cultureKey Язык из системной настройки cultureKey
up Параметр, который позволяет искать условие у родителей 0
fastMode Быстрый режим обработки чанков. Все необработанные теги (условия, сниппеты и т.п.) будут вырезаны. 0
where Массив дополнительных параметров выборки, закодированный в JSON. -
showLog Показывать дополнительную информацию о работе сниппета. 0
return Формат вывода данных. Возможные значения: chunk, data и json chunk


Примеры:

1. Выводим все активные блоки текущего ресурса
{'!PageBlocks' | snippet}

2. Выводим все блоки из ресурса c id 7
{'!PageBlocks' | snippet: [
    'rid' => 7
]}

3. Выводим блок с id 7
{'!PageBlocks' | snippet: [
    'id' => 7
]}
Если указан параметр id, то все остальные параметры игнорируются, кроме where.

4. Выводим блоки коллекции текущего ресурса
{'!PageBlocks' | snippet: [
    'collection' => 1
]}

5. Выводим блоки с условием
{'!PageBlocks' | snippet: [
    'where' => [
        'resource_id' => 1,
        'context_key' => 'web',
        'cultureKey' => 'ru',
        'constructor_id' => 1,
        'collection_id' => 0,
        'object_id' => 0 // id ресурса, если блок к нему привязан.
        'active' => 1
    ]
]}

6. Помните, я приводил пример, что коллекцию можно использовать как статьи для блога. Так вот, если мы не расширили таблицу ресурсов (ну не хочу трогать таблицу и все), но нужно получить все данные блока на странице статьи (ресурса), то это делается легко:
{set $block = '!PageBlocks' | snippet: [
     'object_id' => $_modx->resource.id,
     'return' => 'json'
] | fromJSON}
{set $values =  $block[0]['values']}
$values — массив всех полей
И теперь на странице выводим превью
<img src="{$values['img']}">


8. События


  • pbBeforeSaveImage (вызывается до сохранения файла)
    • $id (0)
    • $data (массив данных)
    • $object (объект blockFile)
  • pbAfterSaveImage (вызывается после сохранения файла)
    • $id (id объекта)
    • $object (объект blockFile)
  • pbBeforeRemoveImage (вызывается до удалении файла)
    • $id (id объекта)
    • $object (объект blockFile)
  • pbAfterRemoveImage (вызывается после удалении файла)
    • $id (id объекта)
    • $object (объект blockFile)
  • pbBeforeSaveBlock (вызывается до сохранения блока)
    • $mode (new или upd)
    • $id (id объекта, если $mode == 'new', то $id = 0)
    • $data (массив данных)
    • $object (объект pageBlock)
  • pbAfterSaveBlock (вызывается после сохранения блока)
    • $mode (new или upd)
    • $id (id объекта)
    • $object (объект pageBlock)
  • pbBeforeRemoveBlock (вызывается до удалении блока)
    • $id (id объекта)
    • $object (объект blockFile)
  • pbAfterRemoveBlock (вызывается после удалении блока)
    • $id (id объекта)
    • $object (объект blockFile)

pbBeforeSaveImage

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

Пример:
<?php
/** @var PageBlocks $PageBlocks */
$PageBlocks = $modx->getService('pageblocks', 'PageBlocks', MODX_CORE_PATH . 'components/pageblocks/model/');

switch ($modx->event->name) {
    case 'pbBeforeSaveImage':
        
        // Переименовываем файл
        $PageBlocks->files->renameFile($object, 'pb_' . $object->name);
        
        // Изменяем формат загружаемых картинок.
        $PageBlocks->files->changeFormat($object, 'webp');
        
        // Создаем превью
        $params = array(
        	'w' => 300,         // Ширина
        	'h' => 200,         // Высота
        	'bg' => 'ffffff',   // Фон
        	'q' => 80,	    // Качество в %
        	'zc' => 'C',	    // Обрезка, TL - это Top Left, есть еще C - center, BR - Bootom Right  и т.д.
        	'f' => 'webp',	    // Формат изображения
        );
        // Каталог, куда будем загружать файл
        $new_path = $object->path . $object->resource_id . '/' . $object->block_id . '/webp'; // gallery/1/410/webp
        // Генерируем новый файл
        $PageBlocks->files->generateThumbnail($object, $params, $new_path);
        
        // Перемещаем файл в другую директорию
        $new_path = $object->path . $object->resource_id . '/' . $object->block_id;
        $PageBlocks->files->moveFile($object, $new_path);

        break;
}

Важно отметить, что при смене формата создается копия файла с новым форматом. По умолчанию файл будет создаваться в текущей директории, но ее можно изменить передав путь в 3-м параметре метода changeFormat.
Пример:
// Изменяем формат загружаемых картинок и загружаем ее в новую директорию
$new_path = $object->path . $object->resource_id . '/' . $object->block_id;
$PageBlocks->files->changeFormat($object, 'webp', $new_path);

pbBeforeRemoveImage

Здесь до удаления файла, можем удалить все превью и другие файлы.

Пример:
<?php
/** @var PageBlocks $PageBlocks */
$PageBlocks = $modx->getService('pageblocks', 'PageBlocks', MODX_CORE_PATH . 'components/pageblocks/model/');

switch ($modx->event->name) {
    case 'pbBeforeRemoveImage':
          
        // Удаляем превью
        $objectPath = $object->path . $object->resource_id . '/' . $object->block_id . '/webp/' . $file->filename;
        $PageBlocks->files->removeFile($object->source, $objectPath);
        
        break;
}

$objectPath — путь к картинке. Ранее мы загружали в данную папку превью.

pbBeforeSaveBlock

Вызывается при сохранении блока до формирования значений. Изменения связанных объектов попадут в значение блока.

Пример:
<?php
/** @var PageBlocks $PageBlocks */
$PageBlocks = $modx->getService('pageblocks', 'PageBlocks', MODX_CORE_PATH . 'components/pageblocks/model/');

switch ($modx->event->name) {
    case 'pbBeforeSaveBlock':
  
        // Получаем все картинки из галереи
        $files = $object->getMany('Files');
        
        // Получаем все видео из видеогалереи
        $videos = $object->getMany('Videos');
        
        // Получаем все таблицы
        $tables = $object->getMany('Tables');
        
        // Получаем конструктор данного блока, но конструктор изменять нельзя, чисто для получения данных.
        $constructor = $object->getOne('Constructor');
        
        break;
}

pbAfterSaveBlock

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

Пример:
<?php
/** @var PageBlocks $PageBlocks */
$PageBlocks = $modx->getService('pageblocks', 'PageBlocks', MODX_CORE_PATH . 'components/pageblocks/model/');

switch ($modx->event->name) {
    case 'pbAfterSaveBlock':
        
        // Получаем значения блока
        $values = json_decode($object->values,1);
        
        // Делаем какие-то изменения с $values
        ...
        
        // Сохраняем новое значение
        $object->set('values', json_encode($values));
        $object->save();
        
        break;
}


Планы:


  • Добавить два поля: карта и теги.
  • Улучшить политику доступа
  • Перенос настроек между сайтами. Создали блоки на одном сайте и потом можно использовать эти блоки на других сайтах, чтобы не терять время на создание одинаковых блоков.
  • Создавать отдельные страницы в админке с помощью коллекций у которых будет свое собственное меню.
  • Рендер на сервере. Тут, конечно же, нужно много тестировать, но если все получиться, то можно будет сразу выводить готовый контент, но опять же, это годиться только для статических страниц. А для динамических, может запускать обновление по крону, не знаю. Этот пункт пока на рассмотрении.

Выводы:


Это обновление сделало компонент еще лучше и еще быстрее (был произведен рефакторинг кода), что позволит создавать сайты еще быстрее и легче. Еще раз большое спасибо всем, кто поддерживал меня и отдельное спасибо @Олег Щавелев за его терпение и вклад. На протяжении целого месяца, а это именно столько времени заняла новая версия компонента, мы с ним общались, выявляли баги, обсуждали новые идеи, которые, кстати, еще не все реализованы. И больше всех он ждал этого обновления.
И теперь немного дёгтя — стоимость компонента с 15 октября будет увеличена на 500 руб. Да, вы можете подумать, что это много и за такую цену лучше использовать другой бесплатный инструмент, но на самом деле было потрачено много времени на разработку, и это еще далеко не конец, и те кто уже пользуется данным компонентом знают какой он удобный и позволяет не терять время при разработке сайта.

Всем добра и будьте здоровы!
Aleksandr Huz
07 октября 2021, 08:34
modx.pro
1
1 964
+18
Поблагодарить автора Отправить деньги

Комментарии: 21

Sergey (Sentinel)
07 октября 2021, 08:45
+1
Ну просто агонь! Молодец Саш!
    Олег Щавелев
    07 октября 2021, 09:25
    +1
    Поздравляю с выходом версии 1.2.0 — ждем 1.3.0.
      Сергей Шлоков
      07 октября 2021, 09:45
      +1
      Версия 1.2.0 не совместима с предыдущими версиями. При обновлении все может поломаться.
      Для информации. При использовании семантического версионирования необходимо следовать следующим правилам:
      Учитывая номер версии МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ, следует увеличивать:

      МАЖОРНУЮ версию, когда сделаны обратно несовместимые изменения API.
      МИНОРНУЮ версию, когда вы добавляете новую функциональность, не нарушая обратной совместимости.
      ПАТЧ-версию, когда вы делаете обратно совместимые исправления.
      Таким образом, разработчик в менеджере пакетов сразу видит можно обновляться или нет.
        Aleksandr Huz
        07 октября 2021, 10:09
        +1
        Да, было бы логичнее сделать 2.0.0. Но, старался делать совместимую версию, ради справедливости ломается только одно поле и не все его используют. И еще ошибка в журнале, что нет одной таблицы, а все остальное после обновления работает как и прежде, поэтому решил оставить 1.2.0.
        Но, ты прав, нужно было 2.0.0.
        Артур Шевченко
        07 октября 2021, 10:37
        +1
        Рендер на сервере.
        Не знаю будет ли полезна эта информация, но я делал аналог для бедных на Migx. Так вот, чтобы кучу логики в шаблон не пихать, я рендерил страницу при сохранении ресурса и сохранял в поле контент или в отдельную TV, если нужен был визуальный редактор в контенте. Чтобы сниппеты, например AjaxForm, работали я заменял { на ## при написании шаблона, а в плагине менял обратно, таким образом вся статика парсилась на сервере, а вся динамика на форнте. Минус в том, что приходится использовать разный синтаксис в шаблоне.
          Aleksandr Huz
          07 октября 2021, 10:40
          0
          И какой вывод сделал? Это того стоило?
            Артур Шевченко
            07 октября 2021, 11:17
            0
            конечно, почти двухкратный прирост скорости отдачи станицы)))
          Артур Шевченко
          07 октября 2021, 11:25
          0
          В общем, меня посещала идея сделать, аналогичный компонент, но с возможностью кастомизации блоков. Т.е. сам блок представляет собой постоянный набор элементов, например Заголовок, Подзаголовок, Кнопка и Картинка и каждый элемент можно немного кастомизировать, менять цвет, размер, тип шрифта. Как основу я использовал bootstrap, потому что там можно изменить глобально настройки всего фреймворка и сайт преобразится, а можно точечно классами менять внешний вид отдельных элементов. В итоге должен был получится недоконструктор сайтов. Но сейчас я думаю, что это никому нах не нужно)))

          P.S. Настройки boostrap я выносил в clientConfig и при сохранении пересобирал sass. Хотел даже статью запилить, но подумал, что это никому не нужно)))
            Aleksandr Huz
            07 октября 2021, 11:35
            0
            Если тебе это нужно, то может кому-то еще понадобится))
              Артур Шевченко
              07 октября 2021, 11:44
              0
              Предполагалось что это будет сделано для людей без знаний html css, но потом мне подумалось, что слишком сложно, а если упрощать, то это уже конструктор, а их хватает. А вообще, может ещё запилю.
            Дмитрий
            07 октября 2021, 11:31
            +1
            Красота-то какая! Респектище! Может, когда-нибудь пощупаю
              Aleksandr Huz
              07 октября 2021, 11:39
              +1
              Может, когда-нибудь пощупаю
              Зачем отлаживать, можно бесплатно установить компонент на модхосте и пощупать.
              А вообще, постараюсь, на след. недели запустить демо-сайт с доступом в админку.
                Диман
                09 октября 2021, 10:46
                0
                А вообще, постараюсь, на след. недели запустить демо-сайт с доступом в админку.
                На живом примере, гораздо проще понять логику создания блоков. Ждем…
              Андрей Шевяков
              07 октября 2021, 18:56
              +1
              Спасибо за дополнение и полезные обновления!
              Еще нужна документация. А то сейчас все методом тыка познается)))
              Но разобраться не сложно. Спасибо еще раз!
                Александр Мельник
                07 октября 2021, 19:45
                0
                Уверен хорошая штука, но пока не могу понять, что это)
                Заметка начинается со слов — новые возможности. И сразу перечисление каких то таблиц, вложенных.
                Это что за таблицы? Это про SQL? Это про тег
                <table>
                ? Компонент позволяет отображать на странице
                <table>
                вложенный в
                <table>
                ?
                Как бы автор назвал свое творение? Это способ создавать сайт без дизайна? Из заготовленных автором блоков?
                  Aleksandr Huz
                  07 октября 2021, 20:16
                  0
                  Если коротко, то PageBlocks похож на migx, но имеет намного больше возможностей.
                  Рекомендую к прочтению:
                  modx.pro/components/21889
                  modx.pro/components/22026
                  modx.pro/development/22234

                  Это что за таблицы? Это про SQL? Это про тег
                  Например, вот таблица:


                  Как бы автор назвал свое творение? Это способ создавать сайт без дизайна? Из заготовленных автором блоков?
                  PageBlocks дает возможность удобно управлять контентом сайта. Есть верстка сайта и ее нужно интегрировать, вы разбиваете всю верстку на блоки и в компоненте создаете соответствующие блоки со всеми полями и затем заполняете эти поля.
                Evgeny
                19 июля 2022, 14:05
                0
                Может кто-то подсказать, как правильно написать плагин, который срабатывает на сохранение документа и записывает количество символов всех блоков в TV-переменную «symbols»? Это код возвращает «0».

                <?php
                
                $contentblocks = $modx->getService('PageBlocks', 'PageBlocks', MODX_CORE_PATH . 'components/pageblocks/model/');
                $contentblocks = strlen(strip_tags($contentblocks));
                
                switch ($modx->event->name) {
                    case 'OnDocFormSave':
                        $resource->setTVvalue('symbols', $contentblocks);
                        break;
                }
                  Семён Кудрявцев
                  19 декабря 2022, 12:20
                  0
                  Прикольный компонент получился, хорошая альтернатива ContentBlocks от modmore.com
                  Единственное, что сразу бросилось в глаза, это при создании коллекции и выводе её в шаблоне через сниппет получается следующее неудобство:
                  Если в коллекции один элемент — возвращается объект
                  Если в коллекции более одного элемента возвращается массив
                  Если уж это коллекция то по идее должен всегда возвращаться массив, иначе нужно делать дополнительные проверки в шаблонах на то, что там вернул сниппет, массив или объект.
                    Игорь
                    20 октября 2023, 10:23
                    0
                    Здравствуйте.
                    Как можно сделать множественный список ресурсов?
                    Стандартный вариант (добавить в поле «Список (множественный выбор)» запрос mysql или сниппет) здесь не срабатывает…
                    @EVAL return $modx->runSnippet('pdoResources', array(
                    	'parents' => 3,
                    	'limit' => 0,
                    	'tpl' => '@INLINE {$pagetitle}=={$id}',
                    	'outputSeparator' => '||',
                    	'sortby' => '{"menuindex":"ASC"}'
                      ));
                      MODXyou
                      25 октября 2023, 12:48
                      0
                      Добрый день!

                      В настройке дополнения есть поле для пути загрузки картинок.
                      pageblocks_source_path assets/images/
                      По умолчанию все картинки кидаются в корень папки, очень не удобно если много страниц.
                      Получается каша вообще
                      Подскажите как сделать чтобы, чтобы каждый ресурс сохранял картинки в свою папку с названием alias
                      Т.е. к примеру assets/images/test/
                        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                        21