22 октября 2009 г.

Magento, products sitemap

На сайте есть обычные продукты, которые можно продавать, и есть специальная категория Glossary, в которой находятся определения - такие продукты нельзя купить :) Т.е. список определений сделан через категорию, это оказалось достаточно удобно.

Проблема в том, что автогенерируемая страница с картой сайта показывает все активные продукты, в том числе и из категории 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

20 октября 2009 г.

Magento, права

Я уже описывал как делать модули, имеющий интерфейс в админке (и пункт меню там же), но этот модуль никак не работал с разрешениями (permissions). Как оно действует по-умолчанию я не знаю - либо показывает меню всем, либо показывает только администратору.

Сейчас я добавил в config.xml модуля немного "кода", так, что теперь можно выбрать, может ли пользователь работать с пунктом меню или нет. Как-то так :) Информации по этому очень мало...
<?xml version="1.0"?>
<config>
    ...
    <adminhtml>
        <menu>
            <catalog module="catalog">
                <children>
                    <blogrewrite translate="title" module="blogrewrite">
                        <title>Blog Rewrite</title>
                        <action>blogrewrite/adminhtml_blogrewrite</action>
                    </blogrewrite>
                </children>
            </catalog>
        </menu>

        <acl>
            <resources>
                <admin>
                    <children>
                        <catalog>
                            <children>
                                <blogrewrite>
                                    <title>Blog Rewrites</title>
                                </blogrewrite>
                            </children>
                        </catalog>
                    </children>
                </admin>
            </resources>
        </acl>
    </adminhtml>
</config>

Я так понимаю, что т.к. мой модуль находится внутри пункта меню верхнего уровня Catalog, то нужно добавить его. А называется модуль (или пункт меню?) blogrewrite.

Как бы то ни было, теперь право просматривать страницу модуля BlogRewrites можно назначить в Admin - System - Permissions - Roles:
permissions.jpg
А на будущее надо бы по-лучше поизучать как работают права в Magento.

Magento, перемещение блоков на странице Shopping Cart

Вот схемка как надо сделать :)
checkout-cart-before.png
Т.е. переместить блоки снизу влево:
checkout-cart-after.png
Первое, что приходит в голову - в checkout.xml переместить блоки из одного места другое. К сожалению, всё не так просто - эти два блока так же имеют немного кода в файле template/checkout/cart.phtml, и блоки, объявленные в xml вызываются как раз из этого файла:
<!-- Discount Code block -->
<div class="shopping-cart-collaterals">
    <div class="col2-set">
        <?php echo $this->getChildHtml('crosssell') ?>
        <div class="col-2">
            <!-- Load block by name "coupon" -->
            <?php echo $this->getChildHtml('coupon') ?>
            <?php if (!$this->getIsVirtual()): echo $this->getChildHtml('shipping'); endif; ?>
        </div>
    </div>
</div>

<!-- Totals block -->
<div class="shopping-cart-totals">
    <?php echo $this->getChildHtml('totals'); ?>
    <?php if(!$this->hasError()): ?>
    <ul class="checkout-types">
        <?php echo $this->getChildHtml('methods') ?>
    </ul>
    <?php endif; ?>
</div>

Пришлось выдёргивать этот код и переносить его в свой новый файл - пришлось создать новый шаблон, на основе 2columns-left.phtml. Почему не использовать уже готовый файл - во-первых, ширина левой колонки в стандартном файле маловата для размещения блока Totals. Во-вторых, в этот файл нужно поместить код для отображения блоков слева (перемещённый из файла cart.phtml).

В общем, я сделал новый файл 2columns-left-checkout.phtml на основе 2columns-left.phtml, и назначил его странице Shopping Cart. Вот что там было изменено:
<?php echo $this->getChildHtml('breadcrumbs') ?>
<!-- start left -->
<div class="col-left side-col" style="width: 250px;">
    <!-- Show left column, take content from xml -->
    <?php echo $this->getChildHtml('left') ?>
    <!-- Make some html for Totals block -->
    <div class="box">
        <!-- Following code took from cart.phtml -->
        <!-- Block should be non-float and have 0 margin -->
        <div class="shopping-cart-totals" style="float: none; margin: 0;">
            <?php echo $this->getChildHtml('totals'); ?>
            <?php if(!$this->hasError()): ?>
            <ul class="checkout-types">
                <?php echo $this->getChildHtml('methods') ?>
            </ul>
            <?php endif; ?>
        </div>
    </div>
