- Добавление таблицы в базу данных
- Создание директории для компонента
- Создание XML схемы компонента
- Генерирование модели компонента
- Принцип работы с компонентом extendresource
- Представление расширенных полей ресурса в админке
- Как добавить checkbox поле к компоненту и отобразить его в админке
- Как в админке MODX создать поля с одиночным и множественным выбором из списка
- Комментарии
Расширение стандартных полей ресурса через свою таблицу в 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.

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
:
- Открыть файл в текстовом редакторе и ввести название компонента.
- Положить его в корень MODX сайта.
- Открыть данный файл из браузера.
После выполнения скрипта в каталоге «core/components/extendresource/model/» будут созданы 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. Поэтому на странице создания плагина во вкладке «Системные события» необходимо установить галочки напротив них.

Событие 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; }

Как добавить checkbox поле к компоненту и отобразить его в админке
Процесс добавления checkbox поля к компоненту и представление его в админке состоит из следующих шагов:
1. Добавить в таблицу site_content_extend
, например, поле isquestion
. Характеристики: тип - tinyint(1)
, атрибуты – unsigned
, по умолчанию – 0
.

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']);

Как в админке MODX создать поля с одиночным и множественным выбором из списка
В этом примере создадим 2 поля. Первое поле – это size
. Заполнение этого поля в админке организуем из выпадающего списка с возможностью выбора только одного значения. Второе поле – это myhobbies
. Данные этого поля могут состоять из нескольких значений устанавливаемых из списка.
Основные шаги:
1. Добавим в таблицу site_content_extend
2 поля.
- Характеристики поля
size
: тип -varchar(5)
, сравнение –utf8_general_ci
, по умолчанию – пустая строка. - Характеристики поля
myhobbies
: тип -varchar(255)
, сравнение –utf8_general_ci
, по умолчанию – пустая строка.

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'])); ...


Интересно, почему так происходит?
Это просто такой синтаксис в php для определения строк. Он называется heredoc.
А как можно в minishop2, из карточки товара на фротне, записать определенную информацию в новое отдельное поле и потом вывести ее в админке? Этим способом почему то у меня не получается у товаров вывести доп.поля. Может где то ошибся, или там нужно по другому что то делать?..
Можно так:
Скриншот элемента:
Всё сделал по аналогии других полей, добавил поле в таблицу, изменил схему, обновил компонент, внёс изменения в плагин в итоге при добавлении изображения, в таблицу добавляется значение, (url изображения), но при перезагрузки страницы в редактировании ресурса поле «image» становится пустым, возможно где-то я опять начудил, правда проверил всё уже двадцать раз. Как я понимаю у меня не получается получить значение таким образом:
Возможно для этого поля как-то по-другому это нужно делать?
Александр и если возможно, подскажите пожалуйста, как нужно сделать чтобы изображение добавленное к ресурсу в редактировании ресурса, отображалось рядом с полем «image»?
Тут вроде как обычно:
1. Добавляем в базу данных поле, например, image:
2. В «extendresource.mysql.schema.xml» помещаем строчку:
3. Обновляем модель.
4. Вносим изменения в плагин ExtendedResource:
Но не получается это сделать, подскажите пожалуйста, как можно использовать свои поля в компоненте Comparison?
указав там разделитель || тогда в таблице сохраняет как нужно, но при таком раскладе в админке при перезагрузке страницы, выбранные значения слетают.
1. Скажите пожалуйста что нужно поправить, чтобы разделитель у значений в базе данных был "||"?
2. Как можно сделать чтобы выводить определённые поля в дополнительной вкладке админки?
3. Можно ли указать какое поле и в каком шаблоне использовать?
4. Если можно, к примеру добавить иконки, картинку, стили к значениям в админке, то как лучше это сделать?
Если возможно, подскажите пожалуйста.
1. В этом случае нужно при получении значения заменить || на запятую. Т.е.:
2. Можно, но готового кода нет, т.к. такой необходимости не было.
3. Можно, для этого следует получить шаблон ресурса, а далее в зависимости от него реализовать определённую логику:
4. Добавить стили в админку, например, можно так:
Кроме этого можно сделать и многие другие вещи, тут нужно просто разобраться как с ней работать.
Phpmyadmin, ячейка таблицы как хранятся выбранные значения
А при получении преобразовываете его в запятую:
При получении значения из базы заменяем || на запятую:
А что в этом случае конкретно не работает? Запятая как была, так и осталась, только в базе значение хранится с помощью разделителя ||.
как вы и говорите в базе сохраняется с разделителем || но начинаются проблемы в админке при выборе значений поля, к примеру редактирую ресурс, выбираю в поле myhobbies (Мои увлечения) Бег, Дайвинг, Лыжи, нажимаю сохранить, перезагружаю страницу а поле (Мои увлечения) пустое как будто-то, не чего не выбрано.
Если делаю так:
В админке при добавлении значений к ресурсу, проблем нет, но тогда в в базе значения сохраняются через запятую.
С чем это может быть связано, что можно ещё попробовать сделать в данном случае?
1. Не сохраняет в базу значения, если используешь это поле для категории ресурсов, почему так?
2. И не получается вывести в результатах mFilter2, [[!+extend.myhobbies]], как это можно попробовать решить?
1. Не знаю с чем у вас это связано. Если ресурс является контейнером всё сохраняется.
2. Необходимо в сниппет mFilter2 добавить модель extendResource (&loadModels), соединение с таблицей content_extend (&leftjoin) и выбрать нужные поля из таблицы (&select).
Не подскажите, как с помощью формы на странице, добавить запись в свою таблицу БД?
Т.е. таблицу сделал. Схему написал. С выводом вроде бы всё понятно. А вот как формой (php или formit) не соображу.
Кроме этого используя эту инструкцию, можно установить полям необходимый тип данных, в случае с TV это сделать нельзя, их значение всегда имеет тип mediumtext. А это создаёт трудности для фильтрации и сортировки.
depth, width, length, grid.
Но по аналогии с вашим кодом у меня не заработало, но в результате разбирательств у меня корректно заработал такой код:
В админке дополнительные поля не отображаются. В журнале ошибок пусто.
Похоже вот это не работает, хотя плагин отрабатывает.
Спасибо.
Для разделения значений поля width использовать 2 вертикальные линии.
Например:
После этого создать сниппет outputList, чанки tplOuterList и tplInnerList.
Сниппет outputList:
Чанк tplOuterList:
Чанк tplInnerList:
Использование сниппета outputList в шаблоне или чанке:
Поле views (количество просмотров) — будет подсчитывать количество просмотров или надо ещё спец.компоненты устанавливать?
Поле level (минимальный уровень доступа к ресурсу) — для чего используется?
Эту инструкцию можно использовать в качестве примера. Например, если вы будете создавать сайт по сдачи квартир, то вам понадобится добавить к ресурсу следующие поля: адрес квартиры, площадь, этаж, цена, состояние, и т.д. Если вы будете это делать с помощью TV, то это приведёт не только к большему количеству запросов при выборе нужных данных, но и к сложностям их фильтрации.