Показаны сообщения с ярлыком checkout. Показать все сообщения
Показаны сообщения с ярлыком checkout. Показать все сообщения

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"/>
        ...
Вот, всего несколько часов работы и страничка чекаута содержит наш допольнительный шаблон. Всё в рамках приличия, ядрёные файлы не модифицированы, все изменения только в папке с пользовательской темой.