Кастомная галерея by Gallery

В продолжение темы работы с xPDO. Я уже довольно долго не использую стандартные сниппеты [[galAlbum]], [[galItem]] и т.п. Блин, реально все заморочено. А кастомный вывод какой-то сделать — это вообще высший пилотаж. Но компонент Gallery использую очень активно, чисто для управления галереями в админке, а вывод галерей пишу сам. Вот сегодня сделал очередную галерейку и хочу показать листинг сниппет. Итак, сниппет: <?php $output = '';

// Получаем все элементы $q = $modx->newQuery('galItem'); $q->join('galAlbumItem', 'AlbumItems'); $q->where(array( 'AlbumItems.album' => $album, )); if(!$items = $modx->getCollection('galItem', $q)){ return; }

// Регистрируем скрипты $assets_url = $modx->getOption('assets_url', null); $modx->regClientCSS("{$assets_url}js/lib/colorbox/style/1/colorbox.css"); $modx->regClientStartupScript("{$assets_url}js/lib/colorbox/jquery.colorbox-min.js"); $modx->regClientStartupScript("<script type="text/javascript"> $(document).ready(function(){ //Examples of how to assign the ColorBox event to elements $('.gallery').colorbox({ rel:'gallery' ,'current': '' }); });
</script>", true);

// Проходим по каждому элементу и набиваем в шаблоны $x = 0; $inRow = 3; $rowClass = "row flow"; $itemClass = "columns four";

$rowOutput = ''; foreach($items as $item){ $x++; // print_r($item->toArray());
$item = $modx->getChunk('SiteGalleryItemTpl', array( 'class' => $itemClass, 'title' => $item->get('name'), 'src' => $item->get('absoluteImage'), ));

$rowOutput  .= $item;

if($x == $inRow){
    $output .= $modx->getChunk('SiteGalleryRowTpl', array(
        'class'     => $rowClass,
        'wrapper'   => $rowOutput,
    ));
    $x = 0;
    $rowOutput = '';
}

}

return $output;

Чанк SiteGalleryRowTpl

<code><div class="[[+class]]">[[+wrapper]]</div> Чанк SiteGalleryItemTpl <div class="galItem [[+class]]"> <div class="title"><span>[[+title]]</span></div> <a href="[[+src]]" class="gallery" title="[[+title]]"> <img src="/assets/components/site_gallery/connector.php?action=web/image/gallery/small&src=[[+src]]"/> </a>

</div> Как видно, для кастомной галереи не нужно писать много кода.

Все понятно. Блин, хотелось бы все же с процессорами разобраться. По-моему, mgr/item/getlist в gallery меньше кода гоняет

Так кто мешает? Говорю же — перегрузи метод outputArray() и все.

вот что получилось: <?php require_once(MODX_CORE_PATH.'components/gallery/processors/mgr/item/getlist.class.php');

class modSiteGalleryProcessor extends GalleryItemGetListProcessor{

public function outputArray(array $array, $count = false){ return array( 'success' => true, 'message' => $this->getMessage(), 'count' => count($array), 'total' => $count, 'object' => $array, ); } } return 'modSiteGalleryProcessor'; вызываю из консоли <?php $response = $modx->runProcessor('gallery/getlist', array( 'album' => 1, ), array( 'processors_path' => $modx->getOption('core_path') . 'site/processors/' )); print_r($response->response); ничего не выдает, только Loading крутится. Что-то я еще не сделал?

  1. В начале кода в консоли пропиши ini_set('display_errors', 1); Чтобы php тебе выводил ошибки.
  2. Поставь FireBug или типа того, чтобы видеть Ajax-овые запросы и т.п.
  3. Ошибка у тебя 99,999% из-за $this->getMessage(). Это моя функция в моем процессоре, и в процессорах MODX-а ее нет. Поэтому у тебя скрипт и разваливается с критической ошибкой.

И еще: 'processors_path' => $modx->getOption('core_path'). 'site/processors/' А что это ты из core_path процессор пытаешься дернуть? У тебя по идее как минимум в core_path. components должно лежать. Пути в общем проверь.

Точно, исправил — заработало.

да просто в core положил папку site, где все процессоры и шаблоны. Не люблю слишком длинные пути.

А все-таки, что экономичнее на твой взгляд — getCollection или все-таки процессор? я так понял, процессор превьюшки генерит (у него возвращаются их адреса)? Они-то как раз и не нужны.

Крайне неудачное решение. Используй MODX_CORE_PATH .'components/site/processors/' и все. А экономия с путями тебе сразу несколько минусов дает:

  1. Компонент — это не только процессоры. Это еще контроллеры для админки, модели и т.п.
  2. Папка core не попадает в снимки сайта, так что Vapor-ом уже не сможешь перенести свой сайт. И еще куча минусов, включая «элементарно забыть про что-то там в core».

Резонно. Так и поступлю.

