Однин из способов сделать магазин быстрее и удобнее для пользователя - использование AJAX подгрузки тела компонента VirtueMart.
Использование подгрузки только нужной части страницы вместо перезагрузки всей страницы имеет немало преимуществ:
1) Экономия трафика
2) Уменьшение нагрузки на сервер
3) Быстрота (как результат 1 и 2)
4) Отсутсвие "мерцания" страницы
5) Эффектно смотрится для юзера
Я приведу пример простейшей реализации, которая позволит перемещаться по категориям через ajax-подгрузку.
На сайте должен быть список категорий магазина: это может быть стандартный модуль меню mod_mainmenu или
усовершенствованный модуль категорий VirtueMart - mod_virtuemart_categories.
Условимся что модуль присутсвует на всех страницах сайта, в параметрах модуля указан
id списка -
catalogТеперь за дело: добавляем в index.php своего шаблона вот такой код:
$script = "
window.addEvent('domready', function(){
loading = false;
$$('#catalog a').each(function (el) {
el.addEvent('click', function (e) {
if (!$('vmMainPage')) return;
(new Event(e)).preventDefault();
if (loading) return;
var container = $('vmMainPage').getParent();
var onComplete = function(responseText, responseXML){
var titleNode = responseXML.documentElement.getElementsByTagName('title')[0];
var bodyNode = responseXML.documentElement.getElementsByTagName('body')[0];
document.title = titleNode.textContent || titleNode.text;
container.setHTML(bodyNode.textContent || bodyNode.text);
loading = false;
}
container.setStyle('position', 'relative');
container.appendChild(
new Element(
'div',
{
'styles' : {
'height': container.offsetHeight,
'width': container.offsetWidth,
'position': 'absolute',
'top': 0,
'left': 0,
'background': '#fff',
'opacity': 0.4
}
}
)
);
container.appendChild(
new Element(
'img',
{
'src': '/media/system/images/spinner.gif',
'styles': {
'position': 'absolute',
'top': '50%',
'left': '50%'
}
}
)
);
loading = true;
new Ajax(el.href, {onComplete: onComplete}).request({tmpl: 'xml'});
});
});
});
";
JHTML::_('behavior.mootools');
$this->addScriptDeclaration($script);
Так как нам нужно подгрузить не только сам компонент, но и новый тайтл, нам нужно обернуть две эти составляющие в какойто контейнет. Это может быть либо JSON, либо XML. Со вторым у меня возникло меньше трудностей, поэтому использую его. Передав в запросе ?tmpl=xml мы тем самым заставляем Joomla запросить не index.php шаблона, а
xml.php, который нужно создать рядом с index.php шаблона. Вот его код:
<?php
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
$this->setMimeEncoding('text/xml');
$title = $this->title;
$body = $this->getBuffer('component');
$body = str_replace('<![CDATA[', '', $body);
$body = str_replace(']]>', '', $body);
?>
<page>
<title><![CDATA[<?php echo $title ?>]]></title>
<body><![CDATA[<?php echo $body ?>]]></body>
</page>
Все, теперь если мы на странице VirtueMart, то клик по меню не приведет к переходу по ссылке, вместо этого сработает скрипт, который подгрузит тело VirtueMart и заголовок страницы.
Пояснения:
catalog - id тега меню(списка категорий) - настраивается в параметрах модуля. Можно использовать любой другой селектор, например $$('.menu a')
vmMainPage - id wrapperа VirtueMart, зашито в коде компонента
'background': '#fff' - цвет оверлея, белый.
'opacity': 0.4 - прозрачность оверлея, 40%
'src': '/media/system/images/spinner.gif' - путь к картинке анимации загрузки
Код протестирован в ff 3, opera 10, ie 8, 7
Впринципе этот скрипт можно вынести из шаблона куда угодно.
Я не касался вопросов хистори браузера, смены адреса (добавления хэша) и др.
Известный факт что Витр - самый популярный, и приэтом самый криворукий магазин на Joomla. Писали его индусы однозначно. И я, хоть и потомок индусов, все же стараюсь забыть свое происхождение и стать профессионалом. Стараюсь изо всех сил, придумываю всякие клевые фигнюшки для вирта, но он ставит палки в колеса повсеместно.
Очередная палка - document.write(бла бла) в дефолтном шаблоне вирта. Скрипты загруженные аяксом не исполняются, а значит не исполнится document.write. А именно этим методом выводятся картинки в попап на странице категории.
Решение простое. Заменяем в файле \components\com_virtuemart\themes\default\templates\browse\browse_1.php
<div class="browseProductImageContainer">
<script type="text/javascript">//<![CDATA[
document.write('<a href="javascript:void window.open(\'<?php echo $product_full_image ?>\', \'win2\', \'status=no,toolbar=no,scrollbars=yes,titlebar=no,menubar=no,resizable=yes,width=<?php echo $full_image_width ?>,height=<?php echo $full_image_height ?>,directories=no,location=no\');">');
document.write( '<?php echo ps_product::image_tag( $product_thumb_image, 'class="browseProductImage" border="0" title="'.$product_name.'" alt="'.$product_name .'"' )?></a>' );
//]]>
</script>
<noscript>
<a href="<?php echo $product_full_image ?>" target="_blank" title="<?php echo $product_name ?>">
<?php echo ps_product::image_tag( $product_thumb_image, 'class="browseProductImage" border="0" title="'.$product_name.'" alt="'.$product_name .'"' )?>
</a>
</noscript>
</div>
на
<div class="browseProductImageContainer">
<a href="<?php echo $product_full_image ?>" target="_blank" title="<?php echo $product_name ?>" onclick="window.open('<?php echo $product_full_image ?>', 'win2', 'status=no,toolbar=no,scrollbars=yes,titlebar=no,menubar=no,resizable=yes,width=<?php echo $full_image_width ?>,height=<?php echo $full_image_height ?>,directories=no,location=no'); return false">
<?php echo ps_product::image_tag( $product_thumb_image, 'class="browseProductImage" border="0" title="'.$product_name.'" alt="'.$product_name .'"' )?>
</a>
</div>
Как видим кода в 2 стало меньше и мы избавились от документ.райт(). Почему изобретатели вирта не додумались до такой записи - загатка. Быть может их просто прикалывает метод document.write, и в новой версии вирта они будут весь код страницы выводить как document.write() и <noscript>обломайся - у тя выкл. js - ты лузер</noscript>
PS: изивинте накипело. решение не проверял, как меня и учил дедушка индус...