MODX - Как добавить дополнительные поля к ресурсам

Александр Мальцев
13K
5
MODX - Как добавить дополнительные поля к ресурсам
Содержание:
  1. Добавление таблицы в базу данных
  2. Создание директории для компонента
  3. Создание XML схемы компонента
  4. Генерирование модели компонента
  5. Принцип работы с компонентом extendresource
  6. Представление расширенных полей ресурса в админке
  7. Как добавить checkbox поле к компоненту и отобразить его в админке
  8. Как в админке MODX создать поля с одиночным и множественным выбором из списка
  9. Комментарии

Статья, в которой рассмотрим способ добавления дополнительных полей к ресурсу без использования TV.

Для хранения дополнительных данных будем использовать не системную (site_content), а свою таблицу. Например, имеющую имя site_content_extend. Для обеспечения работы с ней посредством xPDO создадим компонент (рабочую модель). В качестве названия компонента выберем, например, extendresource.

Для представления дополнительных полей в админке, а именно на страницах создания и редактирования ресурсов, напишем плагин. Если вам это действие не нужно, то создание этого элемента можно опустить.

Добавление таблицы в базу данных

Добавление новых объектов в базу данных можно осуществить, например, с помощью инструмента phpmyadmin.

В качестве примера создадим таблицу site_content_extend, имеющую следующие поля:

  • id – характеристики: тип - int(10), атрибуты – unsigned, auto_increment – да, первичный;
  • resource (id ресурса) – характеристики: тип - int(10), атрибуты – unsigned, уникальный;
  • views (количество просмотров) - характеристики: тип - int(10), атрибуты – unsigned, по умолчанию - 0;
  • keywords (ключевые слова) - характеристики: тип - varchar(120), по умолчанию – пустая строка;
  • level (минимальный уровень доступа к ресурсу) - характеристики: тип - smallint(5), атрибуты – unsigned, по умолчанию - 0.
Добавление таблицы в базу данных с помощью инструмента phpmyadmin

SQL дамп таблицы «modx_site_content_extend» можно скачать по этой ссылке.

Создание директории для компонента

Создадим в директории /core/components каталог extendresource.

После этого создадим ещё несколько папок, чтобы получился следующий путь:

core/components/extendresource/model/schema/

Создание XML схемы компонента

В каталоге schema компонента extendresource поместим файл extendresource.mysql.schema.xml со следующим содержимым:

<?xml version="1.0" encoding="UTF-8"?>
<model package="extendresource" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1">
  <object class="extendResource" table="site_content_extend" extends="xPDOSimpleObject">
    <field key="resource" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" index="unique" />
    <field key="views" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="index" />
    <field key="keywords" dbtype="varchar" precision="120" phptype="string" null="false" default="" />
    <field key="level" dbtype="smallint" precision="5" attributes="unsigned" phptype="integer" null="false" default="0" />

    <index alias="resource" name="resource" primary="false" unique="true" type="BTREE">
      <column key="resource" length="" collation="A" null="false" />
    </index>
    <index alias="views" name="views" primary="false" unique="false" type="BTREE" >
        <column key="views" length="" collation="A" null="false" />
    </index>

    <aggregate alias="Resource" class="modResource" local="resource" foreign="id" cardinality="one" owner="foreign" />
  </object>
</model>

XML схема в MODX Revolution – это описание объектов базы данных компонента и их связей. Она нужна только для того, чтобы выполнить генерацию рабочей модели компонента.

Генерирование модели компонента

На этом шаге создадим модель. Для выполнения этого действия воспользуемся скриптом parse_schema.php.

Принцип работы со скриптом parse_schema.php:

  1. Открыть файл в текстовом редакторе и ввести название компонента.
  2. Положить его в корень MODX сайта.
  3. Открыть данный файл из браузера.

После выполнения скрипта в каталоге «core/components/extendresource/model/» будут созданы php файлы (модель компонента).

MODX Revolution – Ввод название компонента в утилиту parse_schema.php MODX Revolution – Открытие файла parse_schema.php из браузера

Принцип работы с компонентом extendresource

Примеры, в которых показано, как можно осуществить получение значений расширенных полей ресурса и сохранение данных в них.

Сохранение данных в расширенные поля ресурса

Фрагмент php-кода, который можно использовать в сниппете или плагине для установки значений расширенным полям ресурса (views, keywords, level):

$id = $modx->resource->get('id');
$extendResource = $modx->getObject('extendResource',array(
  'resource' => $id,
));
if (!is_object($extendResource)) {
  $extendResource = $modx->newObject('extendResource');
  $extendResource->set('resource', $id);
}
$extendResource->set('views', 77);
$extendResource->set('keywords', 'modx, создание сайтов');
$extendResource->set('level', 100);
$extendResource->save();

Получение значений расширенных полей ресурса

Вывод значений расширенных полей ресурса на страницу можно осуществить разными способами.

1 вариант - с помощью плагина (например, ExtendResource).

Код плагина ExtendResource (php):

<?php
$modx->addPackage('extendresource', $modx->getOption('core_path').'components/extendresource/model/');

// в каких ресурсах необходимо показывать расширенные поля (массив шаблонов)
// $templateIds = [2, 3]; // (1)

// получаем шаблон, установленный в системных настройках по умолчанию
// $templateId = $modx->getOption('default_template'); // (1)
// получаем контекст нового ресурса
// $contextKey = $_GET['context_key'];

// если ресурс не новый, то получаем шаблон у ресурса
if ($id > 0) {
//   $templateId = $resource->get('template'); // (1)
//   $contextKey = $resource->get('context_key');
}

// если дополнительные поля нужно вывести только в ресурсах, привязанных к шаблонам указанных в $templateIds (в этом случае строчки (1) нужно раскомментировать)
// if (!in_array($templateId, $templateIds)) { // (1)
//  return; // (1)
// } // (1)