</div>
<!-- Set main block (content) width to 613px
     (default is a little bit more, therefore layout problems) -->
<div id="main" class="col-main" style="width: 613px;">
<!-- start global messages -->
    <?php echo $this->getChildHtml('global_messages') ?>
<!-- end global messages -->
<!-- start content -->
    <?php echo $this->getChildHtml('content') ?>
<!-- end content -->
</div>

Итак, мы добавили вывод блока Totals после вывода левой колонки. А так же немного модифицировали стили блоков (см. комментарии). Левая колонка выводит Discount Coupons, это задаётся полностью в checkout.xml. Вот как блок Discount Coupons переносится в левую колонку:
<checkout_cart_index>
    ...
    <remove name="right"/>
    <!-- We should not remove left column, comment that line -->
    <!--<remove name="left"/>-->
    <reference name="left">
        <action method="unsetChildren"/>
        <block type="checkout/cart_coupon" name="checkout.cart.coupon" as="coupon" template="checkout/cart/coupon.phtml"/>
    </reference>
    ...

Убираем удаление левой колонки, убираем всех лишних детей из левой колонки, добавляем блок с шаблоном блока Discount Coupon.

С перемещением блока получился небольшой затык. Хотя блоки, которые вызываются из шаблона (totals, methods), я скопировал из reference name="content" в reference name="left", всё отображалось совсем не как надо. А потом я сообразил, что в шаболоне эти блоки вызываются не "изнутри" блока left/content, а из "корня". После того как я переместил эти блоки в reference name="root" всё наконец заработало. Вот этот кусочек:
<reference name="root">
    <block type="checkout/cart_totals" name="checkout.cart.totals" as="totals" template="checkout/cart/totals.phtml"/>
    <block type="core/text_list" name="checkout.cart.methods" as="methods">
        <block type="checkout/onepage_link" name="checkout.cart.methods.onepage" template="checkout/onepage/link.phtml"/>
        <block type="checkout/multishipping_link" name="checkout.cart.methods.multishipping" template="checkout/multishipping/link.phtml"/>
    </block>
</reference>

В основном всё, блоки переместились снизу налево и отображают то, что и должны. Остались мелочи - удалить выводы блоков снизу (можно просто закомментировать вывод блоков прямо в cart.phtml), и поправить css, т.к. текущие правила расчитаны на то, что эти блоки будут внутри блоков с определёнными классами. Вот добавленный в boxes.css код:
/* Copy some styles from Discount Codes, it was in the middle of
   page, now it's on the left side */
.col-left .discount-codes h4 {
    background-image:url(../images/icon_asterick.gif);  padding-left:23px;
    min-height:16px;
    color:#e26703;
    background-repeat:no-repeat;
    background-position:0 0;
    padding:1px 0 1px 21px;
    text-transform:uppercase;
}

.col-left .discount-codes.box {
    margin-bottom:18px;
    padding:12px 15px;
    border:1px solid #D0CBC1;
    background:url(../images/base_mini_head_bg.gif) repeat-x #fff;
}

Ну и последнее - убираем вывод блока с классом shopping-cart-collaterals. Этот блок содержит не только Discount Coupons, но и кое-что ещё. Но его можно убрать целиком, потому что в текущей конфигурации весь остальной вывод выключен (в админке) - выводится только Discount Coupons.

Вот код, который убирает всё ненужное снизу страницы:
<?php /*
<div class="shopping-cart-collaterals">
    <div class="col2-set">
        <?php echo $this->getChildHtml('crosssell') ?>
        <div class="col-2">
            <?php echo $this->getChildHtml('coupon') ?>
            <?php if (!$this->getIsVirtual()): echo $this->getChildHtml('shipping'); endif; ?>
        </div>
    </div>
</div>

<div class="shopping-cart-totals">
    <?php echo $this->getChildHtml('totals'); ?>
    <?php if(!$this->hasError()): ?>
    <ul class="checkout-types">
        <?php echo $this->getChildHtml('methods') ?>
    </ul>
    <?php endif; ?>
</div>
*/ ?>

