Николай Ланец
19 июля 2013 г., 20:22

Разбор нескольких типовых ошибок modxSmarty + процессоры.

Поступил тут один вопрос, который я хотел бы разобрать в паблике поподробней (к слову: задавайте такие вопросы не в личку, а в паблик. Ничего зазорного здесь нет, а материал будет полезен и другим).
Вопрос и ответ под катом.
Вопрос:
Пытаюсь разобраться с написанием процессоров для использования с 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>

Добавить комментарий