$id = $modx->resource->get('id');
$views = 0;
$keywords = '';
$level = 0;
// если ресурс не новый, то...
if ($id > 0) {
  $extendResource = $modx->getObject('extendResource',array(
    'resource' => $id,
  ));
  if (is_object($extendResource)) {
    $views = $extendResource->get('views');
    $keywords = $extendResource->get('keywords');
    $level = $extendResource->get('level');
  }
}
// устанавливаем плейсхолдеры
$modx->setPlaceholders(array(
  'views' => $views,
  'keywords' => $keywords,
  'level' => $level
),'extend.');
return;

В качестве события, при котором будет происходить выполнения плагина, установим OnLoadWebDocument. Данное событие возникает после загрузки документа, но перед тем как теги MODX будут обработаны.

Основное действие плагина ExtendResource заключается в установке плейсхолдеров extend.views, extend.keywords и extend.level.

Вывод значений расширенных полей текущего ресурса (в чанке или шаблоне):

Просмотры: [[+extend.views]]
Ключевые слова: [[+extend.keywords]]
Уровень: [[+extend.level]]

Другой вариант получить значения дополнительных полей – это воспользоваться сниппетом (например, getExtendResource):

<?php

$array = array (
  'views' => 0,
  'keywords' => '',
  'level' => 0
);

$output = $array[$field];

$id = $modx->resource->get('id');
$extendResource = $modx->getObject('extendResource',array(
  'resource' => $id,
));
if (is_object($extendResource)) {
    $output = $extendResource->get($field);
}

return $output;

Использование сниппета getExtendResource для получения значения расширенных полей ресурса (например, keywords):

[[!getExtendResource? &field=`keywords`]]

Представление расширенных полей ресурса в админке

Для того чтобы представить расширенные поля ресурса на страницах создания и редактирования ресурса, необходимо создать плагин (например, ExtendedResource). Плагин будет выполнять действия, при наступлении 2 событий: OnDocFormPrerender и OnDocFormSave. Поэтому на странице создания плагина во вкладке «Системные события» необходимо установить галочки напротив них.

MODX Revolution – Установка событий, которые должен отслеживать этот плагин

Событие OnDocFormPrerender возникает перед тем, как в менеджере будет загружена форма редактирования ресурса. Данное событие будем использовать для добавления расширенных полей views, keywords и level в форму создания и редактирования ресурса.

Событие OnDocFormSave происходит после того, как ресурс будет сохранён в менеджере через форму редактирования. Данное событие будем использовать для сохранения значений расширенных полей views, keywords и level.

Данный плагин (ExtendedResource) нужен только для того, чтобы с данными полями можно было взаимодействовать при создании и редактирования ресурсов в админке. Если это вам не нужно, то этот плагин можно не добавлять в систему MODX Revolution.

<?php

$modx->addPackage('extendresource', $modx->getOption('core_path').'components/extendresource/model/');

/* при необходимости */
// в каких ресурсах необходимо показывать расширенные поля (массив шаблонов)
// $templateIds = [2, 3];

// получаем шаблон, установленный в системных настройках по умолчанию
// $templateId = $modx->getOption('default_template');
// получаем контекст нового ресурса
// $contextKey = $_GET['context_key'];
// если ресурс не новый, то получаем шаблон и контекст у ресурса
// if ($id > 0) {
//   $templateId = $resource->get('template');
//   $contextKey = $resource->get('context_key');
// }

// завершаем работу плагина, если шаблон ресурса не соответствует не одному из указанных
// if (!in_array($templateId, $templateIds)) {
//   return;
// }