Просто комментируем это дело :)

Вот так за пару часов блоки переехали снизу в левую колонку.

Изменённые файлы:
  • app/design/frontend/default/sunnyD/layout/checkout.xml
  • app/design/frontend/default/sunnyD/template/checkout/cart.phtml
  • app/design/frontend/default/sunnyD/template/page/2columns-left-cart.phtml
  • skin/frontend/default/sunnyD/css/boxes.css

16 октября 2009 г.

Дополнительный контент на Checkout странице, левая колонка

В прошлый раз я писал как добавить свой контент в правую колонку на странице чекаута. Оказалось что это не совсем то, что нужно :) А нужно добавить левую колонку и уже туда поместить картинки. Вот так:
checkout-left.png
Это оказалось даже проще чем добавить контент в правую колонку. Только есть один нюанс - когда мы добавим новую колонку, размер средней колонки (с основным контентом) уменьшится. А в этой средней колонке есть элементы, которые расчитаны на строго определённый размер основной колонки, и размеры там задаются в пикселях. Это выпадающий список с адресами, поле ввода адреса-1 и адреса-2, и поля логина/пароля, если чекаут делается из под гостя.

Если не изменить размеры этих элементов, они выедут за свою родительскую колонку, и будет некрасиво. Ну и вообще, колонка рассчитана быть размером 650px вроде, поэтому в любом случае с уменьшением размера элементы внутри поедут. Это будет выглядеть немного не так, как задумывалось, но в целом неплохо. В частности, форма ввода адреса при нормальном размере отображается как бы в двух колонках - поля ввода есть и слева и справа. При уменьшенном размере все поля располагаются друг под другом.

Итак, для начала нужно поменять шаблон страницы чекаута на 3columns.phtml. Старый шаблон 2columns-right-checkout.phtml больше не нужен, его можно удалить.

Здесь же, недалеко от изменения шаблона, добавим наш шаблон с картинками в левую колонку:
<checkout_onepage_index>
    ...
    <!-- Mage_Checkout -->
    <!--<remove name="left"/>-->

    <reference name="root">
        <action method="setTemplate"><template>page/3columns.phtml</template></action>
    </reference>
    <reference name="left">
        <action method="unsetChildren" />
        <block type="core/template" name="images" template="callouts/checkout.phtml"/>
    </reference>
    ...

Здесь сначала мы убираем удаление левой колонки remove name="left". Потом устанавливаем для чекаута шаблон 3columns.phtml. Затем модифицируем блок с названием left - удаляем все добавленные в левую колонку блоки, добавленные где-то до нас - action method="unsetChildren". Если этого не сделать, в левой колонке будут отображаться разные блоки, вроде списка категорий, списка тэгов, и т.д. И, наконец, добавляем наш шаблон block type="core/template"...

Основная задача решена - страница чекаута превратилась в трёхколоночную, и левая колонка отображает наш шаблон с картинками.

Теперь нужно поменять размеры некоторых элементов.

Для начала поменяем размеры выпадающих списков с адресами. Эти элементы можно легко достать по их id - это billing-address-select и shipping-address-select. Добавим новый стиль в boxes.css:
#billing-address-select, #shipping-address-select {
    width: 420px;
}

Дальше нужно поменять размеры полей для ввода адреса на страницах Billing Information и Shipping Information. Эти поля возникают если в списке выбора адреса выбрать New Address.

Эти поля тоже имеют id, но они какие-то странные - shipping:street1, т.е. содержат двоеточие. У меня не получилось выбрать такие элементы с помощью css селектора #shipping:street1, поэтому пришлось добавить атрибут style прямо в эти самые тэги. Они находятся в файлах template/checkout/onepage/billing.phtml и template/checkout/onepage/shipping.phtml. Просто добавляем код style="width: 250px;" к input элементам, всего их 4 штуки.

Теперь - формы ввода логина/пароля, если пользователь делает чекаут как гость. Хотя эти поля можно вытянуть по id, я не стал этого делать, потому что точно такая же форма, такие же поля с такими же id, могут использоваться на другой форме, например, на форме логина пользователя. Поэтому я опять добавил тэг style прямо в тэг. Эта форма находится в файле template/checkout/onapage/login.phtml, всего два поля нужно обновить.

