Давно подумывал о замене стандартных компонентов breadcrumbs, процессоры MODX привлекают меня гораздо больше, да и когда работаешь в одном окружении (smarty), необходимость переключаться на другой синтаксис слегка нервирует. И вот это случилось. Представляю на ваш суд процессор для вывода цепочки родителей.
Процессор breadcrumbs.class.php я кинул в папку (modxsite)site/web <?php
class modSiteWebBreadcrumbsProcessor extends modProcessor{
public function initialize(){
$this->setDefaultProperties(array(
'startId' => 0,
'excludeDocs' => array(),
'showHidden' => true,
'showUnpub' => false,
'showDeleted' => false
));
return parent::initialize();
}
public function process() {
$bc_path = array();
$resource = $this->modx->resource;
//стоим в голове, нечего выводить
if($resource->get('id')==$this->getProperty('startId')){
return array(
'success' => true,
'message' => '',
'object' => array()
);
}
//соберем цепочку родителей
$r=$resource->toArray();
unset($r['content']);
$bc_path[]=$r;
while($resource = $resource->getOne('Parent')) {
if (in_array($resource->id, $this->getProperty('excludeDocs'))
|| !$this->getProperty('showHidden') && $resource->hidemenu
|| !$this->getProperty('showUnpub') && !$resource->published
|| !$this->getProperty('showDeleted') && $resource->deleted
){
continue;
}
$r=$resource->toArray();
unset($r['content']);
array_unshift($bc_path,$r);
if($resource->id==$this->getProperty('startId'))
break;
}
return array(
'success' => true,
'message' => '',
'object' => $bc_path,
);
}
} return 'modSiteWebBreadcrumbsProcessor'; для вывода использовал шаблон {$params=['startId'=>37]} {* это голова нужной ветки *} {processor action='site/web/breadcrumbs' ns=modxsite params=$params assign=result}
<div class="breadcrumbs"> {$total = count($result['object'])} {$counter = 0} {foreach $result.object as $object} {$counter=$counter+1} {if $counter<$total} <span itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb"> <a itemprop="url" rel="{$object.pagetitle}" href="{$object.uri}"> <span itemprop="title">{$object.pagetitle}</span></a></span> / {else} <span itemscope="itemscope">{$object.pagetitle}</span> {/if} {/foreach} </div> Буду благодарен любым советам по доработке.Саша, привет! Прежде всего: не стоит использовать для этого getdata-процессор, правильней просто расширить modProcessor и написать свой метод process. 2. Сорри, что докапываюсь до синтаксиса, но $modx=$this->modx; $resource = $modx->resource; Просто чтобы один раз вызвать $modx, создавать для нее переменную? Чем не нравится просто $this->modx? И, хотя это объекты и все равно между ними будут ссылки, но все-таки хотя бы для наглядности не забываем про амперсанты. $modx = & $this->modx; $resource = & $modx->resource; 3. Посмотри микроразметку, которую формирует родной Breadcrumbs, там не все так просто. Есть стандарты, и лучше их придерживаться, а то СЕОшники помидорами закидают.
$modx=$this->modx; $resource = $modx->resource; исправил, но при добавлении ссылки $modx= & $this->modx->resource; перестает выводиться сам ресурс (пустой контент) Посмотри микроразметку спасибо за информацию, сейчас посмотрю
перестает выводиться сам ресурс (пустой контент) Кстати да :) Ведь ты ниже перетираешь в цикле переменную $resource :) Поэтому $modx = & $this->modx — оправдано, а вот с $resource здесь не оправдано. Но где логика позволяет, лучше конечно использовать, так как нагрузку снижает, не делает копию инстанса.
Подправил разметку.
ОК. Ты бы это сразу куда-нибудь на гист выложил, чтобы всегда актуальный код был и можно было ПРы слать.
Выложил: gist.github.com/Tramp1357/cc2334428add09fc4d05
Круть! При случае обязательно погоняю. Но процессор все равно подумай на счет перевода на обычный modProcessor.
подумай на счет перевода на обычный modProcessor Да я так и думал сначала, но потом решил, что зачем велосипед изобретать — есть процессор, который собирает все данные ресурсов. Кто знает — может, понадобится когда картинками из TV крошки отрисовать? :)
getdata-процессор рассчитан только на выборку документов за раз, он не рассчитан на выборку внутри него циклами. То есть его общий механизм тут не применим, а вставить список id-шников в prepareQueryBeforeCount здесь не годится, так как в какой-то момент ты получишь не тот результат просто из-за сортировки. Ты же не можешь гарантировать, что крошки все будут иметь id по порядку, или заголовки или типа того. Тебе надо просто получить их данные в цикле и набить в массив, и это делается за раз в одной функции. И тв-шки добавить не сложно.
получишь не тот результат просто из-за сортировки ну, для этого я и переопределил afterIteration. Возможно, и кривовато, но данных немного… А в целом я согласен, переделаю. Просто это-первое, что пришло в голову :)
переделал процессор. Действительно проще получилось :)
Вот видишь :) Я переписал немного твой код (к слову, сорри за микс табов и пробелов) gist.github.com/Fi1osof/c2087b988a679bd699c3 Глянь, наверняка мысли мои уловишь.
Да, так лучше и нагляднее. Я пока такие мелочи упускаю. Но в любом случае, думаю, польза от него будет. По крайней мере, вывод теперь полностью под контролем :)
Все так :)