Создание слайдера с использованием MIGX в MODX

Александр Мальцев
Александр Мальцев
26K
60
Содержание:
  1. Что такое MIGX
  2. Установка MIGX
  3. MIGX - Создание карусели Bootstrap
  4. Комментарии

Урок, в котором рассмотрим назначение дополнения MODX Revo MIGX.

Работу с MIGX разберём на примере, результатом которого станет возможность добавлять в удобной форме изображения к ресурсам. Вывод изображений связанных с ресурсом на страницу будем осуществлять посредством карусели (слайдера) Bootstrap 3.

Что такое MIGX

MIGX - это компонент для MODX Revolution, который добавляет к переменным шаблона (TV параметрам) новый тип ввода с аналогичным названием (migx) и удобными инструментами для работы с ним. MIGX позволяет сохранить в одну TV-переменную целую таблицу данных. Это означает то, что с помощью MIGX и одного дополнительного поля (TV) можно с каждым ресурсом связать сложный набор данных. Для хранения данных в MIGX TV-переменной используется формат JSON.

Название MIGX расшифровывается как MultiItemsGridtv (МногоЭлементнаяСеткаTV) для MODX.

Для извлечения сложных элементов данных из дополнительного TV поля с типом MIGX можно использовать сниппет getImageList. Данный сниппет поставляется вместе с пакетом MIGX.

Установка MIGX

Процесс установки MIGX начинается c открытия в админке MODX Revolution страницы "Управление пакета" (Приложение -> Установщик) и нажатия в ней кнопки "Загрузить дополнения". На открывшейся странице в поле "Поиск" вводим название пакета (MIGX) и нажимаем клавишу Enter. После этого из представленных результатов выбираем искомое дополнение и нажимаем на кнопку "Загрузить". Возвращаемся на предыдущую страницу и завершаем процесс инсталляции с помощью кнопки "Установить".

В процессе установке необходимо определиться с местом расположения компонента MIGX в главном меню админки. Выбор тут осуществляется из 2 вариантов. Первый вариант (Top Nav) подразумевает размещения ссылки на компонент в качестве основного пункта меню, а второй (Extras/Components) – в элементе "Приложения".

Настройка расположения компонента MIGX в меню менеджера MODX Revo

Результат установки дополнения MIGX:

Расширения MODX, установленные в системе

MIGX - Создание карусели Bootstrap

В качестве примера рассмотрим применение компонента MIGX для создания карусели Bootstrap. Перед тем как переходить к созданию элемента определимся с перечнем основных полей, которые необходимы для формирования каждого слайда карусели. Этот список будет состоять из следующих полей:

  • title - заголовок (название) слайда (изображения);
  • image – изображение;
  • description - описание изображения.

Создание MIGX элемента, состоящего из вышеперечисленных полей, осуществляется на вкладке "MIGX" страницы "Управление MIGX". Открытие страницы "Управление MIGX" выполняется с помощью пункта MIGX в главном меню менеджера или в раскрывающем списке "Приложения" в зависимости от настройки его расположения.

MODX - Управление MIGX

Создание нового MIGX элемента

Процесс разработки нового элемента MIGX осуществляется с помощью кнопки "Добавить элемент". После нажатия на эту кнопку открывается модальное окно "MIGX", состоящее из множества вкладок. Для большинства задач достаточно использовать только первых три: Settings (Основные параметры), Formtabs (вкладка для создания структуры) и Columns (вкладка для разработки таблицы, с помощью которой конечный пользователь будет управлять данными).

На вкладке "Settings" введём название элемента (например, photos) и надпись, которая будет заменять текст "Добавить элемент".

MODX - Ввод название MIGX-элемента

На вкладке "Formtabs" осуществляется создание полей. Другими словами она определяет структуру, которую конечные пользователи будут использовать для ввода своих данных. Чтобы добавить поля к MIGX необходимо нажать на кнопку "Добавить элемент" и в открывшемся диалоговом окне ввести название набора (Caption) и заполнить таблицу Fields.

MODX - Создание полей MIGX-элемента (вкладка Formtabs)

Ввод записей в таблицу MODX Revolution MIGX осуществляется с помощью кнопки, расположенной сразу же после заголовка "Fields".

В таблицу Fields внесём следующие 3 записи:

  • Fieldname (имя поля) – title, Caption – Заголовок, Description – Описание фотографии.
  • Fieldname (имя поля) – image, Caption – Изображение, Input TV Type – image.
  • Fieldname (имя поля) – description, Caption – Описание.
MODX MIGX - Создание поля title

Заключительный шаг – это ввод данных во вкладку "Columns". Данная вкладка определяет название столбцов колонок таблицы (внешний вид), с помощью которых пользователь осуществляет просмотр и ввод данных в соответствующую дополнительную TV-переменную MIGX ресурса (в данном случае TV-переменную, определённую MIGX-элементом photos).

Введём в таблицу Columns следующие сведения:

  • Header – Заголовок, Field (имя поля) – title, Column width (ширина колонки) – 100.
  • Header – Файл изображения, Field – image, Renderer – this.renderImage.
  • Header – Описание, Field – description, Column width (ширина колонки) – 200.

Добавление записей в таблицу осуществляется с помощью кнопки "Добавить элемент".

MODX MIGX - Добавление данных во вкладку конфигурации Columns

Создание TV-поля MIGX с конфигурацией photos

После создания MIGX-элемента (конфигурации) photos приступим к созданию дополнительного поля (TV) с типом ввода MIGX и конфигурацией photos.

