Решил поделить совсем простым решением для обеих версий Modx, которое использую практически на каждом проекте. Проблема в том, что регулярно возникает необходимость вывода различных блоков информации в тех или иных местах макета, а создавать отдельный шаблон для этого не хочется, так как работать с большим количеством шаблонов более времязатратно.
Начну с простого, как вывести какую-то информацию в зависимости от текущего id документа, например 12. Для этого надо воспользоваться PHx или его аналогом в MODX Revolution, в зависимости от версии CMS/CMF.
# код для Evolution [*id:is=`12`:then=`Вывод какой-то информации`*] # код для Revolution [[*id:is=`12`:then=`Вывод какой-то информации`]]
, при этом в качестве id может выступать любой параметр документа, включая TV. Вооружившись этим знанием мы можем создать шаблон, в котором соседние документы будут показываться только в потомках основного документа. Для этого достаточно создать единый шаблон и прописать следующий код:
# код для Evolution [*isfolder:is=`0`:then=`[[PrevJumpNext]]`*] # код для Revolution [[*isfolder:isnot=`1`: then=`[[pdoNeighbors]]`]]
Здесь все просто. Мы проверяем, является ли данный документ контейнером, ведь родительский документ всегда будет контейнером, и если не является, то показываем сниппет выводящий соседние документы.
Часть 5 — Интернет-магазин на MODx Revo. Вывод статей (ресурсов) в MODx Revo.
А еще проверяемые параметры можно группировать, например:
# код для Evolution [*parent:is=`0`:or:is=`8`:then=`Вывод какой-то информации`*] # код для Revolution [[*parent:is=`0`:or:is=`8`:then=`Вывод какой-то информации`]]
, здесь информация будет показываться только в тех документах, родителями которых является документ с id 0, т.е. корневой документ, и документ с id 8.
В общем используя данное решение, можно легко показывать нужные нам блоки на разных документах, при этом не создавая большого количества шаблонов под эти нужды.
Источник: www.devmarks.ru
Упрощаем работу с TV
Продолжая тему, начатую Василием, предлагаю решение для упрощения работы с TV. Оно поможет тем, у кого логика сайта завязана на TV — запросы, фильтры и т.п. Решается эта задача созданием полей в таблице ресурсов и копированием в них значений TV.
Покажу на своем примере.
- Создаем TV «tv.action», которая будет признаком, что ресурс акционный. Это нужно для выборки только тех ресурсов, которые участвуют в акции. 1 — участвует, 0 — нет. Обратите внимание на префикс.
- В таблице modx_site_content создаем поле «action». Удобнее всего через phpMyAdmin.
Тип: tinyint Длина: 1 Значение по-умолчанию: 0 Атрибуты: UNSIGNED
event->name) { case ‘OnMODXInit’: // Загружаем наше поле в модель ресурса $modx->loadClass(‘modResource’); $modx->map[‘modResource’][‘fields’][‘action’] = 0; $modx->map[‘modResource’][‘fieldMeta’][‘action’] = array( ‘dbtype’ => ‘tinyint’, ‘precision’ => 1, ‘attributes’ => ‘unsigned’, ‘phptype’ => ‘integer’, ‘null’ => false, ‘default’ => 0, ); break; case ‘OnDocFormSave’: // Сохраняем ТВ в поле таблицы ресурса $resource->set(‘action’, $resource->getTVValue(‘tv.action’)); $resource->save(); break; }
Не забываем отметить нужные события.
Как сменить шаблон в ModX Evo? #2 урок
[[!pdoResources? where=`{«action»:»1″}` depth=`0` ]]
и получаем все ресурсы, для которых установлен признак акции. И никакой мороки с значениями по умолчанию, джойнами и т.п. Сложные типы TV-шек не тестировал, но думаю должно работать. Для тех, у кого много TV, скорость запросов должна заметно вырасти.
Было бы интересно узнать результаты до и после.
В результате ТВ-шки работают как обычно, а вот запросы значительно упростились, так как они теперь работают только с одной таблицей. И на странице можно указывать тег с именем добавленного поля ( [[*action]] ), парсер обработает его быстрее, так как он не будет делать дополнительный запрос к таблице ТВ-шек. Вот такой велосипед получился.
Важно!
Имя ТВ и поля должны отличаться! В противном случае, при использовании TV на странице сайта значение поля будет некорректным. Можно добавить префикс «tv» к имени ТВ-шки.
Причина в том, что в классе modRequest в 247 строчке подгружаются ТВ-шки и затирают значение поля. Выход нашел пока только один — ТВ-шкам давать префикс. Например, создаем ТВ «tv.action», а поле для нее создаем «action».
Тогда в плагине нужно писать так
$resource->set(‘action’, $resource->getTVValue(‘tv.action’));
Рекомендация!
MODx Revo API (xpdo)
Небольшое описание, о том как пользоваться modx revo api
8358 23 August 2016 1 документация, modx revo, xPDO
Текущий ресурс / Текущий пользователь
$currentResource = $modx->resource; $currentUser = $modx->user;
Если пользователь не залогинен в контексте, имя пользователя будет ‘(anonymous)’.
Поля для каждого объекта доступны через метод get(). getContent() для содержания (контента) ресурса.
$intro = $modx->resource->get(‘introtext’); $UserID = $modx->user->get(‘id’); $content = $modx->resource->getContent();
Ищем другие объекты.
$resource = $modx->getObject(‘modResource’, $id);
Ссылки на все объекты MODx можно получить с помощью метода $modx->getObject().
$object = $modx->getObject(‘object-class-name’, array(‘name’ => ‘object-name’ ));
$object = $modx->getObject(‘object-class-name’, $object-id);
Получить ссылку на чанк по имени.
$chunk = $modx->getObject(‘modChunk’,array(‘name’ => ‘chunkName’ ));
Получить ссылку на чанк по id.
$chunk = $modx->getObject(‘modChunk’,$chunkId);
Получить опубликованный ресурс по имени (pagetitle).
$document = $modx->getObject(‘modResource’,array( ‘published’ => 1, ‘pagetitle’ => ‘Джузеппе’ ));
$name = ‘modResource’; $criteria = array( ‘published’ => 1, ‘pagetitle’ => ‘Джузеппе’ ) $document = $modx->getObject($name,$criteria);
Для получения массива документов, отвечающих вашим критериям, вы можете использовать getCollection() вместо getObject().
Такой пример выведет все опубликованные и доступные для поиска ресурсы.
$docArray = $modx->getCollection(‘modResource’,array( ‘published’ => 1, ‘searchable’ => 1 ));
Еще getCollection() не возвращает массив PHP а возвращяет массив объектов. Получить массив PHP, можно с помощью метода объекта toArray().
$phpArray = $object->toArray();
Если вы хотите получить несколько соответствующих объектов, связанных с одним объектом, вы можете использовать метод объекта getMany(). Предполагая, что вы использовали getObject(), чтобы получить ссылку на ресурс или шаблона, вы можете получить связанные с ними TV как показано здесь:
$tvs = $template->resource->getMany(‘TemplateVars’);
Чтобы получить дочерние ресурсы:
$children = $resource->getMany(‘Children’);
getObject() и getOne() возвращают ноль, если запрашиваемый объект не найден, а getMany() и getCollection() возвращает пустой массив, если нет результатов приведенным критериям.
Все отдельные ресурсы (документ, гиперссылки, символические ссылки и статические ресурсы) могут быть получены с помощью:
$modx->getObject(‘modResource’,$criteria);
И по отдельности.
$modx->getObject(‘modDocument’,$criteria); $modx->getObject(‘modWeblink’,$criteria); $modx->getObject(‘modSymlink’,$criteria); $modx->getObject(‘modStaticResource’,$criteria);
Отдельные элементы (чанки, сниппеты, плагины, шаблоны, TV переменные и категории) с использованием ключа объекта желаемого класса.
$modx->getObject(‘modChunk’,$criteria); $modx->getObject(‘modSnippet’,$criteria); $modx->getObject(‘modPlugin’,$criteria); $modx->getObject(‘modTemplate’,$criteria); $modx->getObject(‘modTemplateVar’,$criteria); $modx->getObject(‘modCategory’,$criteria);
Системные настройки
$modx->getOption(‘site_name’);
Получение поля объекта с помощью $object->get()
После того как вы получили объект с помощью getObject(), getCollection(), или getMany(), вы можете использовать с $object->get() для получения любого поля объекта по названию.
$resource = $modx->getObject(‘modResource’,1); $pagetitle = $resource->get(‘pagetitle’); $longtitle = $resource->get(‘longtitle’); $id = $resource->get(‘id’); .
Связи $object->getOne() и $object->getMany() с объектами.
Чтобы получить родительский ресурс как объект MODx.
$parentRes = $resource->getOne(‘Parent’);
Получения пользователем объекта пользователя, который создал ресурс.
$user = $resource->getOne(‘CreatedBy’);
Объект пользователя содержит только ID, имя пользователя и хэш пароля пользователя. Чтобы получить больше, вам нужно получить объект modUserProfile, связанный с этим пользователем.
$user->getOne(‘Profile’);
Выпихнуть поля можно так.
$profile->get(‘fullname’); $profile->get(‘website’); .
ТВшки (Template Variables)
Получение обработанного значение TV текущего документа.
$modx->resource->getTVValue(‘image’);
$modx->resource->getTVValue($id); // Указываем id TV
Или получить значение TV по pagetitle нужного нам ресурса.
Такой код выведет значение image ресурса со значением pagetitle = Джузеппе.
$resource = $modx->getObject(‘modResource’,array( ‘pagetitle’=>’Джузеппе’ )); $val = $resource->getTVValue(‘image’);
// id ресурса из которого получим TV $id = ’17’; // какое TV $tv = $modx->getObject(‘modTemplateVar’, array( ‘name’=>’image’ )); // получаем значение TV ресурса. $value = $tv->getValue($id); // Обрабатываем TV и получачем что хотели. $processed = $tv->renderOutput($id);
Изменение объектов
После получения ссылки на объект с помощью $modx->getObject(), вы можете изменить значение ее поля.
$resource = $modx->getObject(‘modResource’, ‘1’); $resource->set(‘pagetitle’, ‘Джузеппе’); $resource->save(); // теперь у ресурса с id 1 значение поля pagetitle = Джузеппе
$object->setContent(‘Джузеппе’); $object->save();
Создание нового объекта
$object = $modx->newObject(‘modChunk’); $object->set(‘name’, ‘juzeppe’); $object->setContent(‘Тут у нас Джузеппе.’); $object->set(‘description’, ‘Эт я’); $object->save(); // теперь у нас есть чанк «juzeppe» с контентом «Тут у нас Джузеппе.» и описанием «Эт я»
Общие объекты и некоторые их свойства.
Вот список наиболее часто используемых объектов с их имена классов и имена некоторых из своих полей и типов. Связанных объектов, доступных с getOne() и getMany() приведены ниже поля для каждого объекта.
modResource
- id (int — идентификатор ресурса)
- pagetitle (text)
- isfolder (int 0/1)
- longtitle (text)
- description (text)
- alias (text)
- published (int 0/1)
- introtext (text — оно же Аннотация)
- content (text)
- template (int — id идентификатор шаблона)
- menuindex (int)
- searchable (int 0/1)
- cacheable (int 0/1)
- createdby (int — id идентификатор пользователя)
- editedby (int — id идентификатор пользователя)
- deleted (int 0/1)
- deletedby (int — id идентификатор пользователя)
- publishedby (int — id идентификатор пользователя)
- createdon (date — дата первого сохранения)
- publishedon (date — дата публикации последнего изменения)
- editedon (date — дата редактирования его в последний раз)
- menutitle (text)
- donthit (int 0/1) (устарел)
- haskeywords (int 0/1) (устарел)
- hasmetatags (int 0/1) (устарел)
- hidemenu (int 0/1)
Связанные объекты доступны getOne()
Связанные объекты доступны в getMany()
- Children (class = «modResource»)
- TemplateVars (class = «modTemplateVar»)
- TemplateVarTemplates (class = «modTemplateVarTemplate»)
modChunk
- name (text)
- description (text)
- category (int — category id number)
- snippet (text — chunk’s contents)
- locked (int 0/1- то есть заблокирован для редактирования)
Связанные объекты доступны getOne()
- Category (class = «modCategory»)
Связанные объекты доступны в getMany()
- PropertySets (class = «modElementPropertySet»)
modSnippet
- name (text)
- description (text)
- category (int — category id number)
- snippet (text — snippet’s contents)
- locked (int 0/1 — AKA locked for editing)
- properties (text)
Связанные объекты доступны getOne()
- Category (class = «modCategory»)
Связанные объекты доступны в getMany()
- PropertySets (class = «modElementPropertySet»)
modPlugin
- name (text)
- description (text)
- category (int — category id number)
- plugincode (text — plugin’s contents)
- locked (int 0/1 — AKA locked for editing)
- properties (text)
- disabled (int 0/1)
Связанные объекты доступны getOne()
- Category (class = «modCategory»)
Связанные объекты доступны в getMany()
- PropertySets (class = «modElementPropertySet»)
modTemplate
- templatename (text)
- description (text)
- category (int — category id number)
- content (text)
- icon (text)
- locked (int 0/1)
Связанные объекты доступны getOne()
- Category (class = «modCategory»)
Связанные объекты доступны в getMany()
- PropertySets (класс = «modElementPropertySet»)
- TemplateVarTemplates (класс = «modTemplateVarTemplate»)
modTemplateVar
- type (text)
- name (text)
- caption (text)
- description (text)
- category (int — category id)
- locked (int 0/1)
- elements (text)
- rank (int)
- display (text)
- display_params (text)
- default_text (text)
Связанные объекты доступны getOne()
- Category (class = «modCategory»)
Связанные объекты доступны в getMany()
- PropertySets (class = «modElementPropertySet»)
- TemplateVarTemplates (class = «modTemplateVarTemplate»)
- TemplateVarResources (class = «modTemplateVarResource»)
- TemplateVarResourceGroups (class = «modTemplateVarResourceGroup»)
modUser
- username (text)
- password (text)
- cachepwd (text)
Связанные объекты доступны getOne()
- Profile» (class = «modUser»)
Связанные объекты доступны в getMany()
modUserProfile
- fullname (text)
- role (int)
- email (text)
- phone (text)
- mobilephone (text)
- blocked (int 0/1)
- blockeduntil (int — date)
- blockedafter (int — date)
- logincount (int)
- lastlogin (int — date)
- thislogin (int — date)
- failedlogincount (int)
- sessionid (text)
- dob (int — date)
- gender (int 0/1)
- country (text)
- state (text)
- zip (text)
- fax (text)
- photo (text)
- comment (text)
Связанные объекты доступны getOne()
- User (class = «modUser»)
- UserRole (class = «modUserRole»)
Источник: pitrooo.ru