что кономичнее на твой взгляд — getCollection или все-таки процессор? Ты путаешь довольно разные вещи. getCollection — это конкретный метод xPDO для получения массива объектов. При этом это не только запросы к базе данных, но и набивка результатов в конечные объекты. Чтобы это лучше понимать, прочитай эти статьи: modxclub.ru/blog/200.html modxclub.ru/blog/166.html А процессор — это процессор. И в нем логика может быть какая угодно. Так вот, классический modObjectGetlistprocessor использует в том числе и метод xPDO::getCollection(). Просто помимо этого он имеет ряд методов для проверки прав, формирования запроса, подсчета общего числа элементов, обработки вывода и т.п. Конечно же он по определению тяжелее, чем просто getCollection(). Но если брать те же getlist-процессоры из shopModx-а, то там не используется метод getCollection, а используется чистое PDO/xPDO. Те процессоры в итоге легче гораздо. Но в случае с Gallery работать с объектами конечно же лучше как минимум по двум причинам:

  1. получаемые galItem-объекты имеют все необходимые методы для работы с этими картинками, а так же формирования путей, самбов и т.п.
  2. как правило элементов не много, так что нагрузкой можно пренебречь.

Ясно. Так и поступлю. Спасибо.

Ну, примерно так: <?php /**

  • Smarty plugin
  • @package Smarty
  • @subpackage PluginsFunction */

function smarty_function_galAlbum($params, & $smarty) { if(!isset($params['album']) OR !$album = $params['album']){return;}

$output = '';
if(!$rowTpl = $params['rowTpl']){
	$output = array();
}

if(!empty($params['assign'])){
    $assign = (string)$params['assign'];
}

$modx = & $smarty->modx;

// Получаем все элементы
$q = $modx->newQuery('galItem');
$q->join('galAlbumItem', 'AlbumItems');
$q->where(array(
    'AlbumItems.album' => $album,
));

if($items=$modx->getCollection('galItem', $q)){
	foreach($items as $item){
	    $item = array(
	        'name'			=>$item->get('name'),
            'description'	=>$item->get('description'),

// 'filename' =>$item->get('filename'), // 'mediatype' =>$item->get('mediatype'), // 'url' =>$item->get('url'), 'relativeImage' => $item->get('relativeImage'), // 'thumbnail' =>$item->get('thumbnail'), // 'image' =>$item->get('image'), // 'absoluteImage' =>$item->get('absoluteImage'), // 'filesize' =>$item->get('filesize'), // 'image_path' =>$item->get('image_path'), ); if($rowTpl){ $smarty->assign('item',$item); $output.=$smarty->fetch($rowTpl); } else{ $output[]=$item; } } } return !empty($assign) ? $smarty->assign($assign, $output) : $output; }

Пожалуйста.

Да, подобные решения очень нужны. Планирую выпустить серьезно обновленную сборку, в котором будет больше готовых модулей на процессорах+Smarty, включая менюшку на процессорах и т.п. Но вот оформлению в виде Smarty-плагинов предпочитаю именно процессоры. Есть ряд причин:

  1. Smarty-плагины — это не формат MODX-а, и они не особо укладываются в модель пакетов для него. А даже если их включать в пакеты, то для подключения их надо указывать Smarty дополнительную директорию расширений (через плагин). Все это очень не удобно.
  2. Smarty-плагины подходят только для самого Smarty. Отдельно их не вызовешь. А вот MODX-процессоры можно вызвать где угодно — хоть в Smarty, хоть в плагиных, хоть в сниппетах, хоть в других плагинах. К тому же процессоры можно использовать и в других системах шаблонизации (ведь все еще витают идеи прикрутить Twig и т.п.).
  3. Smarty-плагины — это просто функции, а значит их расширить или переопределить нельзя. С процессорами все гораздо интересней, потому что это классы. В общем, я стараюсь Smarty не обвешивать особенно.

согласен. В принципе, я вчера и процессор испытал — все удобно. И полностью согласен с тобой в плане процессоров. Просто я пока во всем этом новичок, все интересно, да и опыта набираюсь потихоньку.

Не, поиграться и попробовать различные способы — это и полезно, и интересно. Всяко поддерживаю.

Здравствуйте, использую ваш код, ссылка /assets/components/gallery/connector.php?action=web/image/gallery/small&src=/assets/gallery/1/2.jpg"/> выдает сообщение {«success»:false,«message»:"\u0414\u043e\u0441\u0442\u0443\u043f \u0437\u0430\u043a\u0440\u044b\u0442.",«total»:0,«data»:[],«object»:{«code»:401}}. Как это можно исправить?

Здравствуйте. 1. Смотрите коннектор вызываемый. Там в паблике без проверки прав будет работать только для действия web/phpthumb. 2. В помощь: modxclub.ru/blog/voprosy-spetsyalistov/136.html