Сайт для тех кто хочет определиться
→ Мой опыт разработки магазина на Drupal 7 + Commerce (разбор сайта vzavitok.ru)

Задача: сделать качественный магазин материалов для рукоделия. Это мой собственный магазин, то есть сразу была установка делать на совесть.

http://vzavitok.ru/

Оказалось, что объем работы, для реализации качественного магазина существенно превышает изначально казавшийся. Поэтому понял, что по-настоящему качественный магазин (на любом движке) - дорогое удовольствие.

В качестве основного модуля был выбран Commerce по нескольким причинам:

1. недавно перешел на семерку, а есть мнение, что под семерку коммерц будет лучше.

2. на друпал-6 я делал один примитивный магазин на шаблоне, и поэтому было интересно попробовать альтернативу уберу в лице коммерца.

3. и самое главное. Ключевое требование к магазину - показывать несколько похожих товаров на одной странице. Три (почти одинаковых) товара, которые отличаются одним параметром и ценой. И таких "троек" предполагается 90% от всех товаров магазина. Нужна одна общая фотка и три цены с тремя кнопками "купить". Это требование сыграло решающую роль в пользу комерца.

Вот пример тизеров товаров если мы находимся на странице категории (каталога)


Commerce

Да, меня тоже напрягает, что сначала нужно создавать продукт, а потом для него делать представление (view-ноду), и связывать их с помощью как я понял node-reference. Но другого более удобного способа я не нашел.

Commerce Bulk Creation

Да, я знаю что есть модуль Commerce Bulk Creation, который призван типа облегчить добавление новых товаров. Но лично в моей ситуации и для моего способа мышления он не подошел. Это дополнительное усложнение и без того сложного комерца. Товаров у меня не много, добавить ручками их один раз не такая уж и проблема. Сейчас около 30 позиций, планируется довести до 100-200. Модуль Commerce Bulk Creation не понравился еще и тем, что хоть и работал, но выдавал ошибки при каждом добавлении. Я решил отказаться от излишней сложности и рисков в пользу надежности и предсказуемости, тем более на первом коммерц-проекте. Еще, данный модуль был-бы более оправдан, если для каждого товара было не 3 размера, а скажем 10. Вот это была-бы ощутимая польза и ускорение.

Ajax Cart

Это магазин расходных материалов.
Специфика сайта в том, что за один раз человек покупает сразу несколько товаров (недорогая расходка 50-150 руб/штука). Поэтому было неприемлемо перебрасывать человека в корзину после положЕния туда одного товара. Более того, было неприемлемо даже перезагружать страницу, как это реализовано в комерце из коробки.

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

Нужно обеспечить непрерывность просмотра категории с одновременным откладыванием в корзину выбранных товаров.

Поэтому естевственно был использован модуль Ajax Cart. Модуль хорошо себя зарекомендовал, не выдает ошибок, работает стабильно, предсказуемый и предельно простой.

Страница корзины /cart

По дефолту оформление заказа для новых юзеров состоит из трех шагов:

1. Страница корзины, где можно удалить товар или изменить его количество.

2. Страница ордера, где нужно ввести свои данные для регистрации и доставки. На этой странице нельзя изменить количество или удалить товар.

3. Страница предпросмотра заказа, где две таблицы: таблица с товарами и таблица подтверждения введенных данных.

И только на третьей странице если мы нажмем "оформить заказ", то тогда он оформится.

Решил подсократить процедуру на оформления на один шаг, дав ссылку не на /cart а на /checkout. Таким образом при переходе пользователя на страницу /checkout, его редиректит на страницу /checkout/order_id, на которой он видит таблицу с его товарами из корзины.

Views

Это мой первый сайт где я использовал Views. В некоторых ситуациях при работе с коммерцем этот модуль незаменим. Например при создании блока вариаций одного товара:

Настройки этого блока выглядят так:

Viewfield

С помощью этого модуля мы можем показать вьюху как поле какой-то ноды.
Есть альтернатива Eva, но меня и этот полностью устроил.

Картинки товаров в корзине

Чтобы во вьюхе корзины сделать картинки товаров, необходимо связать Line items с products:

Чего не удалось сделать с вьюхами

Ссылка на товар из корзины [Fail]
Сделать ссылку на страницу самого продукта (которая видна только админу) у меня получилось. Но мне-то нужна ссылка на представление! Бился над решением этой задачи не один день, но так и не осилил.

Backup migrate

Отлично зарекомендовал себя во время развертывания сайта из бэкапа. phpMyAdmin без лишних слов сожрал mysql файл и выдал чистый полностью рабочий сайт.

Настроил автоматический бэкап базы на сервер через каждые 6 часов. Поставил ограничение в 20 бэкапов, после чего старые будут удаляться. Таким образом у меня есть бэкапы сайта за последние 5 дней, и если что-то случиться, 5 дней мне вполне достаточно чтобы среагировать и забрать бэкапы. Если учесть, что обычно дамп базы весит 3.5 мегабайта, то 20 бэкапов занимают на сервере 70 мегабайт, что совсем не много за надежность и уверенность в завтрашнем дне.