Например, тэг для пароля будет иметь такой вид:
<input type="password" class="input-text required-entry" id="login-password" name="login[password]" style="width: 200px;" />

И последнее - форма добавления комментария на последнем шаге. Она совсем чуть-чуть вылезает за разрешённые границы, но этого достаточно, что бы в IE всё поехало конкретно.

Файл template/checkout/onepage/agreements.phtml содержит этот элемент. Немного уменьшаем ширину, прописанную в атрибуте style, до 420px:
<ol class="checkout-agreements">
    <li>
        <label for="biebersdorfCustomerOrderComment"><?php echo Mage::helper('biebersdorfcustomerordercomment')->__('Your Comment for this Order') ?></label>
        <br/><textarea name="biebersdorfCustomerOrderComment" id="biebersdorfCustomerOrderComment" style="width: 420px; height: 100px;"></textarea>
    </li>
</ol>

Всё готово, теперь чекаут содержит левую колонку с нашими картинками, и никакие поля не вылезают за рамки родительских блоков.

Модифицированные файлы:
  • app/design/frontend/default/sunnyD/template/checkout/onepage/billing.phtml
  • app/design/frontend/default/sunnyD/template/checkout/onepage/shipping.phtml
  • app/design/frontend/default/sunnyD/template/checkout/onepage/login.phtml
  • app/design/frontend/default/sunnyD/template/checkout/onepage/agreemenst.phtml
  • app/design/frontend/default/sunnyD/layout/checkout.xml

15 октября 2009 г.

Дополнительный контент на странице Checkout

Нужно добавить две картинки на страницу чекаута, как на этой картинке:
checkout.png
Это оказалось не так просто, как казалось :)

Для начала сделаем небольшой файл-шаблончик с нужными картинками. Это файл app/design/frontend/default/sunnyD/template/callouts/checkout.phtml:
<div class="box">
    <script src="https://siteseal.thawte.com/cgi/server/thawte_seal_generator.exe"></script>
</div>

<div class="box">
    <img src="<?php echo $this->getSkinUrl('images/free-shipping.gif') ?>" alt="<?php echo __('Free Shipping') ?>" />
</div>

Первая картинка загружается динамически, для чего используется Javascript.

Первая попытка

Почему бы просто не добавить новый блок в checkout.xml? Для этого можно использовать встроенный блок core/template. Он очень удобен для вывода простых шаблонов без логики, ему нужно передать всего один параметр - шаблон, который надо вывести. И, т.к. шаблон простого чекаута состоит из контента и правого блока (шаблон 2columns-right.phtml), добавить наш новый блок к правой части страницы, как-то так:
<checkout_onepage_index>
    ...
    <reference name="right">
        ...
        <block type="core/template" name="images" template="callouts/checkout.phtml"/>
        ...
Это даже работает, и на первый взгляд мы имеем именно то что надо - справа появляются наши картинки из шаблона checkout.phtml.

Но на второй взгляд, когда нажать кнопку Continue что бы перейти к следующему шагу чекаута, правая часть страницы целиком перезагружается. html для правой страницы приходит в Ajax запросе. Этот html больше не содержит наших картинок.

Вторая попытка

Ладно, значит нужно поправить возвращаемый html, что бы он содержал наши картинки.

Для этого надо поправить checkout.xml, секцию checkout_onepage_progress. Нужно добавить наш блок, как мы это делали в секции checkout_onepage_index. Но что это? Наших картинок всё-равно нет!

В общем в итоге выяснилось, что к блоку нужно добавить параметр output и присвоить ему значение toHtml:
<checkout_onepage_progress>
    ...
    <block type="core/template" name="images" output="toHtml" template="callouts/checkout.phtml"/>
    ...

Да что же это? Теперь после кнопки Continue видно только одну картинку, которая загружается через тэг img. Второй картинки, загружаемой через Javascript, не видно. Более того, хотя js код пришёл в ответе от сервера, он пропал из DOM дерева. Какой-то фильтр?

В общем, попытка номер два тоже провалилась.

Успех

Ладно, если не получается показывать обе картинки модифицируя код правой части, возвращаемый с помощью Ajax запроса, попробуем сделать так, что бы шаблон оставался неизменным на протяжении всех шагов чекаута.

