8. Ext JS - Внутри CMP
Последнее обновление Dec 5th, 2019 | История страницы | Улучшить эту страницу | Сообщить о проблеме
Support the team building MODX with a monthly donation.
The budget raised through OpenCollective is transparent, including payouts, and any contributor can apply to be paid for their work on MODX.
Backers
Budget
$301 per month—let's make that $500!
Learn moreЗдесь мы совершаем переход от автономного Ext JS к MODX. Многие вещи одинаковы, но, к сожалению, кривая обучения все еще растет. Нашей первой будет как можно более простая задача: мы собираемся создать страницу настраиваемого менеджера, в которой перечислены типы контента. Да, это то, что MODX уже делает в Система -> Типы содержимого, но в этом суть: мы хотим попробовать свои силы в воссоздании того, что MODX уже предоставляет.
Вот скриншот встроенной сетки, отображающей типы контента. Вот что мы собираемся воссоздать в нашем собственном CMP:
Ориентируя себя¶
Предыдущие уроки здесь были просты в том смысле, что они ставили все перед вами: вы должны были включить файлы JavaScript и CSS Ext JS, но помимо этого, это был просто вопрос манипулирования JavaScript. Однако, как только мы перейдем к менеджеру MODX, все может стать более сложным. Вещи немного скрыты в различных папках и файлах классов PHP. А также у нас есть дополнительная проблема, связанная с разрешениями пользователей. Итак, давайте сделаем глубокий вдох и рассмотрим, что мы видим внутри менеджера.
Менеджер¶
Менеджер MODX действует как автономное приложение. Большинство файлов, с которыми мы будем иметь дело, находятся в следующих местах:
-
manager/assets/modext
: дом для различных конфигураций Ext JS, панелей, виджетов и т. д. -
manager/controllers/
: дом для PHP кода, который загружает Ext JS вещи. JS указывает на коннектор. -
connectors/
: К счастью, это гнездо файлов исчезает в MODX 2.3, но в MODX 2.2 и ранее коннекторы просто указывают на процессор. -
core/model/modx/processors/
: обрабатывает выборку данных -
core/model/modx/modmanagerrequest.class.php
: отвечает за обработку всех запросов в менеджере -
core/model/modx/modprocessor.class.php
: отвечает за фактическое получение данных.
Вы еще не запутались? Я - да, и поэтому пишу эти глупости. Таким образом, диспетчеры менеджеров сбивают с толку, они плохо документированы, и они изменятся в следующей версии, поэтому то, что я собираюсь предложить, возможно, немного неортодоксально, но за ним чертовски легко следовать.
Ну, держитесь! Поскольку контроллеры менеджера MODX добавляют дополнительный уровень сложности, и они плохо документированы, я собираюсь пропустить их для этой демонстрации.
Контроллер Ajax¶
Ваши контроллеры Ajax должны быть доступны через HTTP, поэтому их типичное расположение будет внутри папки assets/
, а точнее, где-то внутри assets/components/<your_pkg>/
.
<?php
/**
* Контроллер для запросов Ajax.
*/
// Отрегулировать путь соответственно
$docroot = dirname(dirname(dirname(dirname(__FILE__))));
include $docroot . '/config.core.php';
if (!defined('MODX_API_MODE')) {
define('MODX_API_MODE', false);
}
include_once MODX_CORE_PATH . 'model/modx/modx.class.php';
$modx = new modX();
$modx->initialize('mgr');
if (!$modx->hasPermission('view_document')) {
header('HTTP/1.0 401 Unauthorized');
print 'Операция не разрешена.';
exit;
}
// Следующие значения стандартны для Ajax URL в Ext JS
$start = (int) $modx->getOption('start',$_POST,0);
$limit = (int) $modx->getOption('limit',$_POST,20);
$sort = $modx->getOption('sort',$_POST);
$dir = $modx->getOption('dir',$_POST,'ASC');
// error_log(print_r($_POST,true)); // <--- раскомментируйте эту строку для отладки
$c = $modx->newQuery('modResource');
$count = $modx->getCount('modResource',$c);
$c->sortby($sort,$dir);
$c->limit($limit,$start);
//$c->prepare(); error_log($c->toSQL()); // <-- раскомментируйте эту строку для отладки
$pages = $modx->getCollection('modResource',$c);
$list = array();
foreach ($pages as $p) {
$array = $p->toArray();
$list[] = $array;
}
// Формат вывода недостаточно хорошо документирован, однако он требует узел для "total" and "rows"
print '{"total":"'.$count.'","results":'.$modx->toJSON($list).',"success":true,"msg":"Got our rows..."}';
//error_log(print_r($list,true)); // <-- еще одна точка отладки
@session_write_close();
exit();
Вы это видите? После того, как мы создадим MODX и проверим права доступа, это по сути то же самое, что вы можете увидеть внутри сниппета. Подобные действия имеют несколько важных преимуществ:
Преимущества простых контроллеров¶
- Вы можете отладить вывод, посетив страницу напрямую, например, http://yoursite.com/assets/components/your_pkg/my_ajax_controller.php - вы должны увидеть данные JSON или, возможно, некоторые ошибки PHP.
- Проверка прав доступа проста, просто обновите
$modx->hasPermission('permission_key_here')
- Никакой дополнительной документации или сложности не требуется
Недостатки в том, что это не «официальный» способ (не знаю, где задокументирован «официальный» способ), поэтому вы не сможете воспользоваться маршрутизацией менеджера, а если вы захотите переопределить поведение собственного контроллера через тему менеджера MODX, вы не сможете это сделать, т.к. эта штука жестко запрограммирована. Поскольку этот способ намного проще, а другой не документирован, я считаю, что это достойный компромисс.
Ваш CMP¶
Следующий код вы можете вставить в вашу директорию core/components/<your_pkg_name/
и ссылаться на нее как на действие при создании CMP.
<?php
/**
* Обычный MODX CMP
*/
$url = MODX_ASSETS_URL.'components/your_pkg_name/'; // <-- update this
//------------------------------------------------------------------------------
//!Grid
//------------------------------------------------------------------------------
$modx->regClientStartupHTMLBlock("<script>
function myactions(val) {
return '<a href=\"index.php?a=30&id='+val+'\">Edit</a>';
}
Ext.onReady(function(){
// Создать хранилище данных
var store = new Ext.data.JsonStore({
root: 'results',
totalProperty: 'total',
idProperty: 'id',
remoteSort: true,
fields: [
'id',
'createdon',
'pagetitle',
'action'
],
// Загрузить, используя теги скрипта для кросс-доменного запроса; если данные находятся в том же домене, как
// данная страница, то использовать HttpProxy было бы лучше
proxy: new Ext.data.HttpProxy({
url: '{$url}getpages.php' // <------- Установите этот параметр с указанием на ваш контроллер Ajax
})
});
store.setDefaultSort('id', 'ASC');
var grid = new Ext.grid.GridPanel({
id: 'articlesGrid',
width:700,
height:500,
store: store,
trackMouseOver:true, // Подсветит строки при наведении курсора мыши
disableSelection:true, // Позволит вам выбрать строку(и)
loadMask: true, // Сгенерирует крутящуюся иконку
// Колонки сетки
columns:[{
header: 'Дата',
dataIndex: 'createdon',
width: 150,
sortable: true
},{
header: 'Заголовок страницы',
dataIndex: 'pagetitle',
width: 350,
sortable: true
},{
header: '',
dataIndex: 'id',
width: 100,
sortable: false,
renderer : myactions,
}],
// Панель постраничного разбиения внизу
bbar: new Ext.PagingToolbar({
pageSize: 25,
store: store,
displayInfo: true,
displayMsg: 'Отображаются записи {0} - {1} из {2}',
emptyMsg: "Нет записей для отображения"
})
});
// Отобразить сетку
grid.render('articles-grid');
// Запустить загрузку локального хранилища
// ПРИМЕЧАНИЕ: имена параметров здесь соответствуют ключам в массиве $_POST
store.load({params:{start:0, limit:25}});
});
</script>");
// Удостоверьтесь, что у вас в HTML добавлен тот же самый элемент div, который указан в методе grid.render()
return '
<h2>Пример</h2>
<div id="articles-grid"></div>';
Вы заметите, что мы печатаем наш JavaScript прямо в заголовок документа. Да, это означает, что мы должны быть очень осторожны с нашими стилями использования кавычек, а подсветка синтаксиса нашего редактора, вероятно, сходит с ума, но это означает, что мы можем напечатать несколько переменных PHP непосредственно в JavaScript, и нам не нужно хранить открытыми с полдюжины файлов только для загрузки этой штуки.
Обычно генерация JavaScript посредством PHP не очень хорошая идея - это то, что обычно осуждается, но это требуется в определенных точках интеграции. «Более правильный» способ сделать это - напечатать некоторые детали конфигурации в виде объектов JavaScript, а затем сослаться на переменные JavaScript в вашем коде. Мы продемонстрируем это позже - сейчас просто попробуйте обдумать, что происходит в коде.
Support the team building MODX with a monthly donation.
The budget raised through OpenCollective is transparent, including payouts, and any contributor can apply to be paid for their work on MODX.
Backers
Budget
$301 per month—let's make that $500!
Learn more