Поступил тут один вопрос, который я хотел бы разобрать в паблике поподробней (к слову: задавайте такие вопросы не в личку, а в паблик. Ничего зазорного здесь нет, а материал будет полезен и другим).
Вопрос и ответ под катом.
Вопрос:
Пытаюсь разобраться с написанием процессоров для использования с modxsmarty, че-то не клеится. Взял Ваш getList шаблон из shopmodx (ShopmodxWebGetlistProcessor), немного его модифицировал:
class SiteNewsGetlistProcessor extends modObjectGetListProcessor { public $classKey = 'modResource'; public $defaultSortField = 'publishedon'; public $defaultSortDirection = 'DESC'; public $objectType = 'modResource'; protected $total = 0; public function prepareQueryBeforeCount(xPDOQuery $c) { $p=0; if(isset($scriptProperties['parent'])) $p=$scriptProperties['parent']; $c->where(array( 'parent' => $p )); $c->limit(8); return $c; } . . .
Дальше все как у Вас. В консоли отрабатывается, получаю ресурсы, но процессор не видит передаваемый параметр parent:
<?php $ns=$modx->getObject('modNamespace','site'); $p=$ns->getCorePath(); $response=$modx->runProcessor('getnews', array('parent'=>4,),array('processors_path'=>$p)); print_r($response->getResponse());
выдает результат с $p=0. Это первая проблема. А вторая — вызываю процессор в smarty:
{processor action="getnews" ns="site" assign=result} <ul class="carousel2"> {if $result.success} {foreach $object.object as $object} {include file="news.tpl"} {/foreach} {else} <li> <strong>error {$result.success}</strong> </li> {/if}
Выводится «error» Если вместо error {$result.success} пишу error {$result}, то выводит «error Array». Насколько я понимаю, smarty почему-то не видит элементы массива (например $result.success).
И подскажите пожалуйста, как я могу разрешить исполнение блоков {php} в modxsmarty?
Ответы:
1. Следите за переменными. Переменные просто так ни от куда не берутся. Вот кусочек кода:
public function prepareQueryBeforeCount(xPDOQuery $c) { $p=0; if(isset($scriptProperties['parent']))
А откуда здесь взялась переменная $scriptProperties? Ее здесь нет. Это раньше (в неклассовых процессорах) была переменная $scriptProperties. Но она создавалась MODX-ом в функции $modx->runProcessor(), то есть передавалась дальше в процессор. А в классных процессорах этого нет. Все параметры процессора находятся в элементе array $this->properties, и для работы с этой переменной есть методы $this->getProperties(), $this->getProperty(), $this->stProperties() и $this->setProperty();
Вот если бы создали эту переменную вот так, то у вас бы все заработало:
public function prepareQueryBeforeCount(xPDOQuery $c) { $p=0; $scriptProperties = $this->getProperties(); if(isset($scriptProperties['parent']))
Но это не по фэн-шую. Правильно использовать методы по умолчанию. К примеру так:
public function prepareQueryBeforeCount(xPDOQuery $c) { // Второй параметр 0 - это значение по умолчанию $p = $this->getProperty('parent', 0); $c->where(array( 'parent' => $p )); $c->limit(8); return $c; } . . .
А еще правильней делать вот так:
// Эта функция вызывается в первых рядах запуска процессора public function initialize(){ // Устанавливаем значения по умолчанию // Не перетирает уже имеющиеся свойства $this->setDefaultProperties(array( 'parent' => 0, )); return parent::initialize(); } public function prepareQueryBeforeCount(xPDOQuery $c) { $c->where(array( 'parent' => $this->getProperty('parent'), )); $c->limit(8); return $c; } . . .
Вот так у вас и важные переменные сразу будет видно, и дефолтовые значения указаны, и их можно будет перегрузить как на уровне входящих параметров, так и на уровне расширяющих процессоров.
2. Тоже следите за переменными:
{processor action="getnews" ns="site" assign=result} <ul class="carousel2"> {if $result.success} {foreach $object.object as $object} {include file="news.tpl"} {/foreach} {else} <li> <strong>error {$result.success}</strong> </li> {/if}
Присваиваете переменной result (assign=result), а пытаетесь использовать переменную $object ({foreach $object.object as $object})
В данном случае правильно {foreach $result.object as $object}.
Ответ 3.
И подскажите пожалуйста, как я могу разрешить исполнение блоков {php} в modxsmarty?
Это не зависит уже от самого modxSmarty. Это же все на совести Smarty, так что все должно работать (читайте манны Smarty).
UPD:
Выводится «error» Если вместо error {$result.success} пишу error {$result}, то выводит «error Array».
$result.success — это логическое. Оно возвращает только true или false (если никто не будет нарушать стандарта). Логическое true просто так в виде текста не выводится. А {$result} — это равносильно print $array. print не выводит содержимого массива, а просто пишет, что это массив (array).
Если хотите четко видеть какой ответ возвращается, то выводите весь ответ так:
<pre> {print_r($result)} </pre>
Интересный взгляд Евгения aka Agel_Nash на развивающийся рынок MODX-репозиториев.
Так как все больше программистов пытаются взять на вооружение объявленную технологию, и методика боле менее обкаталась и приняла четкие очертания, пишу пошаговую инструкцию как и с чего начать.
Весь процесс я заснял и выкладываю в виде подробного часового ролика. Но кому лень смотреть, или формат не удобный/скучный, расписываю здесь пошаговую инструкцию.
1. Устанавливаем чистую MODX Revolution.
2. Добавляем новый источник пакетов. Как минимум пакет modxSite не лежит в официальном репозитории modx.com, по этому его предстоит скачать с https://rest.modxstore.ru/extras/.
?
3. Устанавливаем пакеты:
  • Ace
  • modxSDK
  • modxSmarty
  • shopModx (из него нам понадобятся только процессоры для выборки документов)
  • phpTemplates
  • Console
  • getPage
4. Создаем базовый контроллер. Для этого создаем статический MODX-шаблон. Файл шаблона должен иметь расширение .php (к примеру, base.php) и запишем в шаблон следующий код:
<?php // Получаем свойства текущего MODX-шаблона $properties = $modx->resource->getOne('Template')->getProperties(); // Если в настройках шаблона не указано название файла-шаблона, // то используем по умолчанию index.tpl if(!empty($properties['tpl'])){ $tpl = $properties['tpl']; } else{ $tpl = 'index.tpl'; } // Если документ не кешируемый, то отключаем кеширование Smarty // (кеширование Smarty включается/выключается в настройках modxSmarty. По умолчанию отключено). if ($modx->resource->cacheable != '1') { $modx->smarty->caching = false; } // Отрабатываем Smarty-шаблон и возвращаем результат return $modx->smarty->fetch("tpl/{$tpl}");

Таким образом мы получим универсальный контроллер, и в дальнейшем на большинство шаблонов его будет вполне достаточно. И если вам надо создать новый MODX-шаблон просто с целью привязать новые TV-параметры, вы также указываете этот статический файл base.php в качестве источника кода для шаблона, и ничего дополнительно делать не придется. А если надо будет и отображение изменить (конечный шаблон), то просто в свойствах MODX-шаблона указываете новую настройку tpl сназванием файла-шаблона. (Если здесь не понятно, лучше посмотреть видео).
По поводу кеширования MODX-шаблонов: если у шаблона нет настройки phptemplates.non-cached=true, то при повторном заходе на страницу шаблон не будет опять обрабатываться, а просто будет отдаваться код из кеша страницы. Если надо отключить кеширование шаблона, то просто в шаблоне создаем такую настройку, и устанавливаем в true. А иначе придется после каждого изменения в коде шаблона сбрасывать кеш сайта (то есть это как правило надо на время программинга или отладки).
?
Важно создать плагин на событие OnHandlerRequest, но с рангом очередности выше плагина modxSmarty. Это чтобы в Smarty-шаблонах переменная $template_url формировала путь к папке публичной части шаблона.
<?php switch($modx->event->name){ case 'OnHandleRequest': if($modx->context->key == 'mgr'){ return; } //URL к файлам шаблона (css, js, images etc.) $modx->smarty->assign('template_url', $modx->getOption('modxSite.template_url').$modx->getOption('modxSmarty.template').'/'); break; }
Код вызова процессора через консоль (может использоваться в сниппетах и плагинах):
<?php print '<pre>'; $modx->setLogLevel(3); $namespace = 'shopmodx'; if(!$response = $modx->runProcessor('web/getdata', array( // Параметры ), array( 'processors_path' => $modx->getObject('modNamespace', $namespace)->getCorePath().'processors/', ))){ print "Не удалось выполнить процессор"; return; } print_r($response->getResponse());
Код общего процессора для выборки документов с условиями, расширяющего базовый процессор из shopModx-а.
<?php require_once MODX_CORE_PATH .'components/shopmodx/processors/web/getdata.class.php'; class modWebGetdataProcessor extends ShopmodxWebGetDataProcessor{ public function initialize(){ $this->setDefaultProperties(array( 'sort' => "{$this->classKey}.menuindex", 'dir' => 'ASC', 'showhidden' => false, 'showunpublished' => false, 'getPage' => false, 'limit' => 10, 'page' => !empty($_REQUEST['page']) ? (int)$_REQUEST['page'] : 0 )); if($page = $this->getProperty('page') AND $page > 1 AND $limit = $this->getProperty('limit', 0)){ $this->setProperty('start', ($page-1) * $limit); } return parent::initialize(); } public function prepareQueryBeforeCount(xPDOQuery $c) { $c = parent::prepareQueryBeforeCount($c); $where = array( 'deleted' => false, ); if(!$this->getProperty('showhidden', false)){ $where['hidemenu'] = 0; } if(!$this->getProperty('showunpublished', false)){ $where['published'] = 1; } $c->where($where); return $c; } public function outputArray(array $array, $count = false) { if($this->getProperty('getPage') AND $limit = $this->getProperty('limit')){ $this->modx->setPlaceholder('total', $count); $this->modx->runSnippet('getPage@getPage', array( 'limit' => $limit, )); } return parent::outputArray($array, $count); } } return 'modWebGetdataProcessor';
P.S. Здесь очень сложно расписать все, так что кому интересно, все-таки сделайте усилие и посмотрите видеоролик. Там основное рассказано и показано в первые 30 минут. Вторая часть ролика может и очень нудная, но там есть неплохие примеры по использованию всего этого дела. И не стесняйтесь, задавайте вопросы.
Ребята реально классно делают! Сделали нам для одного проекта довольно много 3D-объектов. На выходных выложу их на сайте и напишу топик.
Предлагаем Вашему вниманию услуги 3D-фотосъемки для онлайн-каталогов!
Съемка предметов с круговым обзором в 360 градусов – новая технология современной цифровой фотографии. 3D-панорама — новшество современной цифровой фотографии, она позволяет воссоздать трехмерное изображение предмета без дорогостоящей отрисовки в 3DMax. 3D-съемка позволяет рассмотреть товар со всех сторон и получить о нем полное представление еще до покупки. Потрясающая объемная картинка создает иллюзию того, что этот предмет вы держите в руках. Ваши клиенты почувствуют себя в магазине, не выходя из дома.
Фотосъемка 2-х предметов бесплатно!!! Мы сделаем для вас фотографии желаемого формата и размера без предоплаты: — если качество работ вам не понравится — вы ничего не оплачиваете;
Образцы работ можете посмотреть на нашем сайте: 360-view.ru/index.php/krugovaya-s-emka/3d-foto
E-mail: studio-360@yandex.ru Тел.: 8 (495) 722-48-45 www.360-view.ru
Пожалуйста :-)
Спасибо! в SDK работать гораздо гораздее! )
Добрый день! Вот незадача… Писал коммент еще ночью, но почему-то его здесь нет.
Проблема однозначная: у вас включено сжатие JS в админке. Пока это не победил (некогда было колупаться), так что пока просто отключаете сжатие JS, перегружаете страницу, и все будет работать.
Добрый день. Очень впечатлился модулями modxSmarty, phpTemplates и modxSDK. Скачал, установил, радуюсь. Круто все. Как я люблю. Николай, спасибо за них огромное!!!
Но возникла одна проблемка: в редакторе среды SDK я не могу ввести пробел, только TAB, и тогда добавляется либо 4 пробела, либо TAB и несколько пробелов. И если я захожу на уже написанную строку, то при нажатии backspace удаляется символ не перед курсором, а на 2 символа левее. И если открываю при открытом SDK окно документа, то поле контента выводится очень маленьким (около 10х10 символов)
Стоит MODX 2.2.8-pl, последние пакеты. На компе установлен PuntoSwitcher, но в остальных окнах MODX он не мешает.
Может, сталкивался кто с таким?
Ничего страшного.