Папка для сохранения на сервере выше корня сайта, и конечно веб-сервер должен иметь права на запись в нее. Конечно хостер тоже каждый день делает бэкапы, но как говорится: "на патруль надейся а сам не плошай". Да и вообще, бэкапы лишними не бывают.

Меня правда слегка напрягает фраза:

You must specify a private file system path in the file system settings to backup to the server.

С какой стати я что-то ему должен?
И зачем он об этом всегда напоминает?

В общем Несмотря на эту фразу бэкапы работают отлично.

Верстка

Адаптивная, не резиновая верстка. Фактически это означает, что сайт существует в двух фиксированных вариантах: 1200px и 1000px. Переключение между режимами во время ресайза окна браузера происходит с помощью CSS без использования jquery и его $(window).onresize(), который заметно тормозит рендеринг при ресайзе браузера. Конечно есть debounce плагины, но игра не стоит свеч, и легкая форма адаптивности прекрасно справляется с поставленными задачами.

Вот CSS код, который переключает эти два режима:


@media (max-width: 1260px) {
.page {
width:960px;
}
.teaserBox {
margin-right:23px;
}
.basketBox {
right:-5px !important;
}
.main-menu {
font-size:17px;
margin-top:25px;
}
.main-menu li {
margin-right:20px !important;
}
}

Корзина, которая всегда видна

Прилипающая к верху страницы корзина делается с помощью этого кода:


if ( $.browser.msie && $.browser.version if($('#block-commerce-cart-cart').length>0){

var posTop = $('#sidebar').position().top;

$(window).scroll(function(){

var topX = (document.body.scrollTop || document.documentElement.scrollTop);
if (topX > posTop) {
$('#sidebar').addClass('sideCartFixed');
} else {
$('#sidebar').removeClass('sideCartFixed');
}
});

}
}

Этот кусок кода добавляет класс sideCartFixed блоку корзины, в тот момент, когда блок в сайдбаре доходит до верхней границы окна браузера.

CSS:


.sideCartFixed #block-commerce-cart-cart {
position:fixed;
top:0px;
}

Display этого блока переключается в fixed (то есть закреплен абсолютно по отношению к окну браузера).

Увеличение и уменьшение количества товаров

* в корзине
* на странице каталога
* на странице товара

Для того чтобы сделать кнопки изменения кол-ва товаров, я не пользовался модулем Commerce extra, вместо этого написал немного JS и CSS.

JS:

(function ($) { // это нужно чтобы увидеть друпаловский jquery

$(function(){ // обычный onload jquery

$('.field-name-field-prod-variations .form-item-quantity input, .views-field-edit-quantity input').each(function(){
$(this).after('+');
$(this).before('-');

});

$('.quantityPlus').click(function(){
var t = $(this);
var curNum = parseInt(t.prev().attr('value'));
t.prev().attr('value', curNum+1);
return false;
});

$('.quantityMinus').click(function(){
var t = $(this);
var curNum = parseInt(t.next().attr('value'));
if(curNum > 1){
t.next().attr('value', curNum-1);
}
return false;
});

});

})(jQuery);

В CSS не нашел никаких вещей, достойных упоминания. Поэтому если возникли трудности с CSS, могу порекомендовать эти книги.

Сокращение количества шагов при оформлении заказа

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

Поэтому дал ссылку не на корзину (/cart) а сразу на страницу чекаута (/ckeckout/id)

Для того чтобы вывести на странице /ckeckout/id вьюху, которая обычно используется в корзине (с возможностью удаления элементов и изменения их кол-ва) нужно создать блок, в котором написать такой PHP код:


global $user;
if ($order = commerce_cart_order_load($user->uid)) {
$wrapper = entity_metadata_wrapper('commerce_order', $order);
if (commerce_line_items_quantity($wrapper->commerce_line_items, commerce_product_line_item_types()) > 0) {
echo commerce_embed_view('commerce_cart_form', 'default', array($order->order_id), 'cart');
}
}
?>

И в настройках видимости блока написать так:



Дизан

Как обычно делал сам.
Логотип нарисовал по этому тутору

Лайфхаки

Для того чтобы убить в админке по адресу /admin/index ненавистные ссылки "Настройка прав" для каждого модуля, написал такой селектор jQuery:


$('.admin-list.compact a:contains("Настройка прав")').remove();

Стало лучше, но остались пустые блоки, пока что не сообразил как удалить блок, если в одном из его потомков нет текста.

Фотографии продукции делал фотиком Canon S5 IS со штативом

Грабли и трудности, с которыми пришлось столкнуться

