Проблема в том, что автогенерируемая страница с картой сайта показывает все активные продукты, в том числе и из категории Glossary. Вот этого и надо избежать. Да, и ещё нужно отсортировать продукты по алфавиту.
Сначала я попробовал сделать категорию Glossary неактивной. Ничего не вышло, Sitemap по-прежнему отображал все продукты. Вариант "выключить" все продукты категории Glossary - вообще не вариант :) Т.е. нигде в настройках в админике, и в xml, нельзя задать ни список категорий для исключения, ни порядка сортировки (может я плохо искал?).
Значит надо делать это вручную. Можно либо поменять ядрёные файлы (оставив нетронутыми шаблонные файлы) - блок
catalog/seo_sitemap_product
, изменить его так, что бы он исключал категорию Glossary и сортировал продукты. Понятно, почему это плохой вариант, и мы так делать не будем :) Вместо этого мы будем менять только шаблонные файлы. Вообще решение этой проблемы добавит немало безнес-логики в шаблоны. Не очень хорошо, но с этим можно жить :) Зато без переделки ядрёных файлов. Шаблон странички Sitemap находится в файле
template/catalog/seo/sitemap.phtml
. Существующий код берёт коллекцию всех продуктов (полученную в соответствующем блоке) и выводит все её элементы.Мы добавим новый массив, который будет содержать продукты, теже объекты, что и коллекция. Но этот массив не будет содержать "продуктов" категории Glossary. После формирования массива вызовем функцию usort и отсортируем массив по названиям продуктов.
Что бы узнать, в каких группах находится текущий продукт, нужно вызвать метод getCategoryIds - он вернёт массив id категорий. Только нужно не забывать, что один и тот же шаблон
template/catalog/seo/sitemap.phtml
используется для вывода как продуктов, так и категорий. Если вызвать getCategoryIds у объекта-категории, он вернёт null. Нужно специально обработать этот случай.Итак, вот код, формирующий новый массив без "продуктов" категории Glossary, и упорядоченный по именам объектов:
<?php $_items = $this->getCollection(); ?>
<?php
// Original collection is not ordered. To sort items by name
// we'll use array, then we'll sort it by name. Array will
// contain the same objects as original collection
$items = array();
// Create our array, excluding Glossary category (id == 63)
foreach ($_items as $_item) {
if (is_array($_item->getCategoryIds()) && in_array(63, $_item->getCategoryIds()))
continue;
$items[] = $_item;
}
function cmp($a, $b) {
return strcmp($a->getName(), $b->getName());
}
usort($items, cmp);
?>
Остальной код, по выводу продуктов, остаётся нетронутым, кроме перебора не коллекции
$_items
, а нового массива $items
.Сразу же после просмотра результата стал заметен баг - хотя продукты из категории Glossary теперь не отображаются, кол-во продуктов выводимое сразу перед списком продуктов (130 Item(s)) осталось прежним.
Поправить это оказалось чуть посложнее. Код, выводящий эту информацию, - шаблон
template/page/html/pager.html
. И используется он в catalog.xml
вот так:<catalog_seo_sitemap>
...
<reference name="content">
<block type="page/template_container" name="seo.sitemap.container" template="catalog/seo/sitemap/container.phtml">
<block type="page/template_links" name="seo.sitemap.links" as="links" template="page/template/links.phtml"/>
<!-- Magento adds block with template "page/html/pager.phtml" -->
<block type="page/html_pager" name="seo.sitemap.pager.top" as="pager_top" template="page/html/pager.phtml"/>
...
Код использует исходную коллекцию, содержащую все продукты, её размер соответственно больше чем нужно. Выход - написать свой шаблон, который подкорректирует кол-во продуктов, выводимое на экран.
Создаим этот шаблон -
template/catalog/seo/sitemap/mypager.phtml
. Сначала посчитаем продукты, исключая продукты из категории Glossary:
<?php // Calc products that don't belong to Glossary category (63) ?>
<?php // We already hide glossary "products" from sitemap page, now we need ?>
<?php // to correct products count ?>
<?php $productsCountWithoutGlossary = 0; ?>
<?php foreach ($this->getCollection() as $_i) { ?>
<?php if (is_array($_i->getCategoryIds()) && in_array(63, $_i->getCategoryIds())) continue; ?>
<?php $productsCountWithoutGlossary++; ?>
<?php } ?>
Т.к. Sitemap отображает вообще всё что есть на одной странице (это сделано уже давно), то и весь код пейджера, рисующий номера страниц, не нужен - оставим только тот код, который выводит кол-во элементов на одной странице:
<table class="pager" cellspacing="0">
<tr>
<td>
<strong><?php echo $this->__('%s Item(s)', $productsCountWithoutGlossary) ?></strong>
</td>
</tr>
</table>
Ещё нужно сказать Magento что мы хотим использовать наш шаблон в файле
catalog.xml
:<catalog_seo_sitemap>
...
<reference name="content">
<block type="page/template_container" name="seo.sitemap.container" template="catalog/seo/sitemap/container.phtml">
<block type="page/template_links" name="seo.sitemap.links" as="links" template="page/template/links.phtml"/>
<!-- Replace default template with ours "catalog/seo/sitemap/mypager.phtml" -->
<block type="page/html_pager" name="seo.sitemap.pager.top" as="pager_top" template="catalog/seo/sitemap/mypager.phtml"/>
...
Последнее - кол-во продуктов выводится не только вверху, но и внизу. Для коррекции выводимого кол-ва так же просто поменяем шаблон в файле
catalog.xml
:<catalog_seo_sitemap>
...
<reference name="content">
<block type="page/template_container" name="seo.sitemap.container" template="catalog/seo/sitemap/container.phtml">
<block type="page/html_pager" name="seo.sitemap.pager.bottom" as="pager_bottom" template="catalog/seo/sitemap/mypager.phtml"/>
...
Вот, готово. Теперь Products Sitemap исключает продукты категории Glossary, и выводит правильное кол-во продуктов. Страница Category Sitemap не падает и выводит все категории :)
Изменённые файлы:
- app/design/frontend/default/sunnyD/layout/catalog.xml
- app/design/frontend/default/sunnyD/template/catalog/seo/sitemap.phtml
- app/design/frontend/default/sunnyD/template/catalog/seo/sitemap/mypager.phtml