Fi1osof 23 августа 2013 2 2
В продолжение темы работы с 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>


Как видно, для кастомной галереи не нужно писать много кода.
2 комментария
Tramp13571
Tramp1357 23 августа 2013г в 21:51 #
Все понятно. Блин, хотелось бы все же с процессорами разобраться. По-моему, mgr/item/getlist в gallery меньше кода гоняет
Fi1osof1
Fi1osof 23 августа 2013г в 22:06 #
Так кто мешает? Говорю же — перегрузи метод outputArray() и все.
Tramp13571
Tramp1357 23 августа 2013г в 23:12 #
вот что получилось:

<?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 крутится. Что-то я еще не сделал?
Fi1osof1
Fi1osof 23 августа 2013г в 23:24 #
1. В начале кода в консоли пропиши ini_set('display_errors', 1); Чтобы php тебе выводил ошибки.
2. Поставь FireBug или типа того, чтобы видеть Ajax-овые запросы и т.п.
3. Ошибка у тебя 99,999% из-за $this->getMessage(). Это моя функция в моем процессоре, и в процессорах MODX-а ее нет. Поэтому у тебя скрипт и разваливается с критической ошибкой.
Tramp13571
Tramp1357 23 августа 2013г в 23:33 #
Точно, исправил — заработало.
Fi1osof1
Fi1osof 23 августа 2013г в 23:26 #
И еще:
'processors_path' => $modx->getOption('core_path'). 'site/processors/'
А что это ты из core_path процессор пытаешься дернуть? У тебя по идее как минимум в core_path. components должно лежать. Пути в общем проверь.
Tramp13571
Tramp1357 23 августа 2013г в 23:34 #
да просто в core положил папку site, где все процессоры и шаблоны. Не люблю слишком длинные пути.
Fi1osof1
Fi1osof 23 августа 2013г в 23:43 #
Крайне неудачное решение. Используй MODX_CORE_PATH .'components/site/processors/' и все.
А экономия с путями тебе сразу несколько минусов дает:
1. Компонент — это не только процессоры. Это еще контроллеры для админки, модели и т.п.
2. Папка core не попадает в снимки сайта, так что Vapor-ом уже не сможешь перенести свой сайт.
И еще куча минусов, включая «элементарно забыть про что-то там в core».
Tramp13571
Tramp1357 23 августа 2013г в 23:50 #
Резонно. Так и поступлю.
Tramp13571
Tramp1357 23 августа 2013г в 23:36 #
А все-таки, что экономичнее на твой взгляд — getCollection или все-таки процессор? я так понял, процессор превьюшки генерит (у него возвращаются их адреса)? Они-то как раз и не нужны.
Fi1osof1
Fi1osof 23 августа 2013г в 23:51 #
что кономичнее на твой взгляд — 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. как правило элементов не много, так что нагрузкой можно пренебречь.
Tramp13571
Tramp1357 24 августа 2013г в 00:01 #
Ясно. Так и поступлю. Спасибо.
Fi1osof1
Fi1osof 24 августа 2013г в 01:02 #
Пожалуйста.
Tramp13571
Tramp1357 24 августа 2013г в 01:02 #
Ну, примерно так:

<?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;
}

Fi1osof1
Fi1osof 24 августа 2013г в 01:17 #
Да, подобные решения очень нужны. Планирую выпустить серьезно обновленную сборку, в котором будет больше готовых модулей на процессорах+Smarty, включая менюшку на процессорах и т.п.
Но вот оформлению в виде Smarty-плагинов предпочитаю именно процессоры. Есть ряд причин:
1. Smarty-плагины — это не формат MODX-а, и они не особо укладываются в модель пакетов для него. А даже если их включать в пакеты, то для подключения их надо указывать Smarty дополнительную директорию расширений (через плагин). Все это очень не удобно.
2. Smarty-плагины подходят только для самого Smarty. Отдельно их не вызовешь. А вот MODX-процессоры можно вызвать где угодно — хоть в Smarty, хоть в плагиных, хоть в сниппетах, хоть в других плагинах. К тому же процессоры можно использовать и в других системах шаблонизации (ведь все еще витают идеи прикрутить Twig и т.п.).
3. Smarty-плагины — это просто функции, а значит их расширить или переопределить нельзя. С процессорами все гораздо интересней, потому что это классы.

В общем, я стараюсь Smarty не обвешивать особенно.
Tramp13571
Tramp1357 24 августа 2013г в 19:10 #
согласен. В принципе, я вчера и процессор испытал — все удобно. И полностью согласен с тобой в плане процессоров. Просто я пока во всем этом новичок, все интересно, да и опыта набираюсь потихоньку.
Fi1osof1
Fi1osof 24 августа 2013г в 19:21 #
Не, поиграться и попробовать различные способы — это и полезно, и интересно. Всяко поддерживаю.
N
Nasg 09 февраля 2014г в 17:34 #
Здравствуйте, использую ваш код, ссылка /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}}. Как это можно исправить?
Fi1osof1
Fi1osof 09 февраля 2014г в 17:50 #
Здравствуйте.

1. Смотрите коннектор вызываемый. Там в паблике без проверки прав будет работать только для действия web/phpthumb.

2. В помощь: modxclub.ru/blog/voprosy-spetsyalistov/136.html
Авторизуйтесь или зарегистрируйтесь (можно через соцсети ), чтобы оставлять комментарии.