Создание дополнительного поля в админке осуществляется на левой панели во вкладке "Элементы". Для этого напротив надписи "Дополнительные поля" нажмите на значок плюса и в открывшейся странице введите следующие данные:

  • На вкладке "Общая информация" в поле "Имя" значение photos (имя дополнительного поля);
  • На вкладке "Параметры ввода" в раскрывающемся списке "Тип ввода" выбрать пункт migx, а в поле "Конфигурации" ввести значение photos.
  • На вкладке "Доступно для шаблонов" выбрать те шаблоны, для которых (а точнее для ресурсов, у которых установлены данные шаблоны) это поле будет доступно.

Ввод данных в TV MIGX поле photos

Откроем любой ресурс, у которого доступно MIGX TV поле photos и введём в него, например, следующие данные:

MODX MIGX - Добавление данных в TV-поле photos ресурса

Вывод данных TV MIGX поля на страницу

Выводить данные на страницу будем с помощью сниппета getImageList, который поставляется вместе с дополнением MIGX.

Данные из TV MIGX поля photos визуально представим в виде карусели Bootstrap. Познакомиться с тем, какой необходимо получить на выходе HTML код можно используя статью Знакомство с каруселью Twitter Bootstrap.

Приступ к реализации. Для этого откроем шаблон, установленный для данного ресурса, и в необходимое место вставим следующий код:

<h1 class="h2 page-header text-center">[[*longtitle:empty=`[[*pagetitle]]`]]</h1>
<div id="carousel" class="carousel slide" data-ride="carousel" style="max-width:600px; margin-left: auto; margin-right: auto;">
  <ol class="carousel-indicators">
    [[getImageList? 
      &tvname=`photos`
      &tpl=`tplCarouselIndicator`
    ]]
  </ol>
  <div class="carousel-inner" role="listbox">
    [[getImageList?
      &tvname=`photos`
      &tpl=`tplCarouselItem`
    ]]
  </div>
  <a class="left carousel-control" href="#carousel" role="button" data-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="sr-only">Предыдущий</span>
  </a>
  <a class="right carousel-control" href="#carousel" role="button" data-slide="next">
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Следующий</span>
  </a>
</div>

Вышеприведённый код состоит из HTML разметки и 2 вызовов сниппета getImageList. Первый выводит индикаторы карусели, а второй – слайды, содержащие изображения. Данные сниппеты имеют 2 параметра. Параметр tvname предназначен для указания имени TV-переменной с MIGX данными, которые необходимо вывести на страницу. А параметр tpl определён для того чтобы задать шаблон (чанк), посредством которого будет формироваться каждая строка данных из MIGX TV-поля photo.

Содержимое чанка tplCarouselIndicator:

<li data-target="#carousel" data-slide-to="[[+idx:subtract]]" [[+idx:is=`1`:then=`class="active"`]]></li>

Содержимое чанка tplCarouselItem:

<div class="item [[+idx:is=`1`:then=`active`]]">
  <img src="[[+image]]" alt="[[+title]]">
  <div class="carousel-caption">
    <h3>[[+title]]</h3>
    <p>[[+description]]</p>
  </div>
</div>

Результат отображения карусели на странице:

MODX - Использование MIGX для создания карусели из данных хранящихся в одной TV-переменной

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

  1. Тимур
    Тимур
    2021-04-22 15:30:29
    Александр, спасибо, сделал по вашей инструкции, все работает.
    Сейчас решил с помощью этого же MIGX-поля вывести галерею из ресурсов на странице.
    Делаю так:
    [[pdoResources?
                    &parents=`121`
                    &sortby=`menuindex`
                    &limit=`99`
                    &sortdir=`ASC`
                    &tpl=`photo`
                    &includeTVs=`photos`
                ]]
    Чанк photo:
    [[!getImageList?
      &sortby=`{"MIGX_id":"ASC"}`
      &tvname=`photos`
      &tpl=`photo-chunk`
      &limit=`20`        
      &docid=`[[*id]]`
    ]]
    Чанк photo-chunk:
    <div class="gal-item">
        <a href="[[+image]]"><img class="img-responsive" src="[[+image]]" title="[[+pagetitle]]" alt="[[+pagetitle]]"/></a>
    </div>
    Ничего не выводится, лог:
    0.0000560: pdoTools loaded
    0.0000181: xPDO query object created
    0.0008361: Included list of tvs: photos
    0.0001371: leftJoined modTemplateVarResource as TVphotos
    0.0001221: Added selection of modResource: `id`, `type`, `contentType`, `pagetitle`, `longtitle`, `description`, `alias`, `alias_visible`, `link_attributes`, `published`, `pub_date`, `unpub_date`, `parent`, `isfolder`, `introtext`, `richtext`, `template`, `menuindex`, `searchable`, `cacheable`, `createdby`, `createdon`, `editedby`, `editedon`, `deleted`, `deletedon`, `deletedby`, `publishedon`, `publishedby`, `menutitle`, `donthit`, `privateweb`, `privatemgr`, `content_dispo`, `hidemenu`, `class_key`, `context_key`, `content_type`, `uri`, `uri_override`, `hide_children_in_tree`, `show_in_tree`, `properties`
    0.0000069: Added selection of modTemplateVarResource: IFNULL(`value`, '') AS `tv.photos`
    0.0006180: Processed additional conditions
    0.0007470: Added where condition: modResource.parent:IN(121,122,123), modResource.published=1, modResource.deleted=0
    0.0000520: Replaced TV conditions
    0.0000980: Sorted by modResource.menuindex, ASC
    0.0000021: Limited to 99, offset 0
    0.0002410: SQL prepared "SELECT `modResource`.`id`, `modResource`.`type`, `modResource`.`contentType`, `modResource`.`pagetitle`, `modResource`.`longtitle`, `modResource`.`description`, `modResource`.`alias`, `modResource`.`alias_visible`, `modResource`.`link_attributes`, `modResource`.`published`, `modResource`.`pub_date`, `modResource`.`unpub_date`, `modResource`.`parent`, `modResource`.`isfolder`, `modResource`.`introtext`, `modResource`.`richtext`, `modResource`.`template`, `modResource`.`menuindex`, `modResource`.`searchable`, `modResource`.`cacheable`, `modResource`.`createdby`, `modResource`.`createdon`, `modResource`.`editedby`, `modResource`.`editedon`, `modResource`.`deleted`, `modResource`.`deletedon`, `modResource`.`deletedby`, `modResource`.`publishedon`, `modResource`.`publishedby`, `modResource`.`menutitle`, `modResource`.`donthit`, `modResource`.`privateweb`, `modResource`.`privatemgr`, `modResource`.`content_dispo`, `modResource`.`hidemenu`, `modResource`.`class_key`, `modResource`.`context_key`, `modResource`.`content_type`, `modResource`.`uri`, `modResource`.`uri_override`, `modResource`.`hide_children_in_tree`, `modResource`.`show_in_tree`, `modResource`.`properties`, IFNULL(`TVphotos`.`value`, '') AS `tv.photos` FROM `modx_site_content` AS `modResource` LEFT JOIN `modx_site_tmplvar_contentvalues` `TVphotos` ON `TVphotos`.`contentid` = `modResource`.`id` AND `TVphotos`.`tmplvarid` = 14 WHERE  ( `modResource`.`parent` IN (121,122,123) AND `modResource`.`published` = 1 AND `modResource`.`deleted` = 0 )  ORDER BY modResource.menuindex ASC LIMIT 99 "
    0.0009501: SQL executed
    0.0000210: Rows fetched
    0.0007961: Prepared and processed TVs
    0.0007398: Loaded "modChunk" with name "photo"
    0.0012848: Returning processed chunks
    0.0054250: Total time
    4 194 304: Memory usage
  1. Тимур
    Тимур
    2021-04-22 17:21:29
    Решил проблему, надо было "*" на "+" исправить:
    &docid=`[[+id]]`
  • Amsterdam
    Amsterdam
    2020-12-12 10:03:33
    Александр, добрый день!

    А как возможно сделать поле migx, что бы в админке оно уже было предзаполнено определенным кодом? В идеале, вывести (в админке) поле textarea, которое бы использовало редактор ace, и в нем был бы прописан определенный код, который я задам в значении по умолчанию. Основной момент — это поле должно быть редактируемым, что бы была возможность дополнить код, вставленный по умолчанию, или вообще удалить.

    Не могу понять, как такое возможно реализовать. Через «значение по умолчанию» в ТВ не получается
    1. Александр Мальцев
      Александр Мальцев
      2020-12-13 15:52:01
      Привет! При создании поля в MIGX вам нужно перейти на вкладку «Input Options». В ней есть поле «Default Value» (значение по умолчанию) и «Use Default if Empty» (использовать по умолчанию если пустое). В «Default Value» вам следует указать преопределённый текст для этого поля.
    2. Amsterdam
      Amsterdam
      2020-12-14 08:50:03
      Спасибо! Через конструктор создания форм получилось, но не совсем как нужно выводится. Дело в том, что в выводе по умолчанию используется много строк кода, а выводятся они одной строкой (видимо поле «Default Value» не поддерживает форматирование).

      А как сделать вывод значений по умолчанию через json? Пытался использовать для этого Tv вкладку значений по умолчанию, но не работает…

      itchief.ru/assets/uploadify/e/8/b/e8bc88ae4bc39deea864d5b0ef931b8f.png
      itchief.ru/assets/uploadify/6/8/2/682e70d7b3d4391a1f4c10e15003c3f2.png
    3. Amsterdam
      Amsterdam
      2020-12-14 11:06:15
      Понял как через json сделать вывод: «default»:«test 555», «useDefaultIfEmpty»:«1», но там тоже нужно писать все только в строчку. А возможно ли подключить к выводу содержимое чанка?
    4. Amsterdam
      Amsterdam
      2020-12-14 11:39:22
      вопрос с выводом чанка тоже решил) «default»:"@CHUNK mychunkname", осталось понять, как прикрутить ace к выводу поля в админке
  • dokreg
    dokreg
    2020-11-26 19:40:52
    Здравствуйте, подскажите, а можно ли выводить элементы MIGX с установкой даты, т.е. задавать дату как у ресурсов в админке modx и применять отложенную публикацию?
    1. Александр Мальцев
      Александр Мальцев
      2020-11-28 02:18:43
      Здравствуйте! Добавьте в MIGX поля с датой публикации и опубликован. После этого напишите php-скрипт с нужной логикой и с помощью cron запускайте его с определённой периодичностью.
  • Андрей
    Андрей
    2020-03-20 16:43:36
    Спасибо за статью.
    Всё в принципе получилось, и мне удалось настроить эту вундервафлю под свои цели. Но есть несколько нюансов, которые так и не удаётся победить. Так, когда картинки добавились и я пытаюсь удалить одну из них (правой кнопкой мыши, нажимаю удалить) удаляются все добавленные картинки сразу. При чём, картинка по которой производился клик удаляется с сервера. Дико непонятно.
    Может есть способ добавить поле с кнопкой «Удалить», чтобы при нажатии фотка удалялась. Не с сервера, а чисто из поля редактора?
    1. Александр Мальцев
      Александр Мальцев
      2020-04-02 15:04:58
      При удалении одного элемента из таблицы должен удаляться только один, а не все. Файлы не должны удаляться при удалении записей. Это всё должно работать по умолчанию. Проверьте может вы какой-нибудь момент упустили. Также проверьте что у вас имеется TV поле image, у которого в качестве значения «Тип ввода» установлено «Изображение».
  • alyon
    alyon
    2019-11-21 09:49:46
    можно ли вывести несколько изображений, например, чтоб выводилось по 3?
    1. Александр Мальцев
      Александр Мальцев
      2019-11-21 12:00:30
      Для этого переделайте карусель на какую-нибудь другую, которая позволяет это выполнить очень просто. Например, её можно заменить на этот слайдер.
  • flintotake
    flintotake
    2018-10-28 21:19:10
    Здравстуйте. Сделал слайдер по вашей инструкции, но есть проблема. При попытке листать изображения влево или вправо вместо смены изображения выбрасывает на главную страницу сайта, а в адресной строке появляется «адрес сайта/#carousel». Помогите разобраться пожалуйста. Спасибо.
    1. Александр Мальцев
      Александр Мальцев
      2018-10-29 14:00:27
      Здравствуйте! В данном примере создание карусели осуществляется на базе фреймворка Bootstrap 3. Для её работы к странице должен быть подключён CSS и JS файл данной версии фреймворка.
    2. flintotake
      flintotake
      2018-11-01 23:35:50
      Сделал, всё работает, Спасибо. А подскажите, можно ли в конфигурацию добавить источником файлов галерею MS2Gallery?
    3. Александр Мальцев
      Александр Мальцев
      2018-11-04 04:34:02
      Не знаю, не пробовал. Если нужна галерея изображений, то можно просто использовать MS2Gallery и настроить вывод изображений, так как нужно.
  • Дмитрий
    Дмитрий
    2018-08-22 23:39:12
    Добрый вечер.

    Изучаю MIGX. Меня настораживает, что при вызове ВСЕХ сниппетов компонента (переносе мышкой в область контента) нет возможности установить его параметры (&....)
    &tvname=`photos`
    &tpl=`tplCarouselItem`
    Окошко параметров открывается, но оно пустое… что то мне подсказывает что так не должно быть… наверное то, что остальные сниппеты позволяют себя настраивать при вызове).
    Переустановил компонент — без изменений…

    Изображение
    1. Александр Мальцев
      Александр Мальцев
      2018-08-23 15:24:12
      Добрый! Откройте сниппет, а в нём вкладку «Параметры». Если параметры по умолчанию не заданы, то они и не будут отображаться.
    2. Дмитрий
      Дмитрий
      2018-08-23 19:18:00
      простите, а где и=х устанавливать? и почему другие сниппеты устанавливаются уже с параметрами по умолчанию?! просто странно как то. И еще. Александр, я вот сейчас буду импортировать ресурсы из CSV (пока у меня EXEL но это я решу) при помощи ImportX. Хочу импортировать сразу в несколько migx-tv- переменные. какая должна быть структура CSV? особенно меня интересуют изображения — у каждого объекта в таблице разное количество изображений списком через запятую в одной колонке (разделитель можно поменять). главное, чтобы все эти изображения залились в oдну migx переменную в разные tv. Вообще ImportX работает с MIGX.? если нет. то будет ли работать CfnflogFill?
  • Антон
    Антон
    2018-02-17 20:53:27
    У меня вопрос такого плана: Есть повторяющиеся items. В которых есть фото, имя человека, и перечень направлений что он делает. Проблема в том, что у разных людей количество этих направлений разное. Возможно ли в MIGX как-то реализовать чтобы заходя в дополнительные поля человек добавлял фото, имя, направление деятельности, и если ему нужно чтобы он мог нажать кнопочку и добавить еще 1, 2 или направления
    1. Серый
      Серый
      2018-01-12 01:21:33
      Александр, скажите, знаете ли вы, как можно добавить колонку, где будет выводиться URL для каждой добавленной картинки, что бы можно было копировать их и вставлять в нужное место в CKEeditore, например? У меня получилось добиться вывода имени файла, когда просто отключал рендер, и выбирал поле картинки, вот как-то бы еще туда добавить генерацию пути…
      1. Серый
        Серый
        2018-01-13 00:15:45
        Вопрос решился. Странное дело, прям какой-то синдром новичка, все сделал точно также, как в туторале, даже просто плейсхолдер [[+image]] вставлял и делал рендер чанка, потом даже все параметры в свой конфигурации идентичные проставил — один фиг весь массив выводился, а в той конфигурации, что импортировал по туториалу — всё ок, на том же MODX'e отлично всё рендерилось. В итоге я тот конфиг перепилил под себя, и теперь счастлив как идиот, ибо после многих дней бесплодной долбёжки в стену наконец-то всё пашет как надо))
    2. Серый
      Серый
      2018-01-07 19:44:56
      А можно ли как-то подключить к полю изображения дополнение Image+, что бы сделать, допустим не карусель, а нормальную компактную галерею без излишеств, но с управляемой генерацией миниатюр? Да так-то и для карусельки тоже полезно было бы… Заранее благодарю за совет!
      1. Александр Мальцев
        Александр Мальцев
        2018-01-08 15:30:15
        Разметку вы можете определить в чанке и тем самым получить нужный HTML код на выходе. Например, галерею.

        Для того чтобы использовать image+ для поля, его необходимо указать в качестве значения Input TV Type.
        Например:
        Fieldname (имя поля) – image, Caption – Изображение, Input TV Type – imageplus.
      2. Серый
        Серый
        2018-01-08 19:38:51
        Пробовал, вся сетка схлопывается… Там еще рендерер есть специальный под image+, все комбинации перепробовал(((
        Конечно, буду еще искать.
        Может оно с мультизагрузкой не хотело дружить? Я ведь сплю и вижу такой мегакомпонент себе накрутить, что б прямо в ресурс закидывать картинки, каждый иметь возможность прокадрировать, и с каждого получить ссылку на кропнутую картинку и на фулсайз (это что бы в Tiny MCE в текст вставлять миниатюрки, а при клике получать фулсайзы в лайтбоксе)
        мои мысли — мои скакуны…
      3. Александр Мальцев
        Александр Мальцев
        2018-01-09 14:31:35
        В качестве рендера установил ImagePlus.MIGX_Renderer. Всё корректно отображается и загружается.
        Скриншоты: отображение изображений, создание и редактирование изображения.
      4. Серый
        Серый
        2018-01-12 01:18:42
        Это потому что там не было мультизагрузки. Выявил такой досадный момент, что либо Image+, либо мультизагрузка((
    3. Евгений
      Евгений
      2017-10-13 16:32:16
      Прошу помощи сделал слайдер по этому уроку все вроде получилось с первого раза, но уже неделю не могу разобраться с CSS меня вверху слайдера модуль
      <ol class="carousel-indicators">    
      <li data-target="#carousel" data-slide-to="0" class="active"></li><li data-target="#carousel" data-slide-to="1"></li><li data-target="#carousel" data-slide-to="2"></li>  </ol>
      выводит цифры 1.2.3. вертикально не пойму как эту конструкцию вниз опустить и чтобы вместо цифр были точки горизонтально и второй вопрос это вместо стрелок вправо-лево выводятся кружочки
      <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">  
        <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>  
        </a>
      . Неделю угрохал и пока впустую сейчас попробовал вызвать вместо css/bootstrap.min.css просто css/bootstrap.css и все заработало как надо теперь вопрос, а как сделать чтоб на минимизированном работало?
      1. Александр Мальцев
        Александр Мальцев
        2017-10-14 04:56:02
        Попробуйте переустановить Bootstrap 3 и подключить его без использования сниппетов минимизаторов.
    4. Алексей
      Алексей
      2017-09-04 23:18:55
      Добрый вечер, Александр!

      Помогите, пожалуйста, разобраться в вопросе, который упорно не хочет решаться!

      В phpMyAdmin создал малюсеньку тестовую табличку:
      CREATE TABLE `abc_test_item` (
        `id` int(10) NOT NULL,
        `name` varchar(250) DEFAULT NULL,
        `message` varchar(255) DEFAULT NULL
      ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
      Установил CMPGenerator и с его помощью создал новый компонент. Структура со схемой создались замечательно. В консоле код:
      $modx->addPackage('test', $modx->getOption('core_path').'components/test/model/');
      
      $item = $modx->newObject('TestItem');
      $item->set('name', 'Alex');
      $item->set('message', 'Test Message');
      $item->save();
      тоже отрабатывает и данные в таблицу вносятся.

      Далее, по этому мануалу установил MIGX, чтобы сохраненные данные можно было отображать в админке. Создал пункт в верхнем меню, создал конфигурацию:
      {
        "formtabs":[
          {
            "MIGX_id":3,
            "caption":"info",
            "print_before_tabs":"0",
            "fields":[
              {
                "MIGX_id":9,
                "field":"name",
                "caption":"\u0418\u043c\u044f",
                "description":"",
                "description_is_code":"0",
                "inputTV":"",
                "inputTVtype":"",
                "validation":"",
                "configs":"",
                "restrictive_condition":"",
                "display":"",
                "sourceFrom":"config",
                "sources":"",
                "inputOptionValues":"",
                "default":"",
                "useDefaultIfEmpty":"0",
                "pos":1
              },
              {
                "MIGX_id":10,
                "field":"message",
                "caption":"\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435",
                "description":"",
                "description_is_code":"0",
                "inputTV":"",
                "inputTVtype":"textarea",
                "validation":"",
                "configs":"",
                "restrictive_condition":"",
                "display":"",
                "sourceFrom":"config",
                "sources":"",
                "inputOptionValues":"",
                "default":"",
                "useDefaultIfEmpty":"0",
                "pos":2
              }
            ],
            "pos":1
          }
        ],
        "contextmenus":"recall_remove_delete",
        "actionbuttons":"addItem||toggletrash",
        "columnbuttons":"recall_remove_delete",
        "filters":"",
        "extended":{
          "migx_add":"",
          "disable_add_item":"",
          "add_items_directly":"",
          "formcaption":"",
          "update_win_title":"Test Window title",
          "win_id":"test",
          "maxRecords":"",
          "addNewItemAt":"bottom",
          "media_source_id":"",
          "multiple_formtabs":"",
          "multiple_formtabs_label":"",
          "multiple_formtabs_field":"",
          "multiple_formtabs_optionstext":"",
          "multiple_formtabs_optionsvalue":"",
          "actionbuttonsperrow":4,
          "winbuttonslist":"",
          "extrahandlers":"",
          "filtersperrow":4,
          "packageName":"test",
          "classname":"TestItem",
          "task":"",
          "getlistsort":"id",
          "getlistsortdir":"desc",
          "sortconfig":"",
          "gridpagesize":"",
          "use_custom_prefix":1,
          "prefix":"abc_",
          "grid":"",
          "gridload_mode":1,
          "check_resid":1,
          "check_resid_TV":"",
          "join_alias":"",
          "has_jointable":"yes",
          "getlistwhere":"",
          "joins":"",
          "hooksnippets":"",
          "cmpmaincaption":"\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438",
          "cmptabcaption":"\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f",
          "cmptabdescription":"Tab Description",
          "cmptabcontroller":"",
          "winbuttons":"",
          "onsubmitsuccess":"",
          "submitparams":""
        },
        "columns":[
          {
            "MIGX_id":1,
            "header":"id",
            "dataIndex":"id",
            "width":"",
            "sortable":"false",
            "show_in_grid":1,
            "customrenderer":"",
            "renderer":"",
            "clickaction":"",
            "selectorconfig":"",
            "renderchunktpl":"",
            "renderoptions":"",
            "editor":""
          },
          {
            "MIGX_id":2,
            "header":"\u0418\u043c\u044f",
            "dataIndex":"name",
            "width":"",
            "sortable":"false",
            "show_in_grid":1,
            "customrenderer":"",
            "renderer":"",
            "clickaction":"",
            "selectorconfig":"",
            "renderchunktpl":"",
            "renderoptions":"",
            "editor":""
          },
          {
            "MIGX_id":3,
            "header":"\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435",
            "dataIndex":"message",
            "width":"",
            "sortable":"false",
            "show_in_grid":1,
            "customrenderer":"",
            "renderer":"",
            "clickaction":"",
            "selectorconfig":"",
            "renderchunktpl":"",
            "renderoptions":"",
            "editor":""
          }
        ]
      }
      по пункту меню начала отображаться болванка, но сами данные из базы никак не хотят отображаться, что только ни делал! По мануалу выше всё должно сработать с первого раза, но… Самое интересное, что при клике на кнопке «Добавить элемент», ввожу данные в поля «имя» и «сообщение» и данные успешно заносятся в базу! Т.е. связь с базой через контроллер настроена правильно. Не понимаю, в чем ошибка..? Кэши многократно чистил и CMS`ки и браузера — ничего. Можете подсказать?
      1. Виталий
        Виталий
        2017-07-31 15:17:18
        Здравствуйте, Александр!
        Все сделал по вашему описанию. Но слайдер не выводится. При вводе данных в таблицу, если подвести указатель мыши к заголовку, то везде [[*]], а должно быть, как я понимаю [[*title]] [[*image]] и т.д. В чем может быть причина?
        1. Александр Мальцев
          Александр Мальцев
          2017-07-31 16:29:45
          Скорее всего, вы что-то пропустили. Проверьте, создали вы поля на вкладке Formtabs.
        2. Виталий
          Виталий
          2017-07-31 17:08:25
          Спасибо! Как обычно, виноват сам. Я tv назвал photos-main-slider, а в вызове оставил скопированное &tvname=`photos`
      2. Серый
        Серый
        2017-07-18 23:50:13
        Спасибо за статью! А можно ли добавить колонку, где будет выводиться URL для каждой картинки, что бы можно было их вставлять в нужное место в CKEeditore, например? И где включается множественная загрузку файлов?
        docs.modx.com/extras/revo/migx/migx.tutorials/migx.use-resource-specific-mediasource-and-multifile-uploader
        Вот тут в принципе работает способ, но ошибку 500 выдает да и поля не те((
        Мне бы просто включить опцию мультизагрузки)))
        1. Александр Мальцев
          Александр Мальцев
          2017-07-19 06:40:11
          Опция мультизагрузки файлов включается так:
          1. Создать динамический источник файлов
          • Открыть источники файлов (Медиа->Источники файлов).
          • Создать новый источник файлов (Имя: ResourceMediaPath, Тип источника файлов: Файловая система).
          • Нажать на кнопку «Сохранить».
          • Выбрать только что созданный источник файлов и выбрать в контекстном меню пункт «Редактировать».
          • В качестве значений параметров basePath и baseUrl установить значение:
            [[migxResourceMediaPath? &pathTpl=`assets/resourceimages/{id}/` &createFolder=`1`]]
          • Нажать на кнопку «Сохранить».
          2. Отредактировать существующую конфигурацию MIGX, которая используется для добавления к ресурсу изображений. Для этого на вкладке Actionbuttons установить флажки напротив полей loadfromsource и uploadfiles.
          3. Отредактировать источник файлов для TV поля MIGX, а именно установить в качестве него ResourceMediaPath.
        2. Серый
          Серый
          2018-01-08 00:39:37
          Почему-то при этом отказывается показывать миниатюрки добавленных картинки. Если добавлять через обычную кнопку добавки — миниатюрки есть. А если так — то нет. Мне кажется пути где-то теряются, потому что если пустой рендер сделать, то на месте миниатюр — лишь имена файлов.
        3. Серый
          Серый
          2018-01-12 01:17:35
          Это было потому что Image+ не дружит c мультизагрузкой в MIGX((
      3. Михаил
        Михаил
        2017-06-16 03:02:49
        Здравствуйте. Отличная стать. Спасибо вам! В этой строчке ошибка?
        <li data-target="#carousel" data-slide-to="[[+idx:subtract]]" [[+idx:is=`1`:then=`class="active"`]]<>/li>
        Так не работает.
        1. Александр Мальцев
          Александр Мальцев
          2017-06-19 14:46:12
          Опечатка вышла. А так:
          <li data-target="#carousel" data-slide-to="[[+idx:subtract]]" [[+idx:is=`1`:then=`class="active"`]]></li>
          
        2. Михаил
          Михаил
          2017-06-19 20:51:45
          Да, спасибо. Уже понял)
      4. Юрий
        Юрий
        2017-03-29 11:56:28
        Здравствуйте, вопрос может немного не по теме, общий вопрос по ТВ.

        Такая идея, создать ТВ поля контактов (телефоны, адрес, почта, карта гугл и т д.) Сделать так, чтобы зайти в админку на ресурс «Главная», там внести значения и на сайте на автомате, везде где идет вызов ТВ, сменились контакты. Например вызываю ТВ [[*phone-1]], и везде на сайте (включая разные шаблоны), где идет вызов данного ТВ, меняется номер телефона. Это все для того, чтобы можно было зайти и в одном месте поменять все контакты на сайте. Столкнулся с проблемой. 1-е, ТВ контактов в админке подтягиваются ко всем ресурсам (в разделе доп. поля), так как пока всем ресурсам назначен один шаблон (если например заполняю все тв в главной то в остальных ресурсах пусто), можно ли скрыть для остальных ресурсов а показывать только для главной (с учетом того что один шаблон)?.. 2-е. когда идет вызов ТВ [[*phone-1]], то это ТВ подтягиветься только для главной, как сделать чтобы и на остальных отображалось по умолчанию с теме данными что введены для главной? (есть вариант задать в самом ТВ значение по умолчанию, может есть другой вариант)…
        itchief.ru/assets/uploadify/a/2/5/a25ebd91a29df95724d487a44d898beb.png
        1. Александр Мальцев
          Александр Мальцев
          2017-03-30 15:52:54
          Здравствуйте! Наиболее правильно это сделать через системные параметры или с помощью дополнения ClientConfig.
        2. Юрий
          Юрий
          2017-03-30 16:19:37
          Спасибо) как раз вчера так и сделал + это избавило от лишних запросов
      5. Артём
        Артём
        2017-03-21 14:54:08
        А как сделать, если нужно несколько галерей на странице? Причем картинки также должны быть привязаны к ресурсу. Ну например, есть страница описания дома и нужно вывести 2 слайдера, один показывает фото участка, а второй показывает фото внутри самого дома. Или выход только создавать несколько MIGX?
        1. Александр Мальцев
          Александр Мальцев
          2017-03-21 15:23:26
          Можно добавить в таблицу Fields дополнительное поле, которое будет определять, к какой карусели будет относиться данное изображение. А при получении данных, их фильтровать по этому полю с помощью параметра where сниппета getImageList:
          &where=`{"carousel:=":"1"}`
          
        2. Артём
          Артём
          2017-03-21 16:47:37
          Ага, тоже подумал завести отдельное поле. Спасибо за быструю подсказку!
      6. Max
        Max
        2017-03-12 03:39:16
        Вопрос. При создании полей в MIGX их нужно заносить в таблицу XML или это сейчас автоматически делается?
        itchief.ru/assets/uploadify/d/9/9/d99bfd9497b2db14835ab5b6a456b1f8.png
        1. Александр Мальцев
          Александр Мальцев
          2017-03-14 18:05:20
          В данной статье рассмотрена работа MIGX с использованием дополнительных полей (TV). Работа через БД будет рассмотрено в следующих статьях по MODX MIGX.
      7. Ник
        Ник
        2017-01-23 13:34:26
        Александр, здравствуйте. Прошу помочь с запросом к базе Migx. Долго бьюсь и никак не могу найти правильное решение.

        Суть:
        Делать выборку из поля со множественным значением.
        Есть Ресурс с подключенной базой Migx, где хранятся каталоги.
        Помимо родного ресурса эти каталоги нужно вывести и на многих других.
        Соответственно, на этом этапе нужна выборка определенных каталогов для определенного ресурса.
        Задачу пытался решить так:
        создал в Migx базе еще одно поле, где вручную указываю id ресурсов (пример — 5||20||13).
        В шаблоне этих ресурсов вывожу каталоги таким образом:
                [[!pdoPage?
                  &element=`getImageList`
                  &tvname=`catalogs_pdf`
                  &tpl=`tpl_catalogs_pdf`
                  &docid=`7`
                  &where=`{"id_pages:find":"[[*id]]"}`
                ]]
        
        Из запроса сразу видно, что работать будет, если в поле «id_pages» указан только один id.

        Для нескольких id пытался изменить условие "&where":
        &where=`["1 = 1 AND FIND_IN_SET('[[*id]]', replace(id_pages, '||', ','))"]`
        
        Это отсюда: modx.pro/development/7236-pdofetch-search-in-tv-fields-with-the-delimiter/

        Еще вариант:
            &where=`{
                "id_pages:LIKE": "1",
                "OR:id_pages:LIKE": "%||1||%",
                "OR:id_pages:LIKE": "1||%",
                "OR:id_pages:LIKE": "%||1",
            }`
        
        Пробовал через tvFilters, но тогда вообще ничего не работает:
            &tvFiltersOrDelimiter=`^^`
            &tvFilters=`id_pages==[[*id]]||%^^id_pages==%||[[*id]]^^id_pages==%||[[*id]]||%^^id_pages==[[*id]]`
        
        Догадываюсь, что собака зарыта в правильном составлении json строки, но, видимо, не хватает знаний.
        1. Alex DOM
          Alex DOM
          2017-01-23 20:27:09
          Ник, Вы вызываете код в сниппете, как вариант попробуйте +id, а не *id
          &where=`{«id_pages:find»:"[[+id]]"}`
        2. Ник
          Ник
          2017-01-23 20:38:32
          Alex, у меня сниппет вызывается на той странице, чей id мне и нужен. &where=`{«id_pages:find»:"[[*id]]"}` у меня прекрасно работает. Проблема в другом, а именно не могу правильно создать json строку для выборки из поля id_pages, когда в нем указано несколько id
        3. Александр Мальцев
          Александр Мальцев
          2017-01-24 15:01:24
          Если вы указываете поля id вручную (в данном случае) с помощью id_pages, то необходимо сделать так, чтобы их однозначно можно было определить.
          Например, так:
          2#3#
          
          Условие where переписать на следующее (вы его указываете для сниппета getImageList, а не для pdoTools):
          &where=`{"id_pages:contains":"[[*id]]#"}`
          
        4. Ник
          Ник
          2017-01-24 15:35:40
          Александр, благодарю!
          Ну почему, почему так просто)))
          Я даже что-то подобное пытался сделать, но дьявол кроется в мелочах. Пропустил видно, что # всем надо добавлять.
          Еще раз спасибо. Очень выручает ваш сайт для всех начинающих, это так нужно.
      8. Руслан
        Руслан
        2016-10-30 11:11:44
        сделал, но картинка расположились одна под другой

        вот код что получилось:
        <section>
                    <div class="container hideOnLoad showOnLoad">
                        <div id="carousel-main-wrapper">
                            <div id="carousel" class="main-carousel" data-ride="carousel">
                                <div class="carousel-inner">
                                    <div class="item">
                                            [[getImageList?
                                              &tvname=`photos`
                                              &tpl=`tplCarouselItem`
                                            ]]
                                    </div>
                                    
                                </div>
        
                                <ol class="carousel-indicators">
                                    <li data-target="#carousel" data-slide-to="0" class="active hideOnLoad showOnLoad1">
                                        <div class="carousel-caption">
                                               [[getImageList? 
                                                  &tvname=`photos`
                                                  &tpl=`tplCarouselIndicator`
                                                ]]
                                </ol>
        
                                <a class="left carousel-control" href="#carousel" data-slide="prev"></a>
                                <a class="right carousel-control" href="#carousel" data-slide="next"></a>
                            </div>
                            <div class="shadow"></div>
                        </div>
                    </div>
                </section>
        исходники:
        <section>
                    <div class="container hideOnLoad showOnLoad">
                        <div id="carousel-main-wrapper">
                            <div id="carousel" class="main-carousel" data-ride="carousel">
                                <div class="carousel-inner">
                                    <div class="item active">
                                        <img src="img/gallery/banner1.jpg" alt="" />
                                    </div>
                                    <div class="item">
                                        <img src="img/gallery/banner2.jpg" alt="" />
                                    </div>
                                    <div class="item">
                                        <img src="img/gallery/banner1.jpg" alt="" />
                                    </div>
                                    <div class="item">
                                        <img src="img/gallery/banner2.jpg" alt="" />
                                    </div>
                                </div>
        
                                <ol class="carousel-indicators">
                                    <li data-target="#carousel" data-slide-to="0" class="active hideOnLoad showOnLoad1">
                                        <div class="carousel-caption">
                                            <h2>Beautiful nature</h2>
                                            <h3>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h3>
                                        </div>
                                    </li>
                                    <li data-target="#carousel" data-slide-to="1" class="hideOnLoad showOnLoad2">
                                        <div class="carousel-caption">
                                            <h2>Lorem ipsum dolor</h2>
                                            <h3>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h3>
                                        </div>
                                    </li>
                                    <li data-target="#carousel" data-slide-to="2" class="hideOnLoad showOnLoad3">
                                        <div class="carousel-caption">
                                            <h2>Coffe & drinks</h2>
                                            <h3>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h3>
                                        </div>
                                    </li>
                                    <li data-target="#carousel" data-slide-to="3" class="hideOnLoad showOnLoad4">
                                        <div class="carousel-caption">
                                            <h2>Steak lunch menu</h2>
                                            <h3>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h3>
                                        </div>
                                    </li>
                                </ol>
        
                                <a class="left carousel-control" href="#carousel" data-slide="prev"></a>
                                <a class="right carousel-control" href="#carousel" data-slide="next"></a>
                            </div>
                            <div class="shadow"></div>
                        </div>
                    </div>
                </section>
        а чанки ваши.
        1. Александр Мальцев
          Александр Мальцев
          2016-10-30 12:04:49
          Проверьте подключили ли вы к странице фреймворк Twitter Bootstrap и библиотеку jQuery.
        2. Руслан
          Руслан
          2016-10-30 12:14:26
          подключено, они у меня в чанке /
        3. Руслан
          Руслан
          2016-10-30 12:39:42
          надо было удалить в шаблоне
        4. Руслан
          Руслан
          2016-10-31 16:29:40
          сайт ru7lan.ru должно выводится текст на зеленых квадратиках внизу слайдера, где я ошибся в коде?
          исходник слайдера выше скинул…
      9. Игорь Денисов
        Игорь Денисов
        2016-09-24 09:08:26
        Очень полезная статья!
        Вообще, уроки по modx радуют всегда. Отличная cmf-ка!