Javascript, работающий со страницей чекаута находится в файле opcheckout.js. Похоже, что код, который обновляет правую часть страницы, выглядит так:
...
reloadProgressBlock: function(){
    var updater = new Ajax.Updater($$('.col-right')[0], this.progressUrl, {method: 'get', onFailure: this.ajaxFailure.bind(this)});
},
...
Т.е. он берёт первый элемент с классом col-right и устанавиливает ему новый html, полученный с сервера.

А вот где элемент с этим классом объявлен - файл template/page/2columns-right.phtml:
...
<!-- start right -->
<div class="col-right side-col">
    <?php echo $this->getChildHtml('right') ?>&nbsp;
</div>
<!-- end right -->
...
Не очень хорошо... Что бы мы ни поместили в правую часть страницы с помощью xml и reference name="right", либо прямо в данный шаблон, это всё будет внутри дива с классом col-right и, в итоге, будет затёрто на последующих шагах чекаута.

Выходит, единственный выход - сделать свой шаблон, основанный на 2columns-right.phtml. А в этом шаблоне как-то поместить наш шаблон с картинками "вне" правой части, что бы он не затёрся новыми данными.

Итак, для начала создадим новый шаблон 2columns-right-checkout.phtml, и укажем в checkout.xml что использовать нужно именно его.

Было:
<checkout_onepage_index>
    ...
    <reference name="root">
        <action method="setTemplate"><template>page/2columns-right.phtml</template></action>
Стало:
<checkout_onepage_index>
    ...
    <reference name="root">
        <action method="setTemplate"><template>page/2columns-right-checkout.phtml</template></action>
Далее модифицируем новый шаблон 2columns-right.checkout.phtml в части вывода правой части:
<!-- start right -->
<div class="side-col" style="float: right;">
    <div class="col-right side-col" <?php echo $this->getChildHtml('right') ?></div>

    <div class="col-right side-col">
        <?php echo $this->getChildHtml('images') ?>
    </div>
</div>
<!-- end right -->
Смысл такой. Создаём новый div-обёртку, которая будет содержать правую колонку. Мы не можем назначит ему класс col-right, потому что тогда контент этого дива затрётся. Но мы можем оставить ему класс side-col (который просто установливает ширину колонки, сейчас 195px). И добавляем свойство float: right что бы наш див-обёртка распологался справа.

Затем добавляем внутрь этого дива-обёртки сначала исходную правую часть getChildHtml('right'), затем наш шаблон с картинками getChildHtml('images').

Теперь оба дива могут иметь оригинальные классы side-col и col-right. При переходе между шагами будет обновляться содержимое первого блока с классом col-right, а второй блок с нашими картинками останется нетронутым на протяжении всего чекаута. Что и требовалось :)

И ещё - что бы код getChildHtml('images') отработал и отобразил наш блок core/template с шаблоном с картинками, нужно его добавить в checkout.xml внутри reference name="root". И ещё добавить свойство as, равное images. Это images и есть то имя, по которому getChildHtml() найдёт наш блок. Получаем:
<checkout_onepage_index>
    ...
    <reference name="root">
        ...
        <block type="core/template" name="images" as="images" template="callouts/checkout.phtml"/>
        ...
Вот, всего несколько часов работы и страничка чекаута содержит наш допольнительный шаблон. Всё в рамках приличия, ядрёные файлы не модифицированы, все изменения только в папке с пользовательской темой.

Magento, список категорий

В теме Modern есть список категорий, отображаемый сверху. Если навести на категорию - выскочит список подкатегорий. Красивый и удобный список.
top-links.png
Только есть проблема с этим списком - он показывает все активные категории. Нет возможности через админку/xml убрать из этого списка некоторые категории, например, категорию Glossary. Вообще-то Glossary уже скрывается, а сейчас нужно скрыть категорию Out of Stock.

Но можно скрывать категории с помощью css, и воспользоваться для этого особенностью этого списка - для каждой категории генерируется уникальный класс, совпадающий с названием категории. Т.о. для того, что бы "убрать" категорию из этого списка, нужно просто добавить новый класс в какой-либо css файл.

Структура списка имеет вид:
<ul id="nav">
    <li class="level0 nav-category-name">...</li>