switch ($modx->event->name) {
  // OnDocFormPrerender
  case 'OnDocFormPrerender':
    $views = 0;
    $keywords = '';
    $level = 0;
    // если ресурс не новый, то...
    if ($id > 0) {
      $query = $modx->newQuery('extendResource');
      $query->where(array(
        'resource' => $id,
      ));
      $extendResource = $modx->getObject('extendResource',$query);
      if (is_object($extendResource)) {
        $views = $extendResource->get('views');
        $keywords = $extendResource->get('keywords');
        $level = $extendResource->get('level');
      }
    }
    $modx->controller->addHtml("<script>
    Ext.ComponentMgr.onAvailable('modx-resource-main-right', function(page) {
      page.on('beforerender', function() {
        page.insert(2,{
          xtype: 'textfield'
          ,name: 'views'
          ,value: {$views}
          ,anchor: '100%'
          ,layout: 'anchor'
          ,fieldLabel: 'Просмотры'
        });
        page.insert(3,{
          xtype: 'textfield'
          ,name: 'level'
          ,value: {$level}
          ,anchor: '100%'
          ,layout: 'anchor'
          ,fieldLabel: 'Уровень'
        });
      })
    });
    Ext.ComponentMgr.onAvailable('modx-resource-main-left', function(page) {
      page.on('beforerender', function() {
        page.insert(2,{
          xtype: 'textfield'
          ,name: 'keywords'
          ,value: '{$keywords}'
          ,anchor: '100%'
          ,layout: 'anchor'
          ,fieldLabel: 'Ключевые слова'
        });
      })
    });
  </script>");
    break;
  // OnDocFormSave
  case 'OnDocFormSave':
    $id = $scriptProperties['resource']->get('id');
    $query = $modx->newQuery('extendResource');
    $query->where(array(
      'resource' => $id,
    ));
    $extendResource = $modx->getObject('extendResource',$query);
    if (!is_object($extendResource)) {
      $extendResource = $modx->newObject('extendResource');
      $extendResource->set('resource', $id);
    }
    $extendResource->set('views', $_POST['views']);
    $extendResource->set('keywords', $_POST['keywords']);
    $extendResource->set('level', $_POST['level']);
    $extendResource->save();
    break;
}
MODX Revolution – Отображение расширенных полей на страницах создания и редактирования ресурсов

Как добавить checkbox поле к компоненту и отобразить его в админке

Процесс добавления checkbox поля к компоненту и представление его в админке состоит из следующих шагов:

1. Добавить в таблицу site_content_extend, например, поле isquestion. Характеристики: тип - tinyint(1), атрибуты – unsigned, по умолчанию – 0.

Добавление поле в таблицу базы данных, которое в MODX будет представлять checkbox поле

2. Обновить XML схему компонента, т.е. добавить в неё описание этого поля:

<field key="isquestion" dbtype="tinyint" precision="1" attributes="unsigned" phptype="boolean" null="false" default="0" />

3. Перегенерировать модель компонента с помощью скрипта parse_schema.php.

4. Обновить плагин ExtendedResource:

<?php
//...
$isquestion = 0;
//...
$isquestion = $extendResource->get('isquestion');
//...
page.insert(4,{
  xtype: 'xcheckbox'
  ,boxLabel: 'Отметье, если это вопрос'
  ,name: 'isquestion'
  ,id: 'extendresource-isquestion'
  ,inputValue: 1
  ,checked: parseInt({$isquestion}) || false
});
...
$extendResource->set('isquestion', $_POST['isquestion']);
Как добавить checkbox в админку MODX

Как в админке MODX создать поля с одиночным и множественным выбором из списка

В этом примере создадим 2 поля. Первое поле – это size. Заполнение этого поля в админке организуем из выпадающего списка с возможностью выбора только одного значения. Второе поле – это myhobbies. Данные этого поля могут состоять из нескольких значений устанавливаемых из списка.

Основные шаги:

1. Добавим в таблицу site_content_extend 2 поля.

  • Характеристики поля size: тип - varchar(5), сравнение – utf8_general_ci, по умолчанию – пустая строка.
  • Характеристики поля myhobbies: тип - varchar(255), сравнение – utf8_general_ci, по умолчанию – пустая строка.
Таблица компонента MODX

2. Добавим эти поля в XML схему компонента extendresource:

<field key="size" dbtype="varchar" precision="5" phptype="string" null="false" default="" />
<field key="myhobbies" dbtype="varchar" precision="255" phptype="string" null="false" default="" />

3. Обновим модель компонента, для этого запустим на выполнение уже настроенный скрипт parse_schema.php.

4. Добавим в плагин ExtendedResource код, который предоставит возможность работать с этими полями в админке MODX:

...
$size = '';
$myhobbies = '';
...
$size = $extendResource->get('size');
$myhobbies = $extendResource->get('myhobbies');
...
page.insert(5,{
  xtype: 'extendresource-size'
  ,name: 'size'
  ,value: '{$size}'
  ,hiddenName: 'size'
  ,anchor: '100%'
  ,layout: 'anchor'
  ,fieldLabel: 'Размер'
});
page.insert(6,{
  xtype: 'extendresource-myhobbies'
  ,id: 'extendresource-myhobbies-id'
  ,resizable: true
  ,name: 'myhobbies[]'
  ,hiddenName: 'myhobbies[]'
  ,value:'{$myhobbies}'
  ,anchor: '100%'
  ,layout: 'anchor'
  ,fieldLabel: 'Мои увлечения'
});
...
MODx.combo.extendresourceSizes = function(config) {
config = config || {};
Ext.applyIf(config,{
  store: new Ext.data.ArrayStore({
    id: 0
    ,fields: ['size']
    ,data: [
      ['XS']
      ,['S']
      ,['M']
      ,['L']
    ]
  })
  ,mode: 'local'
  ,displayField: 'size'
  ,valueField: 'size'
});
MODx.combo.extendresourceSizes.superclass.constructor.call(this,config);
};
Ext.extend(MODx.combo.extendresourceSizes,MODx.combo.ComboBox);
Ext.reg('extendresource-size',MODx.combo.extendresourceSizes);

MODx.combo.extendresourceMyhobbies = function(config) {
config = config || {};
Ext.applyIf(config,{
  xtype:'superboxselect'
  ,triggerAction: 'all'
  ,mode: 'local'
  ,store: new Ext.data.ArrayStore({
    id: 0
    ,autoLoad: true
    ,fields: ['hobbies']
    ,data: [
      ['бег']
      ,['дайвинг']
      ,['плавание']
      ,['лыжи']
      ,['боулинг']
    ]
  })
  ,mode: 'local'
  ,displayField: 'hobbies'
  ,valueField: 'hobbies'
  ,forceSelection: true
  ,triggerAction: 'all'
  ,extraItemCls: 'x-tag'
  ,expandBtnCls: 'x-form-trigger'
  ,clearBtnCls: 'x-form-trigger'
});
MODx.combo.extendresourceMyhobbies.superclass.constructor.call(this,config);
};
Ext.extend(MODx.combo.extendresourceMyhobbies,Ext.ux.form.SuperBoxSelect);
Ext.reg('extendresource-myhobbies',MODx.combo.extendresourceMyhobbies);
...
$extendResource->set('size', $_POST['size']);
$extendResource->set('myhobbies', implode(',', $_POST['myhobbies']));
...
Создание в админке MODX списка с одиночным выбором Создание в админке MODX списка с множественным выбором

Комментарии ()

  1. Павел Андросов
    01 февраля 2021, 17:44
    Александр, здравствуйте. В админку все вывелось, но вот в таблицу данные не сохраняются. При перезагрузке — скидывается до данных по умолчанию. Скорее всего — я не добавил код для сохранения данных. Не могли бы вы поподробнее рассказать как сделать сохранение данных. Спасибо
    1. Александр Мальцев
      02 февраля 2021, 16:07
      Здравствуйте! Может забыли включить системное событие OnDocFormSave для плагина?
      1. Павел Андросов
        02 февраля 2021, 16:26
        Проблема была в создании классов из схемы. Видимо, указал неправильную схему в parse_schema.php. Теперь все работает, огромное спасибо за уроки :)
    2. Александр
      30 ноября 2020, 21:54
      Александр, доброго вечера Вам! Случайно обнаружил «опечаток» в руководстве а точнее в разделе где рассказывается за плагин: «ExtendedResource» а конкретно в этой строке:
      </script>HTML);
      при таком окончании скрипта, выходит вот эта ошибка:
      Parse error: syntax error, unexpected '' (T_ENCAPSED_AND_WHITESPACE), expecting '-' or identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING)
      если каждый тег перенести на новую строку, всё работает:
      </script>
      HTML
      );
      Интересно, почему так происходит?
      1. Александр Мальцев
        01 декабря 2020, 14:49
        Привет, Александр! Спасибо, так получилось при форматировании кода статьи. Изменил этот момент, а также дополнительно вынес определение этой строки и присвоил её переменной $html. Так мне кажется лучше.
        Это просто такой синтаксис в php для определения строк. Он называется heredoc.
        1. Александр
          02 декабря 2020, 02:11
          Здравствуйте! Внёс изменения в плагин, спасибо.
      2. Александр
        28 ноября 2020, 21:05
        Александр, здравствуйте! Пытаюсь добавить условие для ограничения вывода своих полей, чтобы вывод полей был только в тех ресурсах у которых id шаблона равен 3 и 4, отчасти получается, но как обычно есть проблемы которые не получается решить, делаю так:
        if(!in_array($resource->get('template'),[3,4])){break;}
        почему-то это условие работает только для ресурсов, которые уже созданы а если добавляешь новый ресурс, то поля выводятся не смотря на то, какой шаблон у ресурса находится в поле (Шаблон), расскажите пожалуйста, как нужно сделать, чтобы при добавлении нового ресурса, поля выводились только в том случае, если в поле (Шаблон) выбран шаблон с id которые указаны в условие?
        1. Александр Мальцев
          29 ноября 2020, 16:51
          Добрый вечер! Эту возможность добавил в код плагина, приведённый в статье. По умолчанию этот код закомментирован. Раскомментируйте и внесите id нужных шаблонов в $templateIds.
          1. Александр
            29 ноября 2020, 18:52
            Здравствуйте! Александр, огромнейшее спасибо за решение, очень нужный функционал.
        2. Александр
          27 ноября 2020, 23:30
          Александр, доброго вечера Вам! Попал на глаза опечаток в руководстве, где рассказано за плагин «ExtendedResource» в место пакета: «extendresource» указан класс:
          modx->addPackage('extendResource'
          на локалке так работает, без проблем, видимо не так чувствителен к регистру а на хосте уже не хочет.
          1. Александр Мальцев
            29 ноября 2020, 14:34
            Спасибо, Александр! Поправил. Не работало, т.к. название пакета не соответствовало имени папки «extendresource». В Windows имена каталогов и файлов просто не чувствительны к регистру, а в остальных системах это конечно уже будут разные элементы.
          2. Amsterdam
            15 ноября 2020, 14:44
            Александр, добрый день!

            А как можно в minishop2, из карточки товара на фротне, записать определенную информацию в новое отдельное поле и потом вывести ее в админке? Этим способом почему то у меня не получается у товаров вывести доп.поля. Может где то ошибся, или там нужно по другому что то делать?..
            1. Александр Мальцев
              18 ноября 2020, 14:01
              Привет! Нужно проверить, где-то что-то забыли сделать. В админке проблем не должно быть. С фронта наверно не получится, т.к. ms2form работает дополнительно только с TV. Тут скорее всего только своё писать.
            2. Александр
              14 ноября 2020, 04:23
              Александр, здравствуйте! Как можно в админке вывести поле «изображение», подскажите пожалуйста?
              1. Александр Мальцев
                18 ноября 2020, 15:31
                Привет!
                Можно так:
                page.insert(1,{
                  xtype: 'panel'
                  ,border: false
                  ,bodyStyle: 'margin-top: 10px;'
                  ,html: '<img src="/assets/img-1.png" style="max-width: 100%; height: auto;">'
                });
                
                1. Александр
                  18 ноября 2020, 21:39
                  Здравствуйте! Спасибо. Александр, скажите пожалуйста а как можно добавить своё поле, для добавления изображения к ресурсу?
                  1. Александр Мальцев
                    27 ноября 2020, 15:04
                    Привет! Вставить поле для добавления изображения к ресурсу, используя Ext JS можно так (посредством modx-combo-browser):
                    // ...
                    page.insert(0,{
                      xtype: 'modx-combo-browser'
                      ,fieldLabel: 'Изображение'
                      ,name: 'image'
                      ,id: 'image'
                      ,anchor: '100%'
                      ,layout: 'anchor'
                    });
                    // ...
                    MODx.combo.Browser = function(config) {
                      config = config || {};
                      Ext.applyIf(config,{
                        width: 400
                       ,triggerAction: 'all'
                       ,triggerClass: 'x-form-file-trigger'
                       ,source: config.source || MODx.config.default_media_source
                      });
                      MODx.combo.Browser.superclass.constructor.call(this,config);
                      this.config = config;
                    };
                    Ext.extend(MODx.combo.Browser,Ext.form.TriggerField,{
                      browser: null
                     ,onTriggerClick : function(btn){
                        if (this.disabled){
                          return false;
                        }
                        this.browser = MODx.load({
                          xtype: 'modx-browser'
                         ,closeAction: 'close'
                         ,id: Ext.id()
                         ,multiple: true
                         ,source: this.config.source || MODx.config.default_media_source
                         ,hideFiles: this.config.hideFiles || false
                         ,rootVisible: this.config.rootVisible || false
                         ,allowedFileTypes: this.config.allowedFileTypes || ''
                         ,wctx: this.config.wctx || 'web'
                         ,openTo: this.config.openTo || ''
                         ,rootId: this.config.rootId || '/'
                         ,hideSourceCombo: this.config.hideSourceCombo || false
                         ,listeners: {
                            'select': {fn: function(data) {
                              this.setValue(data.relativeUrl);
                              this.fireEvent('select',data);
                            },scope:this}
                          }
                        });
                        this.browser.show(btn);
                        return true;
                      }
                      ,onDestroy: function(){
                        MODx.combo.Browser.superclass.onDestroy.call(this);
                      }
                    });
                    Ext.reg('modx-combo-browser',MODx.combo.Browser);
                    
                    Скриншот элемента:
                    Поле modx-combo-browser для добавления изображения к ресурсу в админке MODX
                    1. Александр
                      27 ноября 2020, 22:44
                      Александр, здравствуйте! Огромное спасибо, вывести поле (Изображение) получилось, но как понимаю для работы с ним есть некоторые нюансы?

                      Всё сделал по аналогии других полей, добавил поле в таблицу, изменил схему, обновил компонент, внёс изменения в плагин в итоге при добавлении изображения, в таблицу добавляется значение, (url изображения), но при перезагрузки страницы в редактировании ресурса поле «image» становится пустым, возможно где-то я опять начудил, правда проверил всё уже двадцать раз. Как я понимаю у меня не получается получить значение таким образом:
                      $image = $extendResource->get('image');
                      возможно для этого поля как-то по-другому это нужно делать?

                      Александр и если возможно, подскажите пожалуйста, как нужно сделать чтобы изображение добавленное к ресурсу в редактировании ресурса, отображалось рядом с полем «image»?
                      1. Александр Мальцев
                        28 ноября 2020, 10:52
                        Для того чтобы дополнительно вывести рядом с полем image картинку необходимо внести следующие изменения в код:
                        // ...
                        page.insert(1,{
                          xtype: 'panel'
                          ,id: 'image-panel'
                          ,border: false
                          ,bodyStyle: 'margin-top: 10px;'
                          ,html: '<img id="image-resource" src="/{$image}" style="max-width: 100%; height: auto;">'
                        });
                        // ...
                        ,listeners: {
                          'select': {fn: function(data) {
                            this.setValue(data.relativeUrl);
                            // добавить ещё следующее
                            var imageResource = Ext.get('image-resource');
                            imageResource.set({
                              src: '/'+data.relativeUrl
                            });
                        // ...
                        
                        1. Александр
                          28 ноября 2020, 13:14
                          Я изначально додумался только до того, чтобы использовать поле для вывода изображения, но тогда при редактировании ресурса и выборе изображения не будет обновления изображения на лету, а этот вариант просто идеальный, большое спасибо!
                        2. Александр Мальцев
                          28 ноября 2020, 10:46
                          Добрый день!
                          Тут вроде как обычно:
                          1. Добавляем в базу данных поле, например, image:
                          Добавление поля image в таблицу базы данных2. В «extendresource.mysql.schema.xml» помещаем строчку:
                          <field key="image" dbtype="varchar" precision="255" phptype="string" null="false"/>
                          
                          3. Обновляем модель.
                          4. Вносим изменения в плагин ExtendedResource:
                          // ...
                          $image = '';
                          // ...
                          $image = $extendResource->get('image');
                          // ...
                          page.insert(0,{
                            xtype: 'modx-combo-browser'
                            ,fieldLabel: 'Изображение'
                            ,name: 'image'
                            ,id: 'image'
                            ,value: '{$image}'
                            ,anchor: '100%'
                            ,layout: 'anchor'
                          });
                          // ...
                          $extendResource->set('image', $_POST['image']);
                          // ...
                          
                          1. Александр
                            28 ноября 2020, 13:07
                            Александр, здравствуйте! Получается я не указал в параметрах поля:
                            ,value: '{$image}'
                            по этому были проблемы. Огромное Вам спасибо!
                2. Александр
                  12 ноября 2020, 15:44
                  Александр, здравствуйте! Пытаюсь вывести поля в компоненте Comparison (Сравнение товаров), делаю таким образом:
                  [[!CompareList?
                      &loadModels=`extendresource`
                      &leftJoin=`{
                      "extendresource": {
                        "class": "extendResource",
                        "alias": "extFields",
                        "on": "extFields.resource = modResource.id"
                        }
                    }`
                    &select=`{"extFields": "extFields.country as country,extFields.date as date,extFields.size as size,extFields.context as context"
                    }`  
                    }`
                  ]]  
                  но не получается это сделать, подскажите пожалуйста, как можно использовать свои поля в компоненте Comparison?
                  1. Александр Мальцев
                    12 ноября 2020, 16:07
                    Александр, CompareList не использовал. Может он это просто не умеет. Если это так, то тогда только разрабатывать свой сниппет.
                    1. Александр
                      12 ноября 2020, 17:01
                      В мануале этого компонента указано (вы можете подключить значения из таблицы msProductFil) и приведён пример с параметром «leftjoin» и «Select»Александр, если теоретически, можно ли c этого примера сделать вывод, что он будет работать с другими полями?
                      1. Александр Мальцев
                        13 ноября 2020, 14:54
                        Александр, у меня нет CompareList. В нём наверно нет «modResource.id». Нужно вместо этого поля указать другое.
                        1. Александр
                          13 ноября 2020, 17:08
                          Александр, чтобы уже точно убедится что использовать «CompareList» для своих полей не получится на всякий случай скину ссылку на сниппет CompareList, если у Вас будет время, посмотрите пожалуйста.
                          1. Александр Мальцев
                            14 ноября 2020, 04:54
                            Если он у вас используется для сравнения товаров, то «msProduct.id», иначе «modResource.id». Если не получится, то в документации CompareList имеется пример с использованием prepareSnippet. Можете сделать через него.
                            1. Александр
                              14 ноября 2020, 09:45
                              Спасибо!
                  2. Александр
                    05 ноября 2020, 19:13
                    Александр, здравствуйте! Всё реализовал по данному руководству, всё получилось, ещё раз спасибо за данное решение, но есть проблема, плагин почему-то добавляет значения в таблицу базы, разделяя их запятой, пример: «дайвинг, плаванье, лыжи» менял в плагине вот эту строку:

                    $extendResource->set('myhobbies', implode('||', $_POST['myhobbies']));
                    указав там разделитель || тогда в таблице сохраняет как нужно, но при таком раскладе в админке при перезагрузке страницы, выбранные значения слетают.

                    1. Скажите пожалуйста что нужно поправить, чтобы разделитель у значений в базе данных был "||"?

                    2. Как можно сделать чтобы выводить определённые поля в дополнительной вкладке админки?

                    3. Можно ли указать какое поле и в каком шаблоне использовать?

                    4. Если можно, к примеру добавить иконки, картинку, стили к значениям в админке, то как лучше это сделать?

                    Если возможно, подскажите пожалуйста.
                    1. Александр Мальцев
                      06 ноября 2020, 15:59
                      Привет!
                      1. В этом случае нужно при получении значения заменить || на запятую. Т.е.:
                      // эту строчку 
                      $myhobbies = $extendResource->get('myhobbies');
                      // заменить на
                      $myhobbies = str_replace('||',',',$extendResource->get('myhobbies'));
                      
                      2. Можно, но готового кода нет, т.к. такой необходимости не было.
                      3. Можно, для этого следует получить шаблон ресурса, а далее в зависимости от него реализовать определённую логику:
                      // получим id шаблона ресурса
                      $template = $resource->get('template');
                      
                      4. Добавить стили в админку, например, можно так:
                      $modx->controller->addCss($modx->getOption('assets_url') . 'bootstrap/css/bootstrap.min.css');
                      
                      Кроме этого можно сделать и многие другие вещи, тут нужно просто разобраться как с ней работать.
                      1. Александр
                        06 ноября 2020, 18:20
                        Александр, большое спасибо за примеры! Правда касаемо первого вопроса, возможно я не точно описал суть проблемы, в нём речь идёт не о получении значений при помощи плагина ExtendResource, а о сохранении их в базу данных с разделителем || плагин ExtendedResource, проблема в следующем, при выборе значений поля myhobbies в админке при редактировании ресурса, в phpmyadmin в таблице в ячейке значения сохраняются через запятую, вот таким образом: «дайвинг, плаванье, лыжи» а нужно чтобы разделитель был || как я понимаю с каким разделителем выбранные значения поля myhobbies будут хранится в таблице в phpmyadmin, отвечает строка плагина ExtendedResource:
                        $extendResource->set('myhobbies', implode(',', $_POST['myhobbies']));
                        точнее параметр implode, если в нём убрать запятую и поставить || тогда значения в таблице сохраняются правильно «дайвинг||плаванье||лыжи» но тогда возникает проблема, выбрав значения при редактировании ресурса, нажимаешь сохранить, перезагружаешь страницу а поле пустое, но в phpmyadmin в таблице они есть, подскажите пожалуйста что нужно поправить?

                        Phpmyadmin, ячейка таблицы как хранятся выбранные значения
                        1. Александр Мальцев
                          07 ноября 2020, 02:51
                          Так правильно, при сохранении вы используете разделитель ||:
                          $extendResource->set('myhobbies', implode('||', $_POST['myhobbies']));
                          
                          А при получении преобразовываете его в запятую:
                          $myhobbies = str_replace('||',',',$extendResource->get('myhobbies'));
                          
                          1. Александр
                            07 ноября 2020, 03:20
                            Да, но проблема в том что если я в параметре implode использую разделитель || в место запятой, то в админке в поле выбранные значения у ресурса:
                            при перезагрузки страницы слетают, просто пустое поле становится:
                            может это зависит от параметров таблицы? Что можно попробовать сделать в данном случае?
                            1. Александр Мальцев
                              07 ноября 2020, 11:27
                              В базу сохраняем с использованием разделителя ||:
                              $extendResource->set('myhobbies', implode('||', $_POST['myhobbies']));
                              
                              При получении значения из базы заменяем || на запятую:
                              $myhobbies = str_replace('||',',',$extendResource->get('myhobbies'));
                              
                              А что в этом случае конкретно не работает? Запятая как была, так и осталась, только в базе значение хранится с помощью разделителя ||.
                              1. Александр
                                07 ноября 2020, 15:33
                                Александр, если я делаю так:
                                $extendResource->set('myhobbies', implode('||', $_POST['myhobbies']));
                                как вы и говорите в базе сохраняется с разделителем || но начинаются проблемы в админке при выборе значений поля, к примеру редактирую ресурс, выбираю в поле myhobbies (Мои увлечения) Бег, Дайвинг, Лыжи, нажимаю сохранить, перезагружаю страницу а поле (Мои увлечения) пустое как будто-то, не чего не выбрано.

                                Если делаю так:
                                $extendResource->set('myhobbies', implode(',', $_POST['myhobbies']));
                                В админке при добавлении значений к ресурсу, проблем нет, но тогда в в базе значения сохраняются через запятую.

                                С чем это может быть связано, что можно ещё попробовать сделать в данном случае?
                                1. Александр Мальцев
                                  07 ноября 2020, 15:50
                                  Так написал, что нужно изменить ещё в одном месте (при получении данных):
                                  ...
                                  $size = '';
                                  $myhobbies = '';
                                  ...
                                  $size = $extendResource->get('size');
                                  //$myhobbies = $extendResource->get('myhobbies');
                                  $myhobbies = str_replace('||',',',$extendResource->get('myhobbies'));
                                  
                                  1. Александр
                                    07 ноября 2020, 17:34
                                    Александр по поводу первого моего вопроса (1. Не сохраняет в базу значения, если используешь это поле для категории ресурсов, почему так?), получилось решить проблему, указав у всех полей, кроме поля (id) и (resources) По умолчанию NULL, но на сколько это правильно и стоит ли так делать?
                                    1. Александр Мальцев
                                      12 ноября 2020, 14:40
                                      Александр, нужно проверить индексы таблицы в базе данных.
                                      1. Александр
                                        12 ноября 2020, 15:11
                                        Спасибо!
                                    2. Александр
                                      07 ноября 2020, 16:34
                                      Честно говоря, как-то даже не ловко, что я не сразу понял с предыдущих ваших ответов всю суть для решения проблемы, огромное спасибо! А за что отвечает этот параметр:
                                      page.insert(6,
                                      Александр и если возможно, есть две проблемы, с которыми тоже не получается разобраться:

                                      1. Не сохраняет в базу значения, если используешь это поле для категории ресурсов, почему так?

                                      2. И не получается вывести в результатах mFilter2, [[!+extend.myhobbies]], как это можно попробовать решить?
                                      1. Александр Мальцев
                                        12 ноября 2020, 14:35
                                        Этот пример вставляет на страницу блок после 6 элемента в указанной секции.
                                        1. Не знаю с чем у вас это связано. Если ресурс является контейнером всё сохраняется.
                                        2. Необходимо в сниппет mFilter2 добавить модель extendResource (&loadModels), соединение с таблицей content_extend (&leftjoin) и выбрать нужные поля из таблицы (&select).
                                        1. Александр
                                          12 ноября 2020, 14:53
                                          Александр, спасибо! Первая проблема была из-за не правильной структуры таблицы сейчас всё работает, вторая тоже по моей невнимательности, ещё раз спасибо за помощь.
                      2. Александр
                        09 октября 2019, 21:40
                        Отличное руководство, спасибо! Скажите пожалуйста, как можно сделать, чтобы в админке к примеру поле level было выпадающим списком, множественный выбор или чекбоксами, аналогично тв?
                        1. Александр Мальцев
                          13 октября 2019, 07:29
                          Информацию по остальным двум моментам тоже добавил в статью.
                          1. Александр
                            16 октября 2019, 09:01
                            Александр, спасибо. Очень нужная и максимально понятная информация.
                          2. Александр Мальцев
                            12 октября 2019, 13:06
                            Спасибо за добрые слова. Информацию по checkbox полю добавил в статью.
                            1. Александр
                              12 октября 2019, 16:24
                              Огромное спасибо за очень нужную и полезную информацию.
                          3. Aleksandr Dom
                            22 июля 2019, 08:54
                            Добрый день.
                            Не подскажите, как с помощью формы на странице, добавить запись в свою таблицу БД?
                            Т.е. таблицу сделал. Схему написал. С выводом вроде бы всё понятно. А вот как формой (php или formit) не соображу.
                            1. Сеокотов
                              12 июля 2018, 16:57
                              есть ли какие то преимущества в скорости работы с этими полями перед TVшками? Или это только для удобства администрирования?
                              1. Александр Мальцев
                                12 июля 2018, 17:35
                                Конечно, есть. Если, например, в проекте используется 7 TV. То для получения их значений для данного ресурса необходимо будет использовать 7 конструкций &leftJoin. И соответственно данный запрос будет выполняться намного дольше, чем, если бы получить все эти значения из одной строки таблицы. В последнем случае понадобится всего один &leftJoin.
                                Кроме этого используя эту инструкцию, можно установить полям необходимый тип данных, в случае с TV это сделать нельзя, их значение всегда имеет тип mediumtext. А это создаёт трудности для фильтрации и сортировки.
                              2. Сергей
                                03 сентября 2017, 19:37
                                Сделал компонент Extend с таблицей Extendresource в БД и с 4 дополнительными полями:
                                depth, width, length, grid.
                                Но по аналогии с вашим кодом у меня не заработало, но в результате разбирательств у меня корректно заработал такой код:
                                <?php
                                $modx->addPackage('Extend', $modx->getOption('core_path').'components/Extend/model/', 'modx_');
                                
                                switch ($modx->event->name) {
                                    case 'OnDocFormRender':
                                        $Extendresource = $modx->getObject('Extendresource', array('id_resource' => $id));
                                        if ($mode == 'upd' && $Extendresource)
                                        {
                                            $depth = $Extendresource->get('depth');
                                            $width = $Extendresource->get('width');
                                            $length = $Extendresource->get('length');
                                            $grid = $Extendresource->get('grid');
                                        }
                                
                                $modx->controller->addHtml(<<<HTML
                                <script>
                                    Ext.ComponentMgr.onAvailable('modx-resource-main-right', function(page) {
                                        page.on('beforerender', function() {
                                            page.insert(2,{
                                                xtype: 'textfield'
                                                ,name: 'depth'
                                                ,value: '{$depth}'
                                                ,anchor: '100%'
                                                ,layout: 'anchor'
                                                ,fieldLabel: 'Глубина'
                                            });
                                            page.insert(3,{
                                                xtype: 'textfield'
                                                ,name: 'width'
                                                ,value: '{$width}'
                                                ,anchor: '100%'
                                                ,layout: 'anchor'
                                                ,fieldLabel: 'Ширина'
                                            });
                                            page.insert(4,{
                                                xtype: 'textfield'
                                                ,name: 'length'
                                                ,value: '{$length}'
                                                ,anchor: '100%'
                                                ,layout: 'anchor'
                                                ,fieldLabel: 'Длина'
                                            });
                                            
                                        })
                                    });
                                    Ext.ComponentMgr.onAvailable('modx-resource-main-left', function(page) {
                                        page.on('beforerender', function() {
                                            page.insert(2,{
                                                xtype: 'textfield'
                                                ,name: 'grid'
                                                ,value: '{$grid}'
                                                ,anchor: '100%'
                                                ,layout: 'anchor'
                                                ,fieldLabel: 'Декоративная решетка'
                                            });
                                        })
                                    });
                                </script>
                                HTML
                                );
                                
                                    break;
                                        
                                    case 'OnDocFormSave':
                                        $depth = $resource->get('depth');
                                        $width = $resource->get('width');
                                        $length = $resource->get('length');
                                        $grid = $resource->get('grid');
                                        
                                        if (!$Extendresource = $modx->getObject('Extendresource', array('id_resource' => $id)))
                                        {
                                             $Extendresource = $modx->newObject('Extendresource', array(
                                                'depth' => $depth,
                                                'width' => $width,
                                                'length' => $length,
                                                'grid'=> $grid
                                            ));
                                        }
                                
                                            $Extendresource->set('depth', $depth);
                                            $Extendresource->set('width', $width);
                                            $Extendresource->set('length', $length);
                                            $Extendresource->set('grid', $grid);
                                
                                        $Extendresource->save();
                                        break;
                                }
                                return;
                                
                                1. Сергей
                                  03 сентября 2017, 13:00
                                  Мдя.
                                  Сделал, все как написано.
                                  В админке дополнительные поля не отображаются. В журнале ошибок пусто.
                                  Похоже вот это не работает, хотя плагин отрабатывает.
                                  $modx->controller->addHtml(<<<HTML
                                  <script>
                                      Ext.ComponentMgr.onAvailable('modx-resource-main-right', function(page) {
                                          page.on('beforerender', function() {
                                              page.insert(2,{
                                                  xtype: 'textfield'
                                                  ,name: 'views'
                                                  ,value: {$views}
                                                  ,anchor: '100%'
                                                  ,layout: 'anchor'
                                                  ,fieldLabel: 'Просмотры'
                                              });
                                              page.insert(3,{
                                                  xtype: 'textfield'
                                                  ,name: 'level'
                                                  ,value: {$level}
                                                  ,anchor: '100%'
                                                  ,layout: 'anchor'
                                                  ,fieldLabel: 'Уровень'
                                              });
                                          })
                                      });
                                      Ext.ComponentMgr.onAvailable('modx-resource-main-left', function(page) {
                                          page.on('beforerender', function() {
                                              page.insert(2,{
                                                  xtype: 'textfield'
                                                  ,name: 'keywords'
                                                  ,value: '{$keywords}'
                                                  ,anchor: '100%'
                                                  ,layout: 'anchor'
                                                  ,fieldLabel: 'Ключевые слова'
                                              });
                                          })
                                      });
                                  </script>
                                  HTML
                                  );
                                  
                                  1. Сергей
                                    03 сентября 2017, 14:52
                                    Хм, так поля появились. Значит я где-то накосячил. Буду разбираться.
                                  2. Сергей
                                    31 августа 2017, 08:39
                                    А какого типа надо добавить дополнительное поле к ресурсу (например «Ширина») и при редактировании ресурса добавить несколько вариантов значений в это поле, что бы потом на фронтенде можно было с этого поля сделать DropDown List с теми вариантами которые ми определили в админке?
                                    Спасибо.
                                    1. Александр Мальцев
                                      31 августа 2017, 15:49
                                      Добавить текстовое поле width в таблицу, например, с типом varchar(255). Обновить XML схему и сгенерировать модель.

                                      Для разделения значений поля width использовать 2 вертикальные линии.
                                      Например:
                                      200||300||900
                                      
                                      После этого создать сниппет outputList, чанки tplOuterList и tplInnerList.

                                      Сниппет outputList:
                                      <?php
                                      $value = $modx->getOption('value', $scriptProperties);
                                      $tplInnerList = $modx->getOption('tplInnerList', $scriptProperties,'tplInnerList');
                                      $tplOuterList = $modx->getOption('tplOuterList', $scriptProperties,'tplOuterList');
                                      
                                      $array = explode ('||', $value);
                                      $items = array();
                                      foreach ($array as $val) {
                                          $items[] = $modx->getChunk($tplInnerList,array(
                                              'item' => $val
                                          ));
                                      }
                                      
                                      $list = implode('', $items);
                                      
                                      $output = $modx->getChunk($tplOuterList,array(
                                          'items' => $list
                                      ));
                                      
                                      return $output;
                                      
                                      Чанк tplOuterList:
                                      <select>[[+items]]</select>
                                      Чанк tplInnerList:
                                      <option>[[+item]]</option>
                                      Использование сниппета outputList в шаблоне или чанке:
                                      [[!outputList? &value=`[[!getExtendResource? &field=`width`]]`]]
                                      [[!outputList? &value=`[[+extend.width`]]
                                    2. Виталий
                                      16 августа 2017, 13:05
                                      Поясните пожалуйста:
                                      Поле views (количество просмотров) — будет подсчитывать количество просмотров или надо ещё спец.компоненты устанавливать?
                                      Поле level (минимальный уровень доступа к ресурсу) — для чего используется?
                                      1. Александр Мальцев
                                        17 августа 2017, 13:57
                                        Это просто пример как можно организовать добавление дополнительный полей к ресурсу. Поля views, level, keywors приведены для примера. Если нужно, например, вести учёт просмотр ресурсов, то эту логику, конечно, необходимо написать дополнительно.

                                        Эту инструкцию можно использовать в качестве примера. Например, если вы будете создавать сайт по сдачи квартир, то вам понадобится добавить к ресурсу следующие поля: адрес квартиры, площадь, этаж, цена, состояние, и т.д. Если вы будете это делать с помощью TV, то это приведёт не только к большему количеству запросов при выборе нужных данных, но и к сложностям их фильтрации.
                                        1. Виталий
                                          17 августа 2017, 16:41
                                          Спасибо.
                                      Войдите, пожайлуста, в аккаунт, чтобы оставить комментарий.