Дальше идет нудное описание косяков, которые мне пришлось разруливать. Если вы не делаете сайт на коммерце прямо сейчас - дальше можно не читать. Возможно к тому времени когда вы соберетесь, многие проблемы будут решены.

SEO

Это необходимое требование для борьбы с конкурентами и завоевывания своей небольшой части аудитории и рынка.

Очень внимательно и не один раз послушал доклад Алексея Костина (эта презентация на SlideShare)

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

Simpleping

Simpleping - хороший модуль от того-же Алексея, но я вынужден был его удалить из-за неадекватного поведения файла simpleping.install. Этот файл в некоторых случаях бросал в начало страницы строку ПХП кода с комментами в виде текста. Возможно это можно вылечить простым добавлением в него, но все равно для модуля со стабильной версией на орге это странно. Учитывая тот факт что я использую Ajax для добавления товаров, я решил не рисковать (ведь посторонняя строка в начале AJAX-запроса будет создавать ошибку его выполнения), и удалить его до тех пор пока не будет фикса этой проблемы.

Еще при обновлении БД друпала эта строка вылазит и убивает AJAX запрос, в итоге неприятный косяк с обновлением БД. Вроде все обновляется, но ошибка в середине процесса апдейта не придает ощущения уверенности, не позволяет почувствовать себя спокойно.

При установки/удалении любого модуля, эта строка тоже всплывает в верху сайта.

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

File Field Paths

сокращенно FFP

Для того чтобы SEO было более злобным качественным, решил что кроме alt="" и title="", название каждого файла должно быть не таким каким его делает фотик IMG_2168.JPG, а содержащим нужные ключевые слова и название товара. Для этих целей был употреблен модуль Filefield Paths

Сразу скажу, с этим модулем у меня вышла очень серьезная накладка.
Последняя версия этого модуля 1.0 beta3 (на момент написания статьи) не совместима с последней на данный момент версией коммерца 1.2. При добавлении товара в корзину возникает ошибка

PHP Fatal error: Unsupported operand types in /commerce/modules/cart/commerce_cart.module on line 844

В некоторых случаях при добавлении в корзину (или удалении из нее) сайт просто перестает работать для человека, у которого "неправильная корзина с неправильными товарами".

Для того чтобы очистить корзину и ордеры в коммерце я чистил таблицы commerce_line_item и commerce_order. Однако стоит признаться, что очистка этих таблиц не всегда помогала, и поэтому пришлось восстановить сайт из последнего бекапа, где у меня установлен FFP beta2.

О данной проблеме отписался в issue

Ошибки коммерца

К сожалению вынужден признать, ошибки есть.

Notice: Array to string conversion в функции DatabaseStatementBase->execute() (строка 2135 в файле /includes/database/database.inc).

Notice: unserialize() [function.unserialize]: Error at offset 0 of 5 bytes в функции commerce_price_field_load() (строка 88 в файле /sites/all/modules/commerce/modules/price/commerce_price.module).

Эти ошибки возникает при добавлении картинки к товару. Хотя конечно она связана с тем-же модулем File Field Paths. Патч предложенный в этом issue не помог, а наоборот сделал работу еще менее стабильной

Использованные модули

  • Insert
  • One Click Upload
  • Ckeditor
  • Image Resize Filter
  • Fancybox 2
  • ImageCache actions (для ватермарков)

Еще не выполненные задачи:

Сделать нормальную (красивую) страницу-сообщение об успешном отправлении заказа. Она появляется на страницах с таким урлом: /checkout/order_id/complete

Избавиться от лишнего шага при оформлении заказа (чтобы на одной странице можно было изменить количество, удалить, и сразу-же оформить)

Сделать блок "похожие товары". Сейчас вместо него висит статичный блок из выбранных мною позиций.

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

Кто осилил все - тот молодец! :)

Аватар пользователя Kirill Pliauho
Kirill Pliauho
Аватар пользователя Kirill Pliauho
Kirill Pliauho
Аватар пользователя Андрей Анатольевич
Андрей Анатольевич
Ваш комментарий:
node/103/
vzavitok-ru-drupal-7-commerce
Ссылки
Обзорные статьи, интервью разработчиков и критика CMS Drupal
Joomla vs Drupal
Что лучше джумла или друпал? Мои мысли
на этот счет
Видео
Обучающие видео, интервью и промо-ролики Drupal
Сайты на друпале
«Образцовые» сайты
на друпале. Подборка крупных сайтов рунета.
Недостатки
Некоторые вещи
в друпале меня
напрягают
Рецепты
Учитесь друпалу
на примерах реальных сайтов
Книги
Drupal намного легче
и приятнее осваивать
по книгам
Приемущества
Друпал удобен разработчику
и выгоден клиенту
Может фреймворк?
Когда оправдано применять друпал,
а когда фреймворк?
Обзоры CMS
Когда оправдано использовать
другие CMS?