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

Александр Мальцев
12K
5
MODX - Как добавить дополнительные поля к ресурсам

Статья, в которой рассмотрим способ добавления дополнительных полей к ресурсу без использования 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. Павел Андросов
    Вчера в 17:44
    Александр, здравствуйте. В админку все вывелось, но вот в таблицу данные не сохраняются. При перезагрузке — скидывается до данных по умолчанию. Скорее всего — я не добавил код для сохранения данных. Не могли бы вы поподробнее рассказать как сделать сохранение данных. Спасибо
    1. Александр Мальцев
      25 минут назад
      Здравствуйте! Может забыли включить системное событие OnDocFormSave для плагина?
      1. Павел Андросов
        6 минут назад
        Проблема была в создании классов из схемы. Видимо, указал неправильную схему в 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
                                          Спасибо.
                                      Войдите, пожайлуста, в аккаунт, чтобы оставить комментарий.