</ul>
Категория Out of Stock будет иметь класс nav-out-of-stock. Добавим новый стиль в файл skin/frontend/default/sunnyD/css/menu.css:
/* Hide Out Of Stock category */
#nav li.level0.nav-out-of-stock {
    display: none;
};
Это правило будет применено к элеменам li с классами nav-out-of-stock и level0, которые являются дочерними по отношению к элементу с id равным nav. Это и есть категория Out of Stock.

14 октября 2009 г.

Windows Seven - Windows XP

Перешёл с семёрки на XP. Наконец-то, и я этому рад! :)

Установленное ПО

После переустановки винды нужно переустановить вагон с тележкой разного софта... Утомительное же это занятие...

Drivers (Wireless, Video), WinRar, foobar2000, Miranda, Skype, Opera, Firefox (+plugins), Total Commander, Notepad++, Video Codecs (+player Media Player Classic), .Net Framework, Java, Flash Player, Pdf viewer, Djv viewer, Python (+modules: setup-tools, MySQL, mechanize, django, djang-debug-toolbar), Php, MySQL, HeidiSQL, Apache Web Server, Aptana, NuSphere PhpEd, oDesk Team, F.lux, uTorrent, John's Background Switcher, Dropbox, Lingvo.

Это только то, что сейчас установлено, что-то может забыл.

А ещё нужно настроить эти программы как удобно, а некоторые - подружить (Php с сервером, отладчик от PhpEd'а с Php, и т.д.). Хорошо что некоторые программы легко переносятся со всеми настройками :)

Что стало лучше

Всё стало работать быстро! Я много читал отзывов, в которых в основном говорилось что семёрка работает как минимум не медленнее хрюши. Всякие Fetch/Prefetch механизмы, кеши-шмеши... А толку?

Сейчас я на каждом действии замечаю разницу между семёркой и XP. Попасть в Панель управления - в семёрке 5 секунд, в XP - 1 секунда. Запустить приложение, в семёрке - от секунды, в XP - от меньше чем за секунду (иногда мгновенно, чего на семёрке не наблюдал никогда).

Ещё в семёрке иногда заедал курсор, если например попытаться развернуть программу, свёрнутую пару часов назад. Т.е. всё тормозило секунд 5-10-20-30, было невозможно работать, пока ОС не сделает свои дела по развёртыванию проги... Чаще чем курсор заедала музыка... Странно зависала миранда секунд на 5 во время создания окошка с чатом.

В общем, в семёрке всё работало с жуткими задержками на каждое действие, в XP всё работает моментально, по сравнению с семёркой :)

Чего будет не хватать

Superbar, наследник Taskbar, - очень удобная штука!

Интерфейс Aero. Это когда всё как будто сделано из стекла, всё полупрозрачное и размазанное :) Полупрозрачный Superbar это красиво :)

Шрифты. Шрифты в семёрке - загляденье! К сожалению, в XP это не так.

Драйвера. Семёрка нашла все устройства на моём Dell Inspiron 1525 "из коробки".

Что будет с радостью забыто

Тормоза, но об этом уже было :)

Несовместимости с некоторыми программами. Т.е. как бы самих несовместимых программ очень мало... Но foobar2000, например, мог работать только в режиме совместимости (я использую старую версию, потому что в новых версиях нет нужного мне плагина), а для того, что бы запустить такую программу, нужно будет ответить Yes на вопрос UAC. Неприятная мелочь.

Сюда же можно отнести неумение некоторых программ работать не из под администратора. Например, Behold, программа для работы с ТВ-тюнером, сохраняет настройки в папке куда она установлена. Поэтому сохранить сделанные в программе изменения настроек можно либо запустив программу из под администратора, либо дать нужные права на папку установки, либо поставить в папку у которой не будет запретов. Неприятная мелочь.

Некоторые другие программы так же хранят настройки в папке установки, что приводит к таким же последствиям (foobar2000, Miranda, ...).

Итог

Windows Seven - хорошая операционка. Всё что было сказано выше относится к публичной бета-версии. Всё было стабильно, красиво, даже приятно, если отбросить странные тормоза :) Её смело можно ставить через пару лет, плюс желательно на новое железо.

Общие впечатления такие, что семёрка добавляет некоторые приятные мелочи. Не больше...