Новый дизайн сайта Gosso.ru и как я его делала
Всем привет! С августа-месяца и до сегодняшнего дня я очень часто отказывалась от новых проектов, ссылаясь на текущую загруженность, и наверняка многие мои клиенты хотели бы узнать чем таким срочным и долгим я занималась.
Сегодня я готова ответить на этот вопрос и представить вниманию широкой общественности новый дизайн сайта Gosso.ru.
Должна сразу предупредить, что данная статья будет с уклоном в техническую сторону дела. Она будет полезна для разработчиков шаблонов под InSales и немного полезна для пользователей в плане того что будет содержать реализуемые «фичи» для магазина на InSales.
Поехали!
Это делает невозможным использование полного списка категорий, т.к. он будет формироваться по 30+ секунд.
Также ввиду особенностей InSales при использовании в каком-либо виде иерархии категорий (например, при выводе подкатегорий, при выводе цепочки текущих категорий и т.д.) платформа разворачивает вообще всю структуру категорий, что не может не сказываться на быстродействии. Поэтому мне сразу же пришлось кешировать всю работу с иерархией категорий с помощью liquid-тега cache (по-моему его даже в документации ни insales, ни shopify нет).
Далее, по макету у меня был в мобильной версии полностью раскрываемый без перезагрузки каталог. Как я уже говорила, использование полного списка категорий – отпадает. Поэтому мне пришлось пойти на хитрость и с помощью liquid (и, соответственно, с кешированием) сформировать json, в котором бы присутствовали подкатегории текущей категории. Проблема в том что insales не будет просто так формировать страницу по какому попало урлу. Для такой задачи подойдет только шаблон collection, но он у нас будет использоваться для товарных категорий. Так что же делать? В целом insales может сформировать отдельную страницу по своим сортировкам. Наиболее простым решением здесь было использовать какой-то непопулярный тип сортировки, коим была объявлена сортировка по возрастанию скидки.
В результате страница такой сортировки превратилась в нечто такое, зато стала пригодна для таскания оттуда списка подкатегорий. Написала ajax-запрос по клику на каждый уровень в мобильном каталоге – и дело в шляпе!
В старом дизайне сайта был «быстрый просмотр» товара при наведении, с изображениями, от которого клиент не хотел отказываться в новом дизайне. Этот просмотр в старом дизайне жутко «тормозил» из-за того что загружался (благо, через отдельный запрос к json’ам товаров, а не прямо в html) сразу при открытии страницы, что мне показалось пустой тратой ресурсов несчастных клиентских браузеров, и в своем исполнении эту загрузку я сделала при наведении курсора на товар. Задержка при появлении элемента, конечно, видна, но она не превышает пол-секунды, клиента это устроило.
В каркасе по умолчанию есть работа с избранным, но хранится оно в cookie (вообще технология прошлого века, давно пора отходить от их использования по поводу и без, давно же уже есть localStorage), но клиент хотел чтобы избранное хранилось в личном кабинете покупателя, для чего мне пришлось создать дополнительное поле покупателя, спрятать его из интерфейса (обычными стилями и jquery hide) и отправлять ajax-запросы на его обновление.
Все оказалось не так просто как на словах! Insales для каждого доп. поля покупателя еще и формирует свой id значения, уникальный для каждого покупателя.
Соответственно, при первой записи доп. поля нужно как-то получить этот id значения и сохранить его (например, в тот же localStorage). Пример моего кода (для вышеназванного каркаса тем InSales):
Число 3681475 в коде, само собой, нужно заменить на id поля в реальном проекте.
Все, теперь метод saveFavoritesToField можно использовать для сохранения избранных товаров в доп. поле покупателя. Done!
У клиента существует каталог готовых дизайнов (более 2000 штук), отдельно взятые товары можно заказать с дизайнами из этого каталога. Каждый дизайн представляет собой товар в магазине.
Одновременно на страницу такое количество товаров грузить – не вариант. Благо, они поделены на категории, и в макете для десктопа и планшета у нас всплывающее окно. Ок, делаем отдельный шаблон для категории с каталогами (без шапки и подвала), грузим его через jquery load. Готово.
Но в мобильной версии у нас всплывающего окна нет. Здесь я использовала API плагина owl carousel, который создает карусель дизайнов и ajax-запросы к json категории дизайнов.
Другой вопрос – привязка дизайна к товару. Она осуществляется путем записи все в тот же localStorage javascript-объекта с соответствием товар-дизайн. Уже позже я подумала о том что было бы логичнее и правильнее записывать это в комментарий к позиции заказа. Но на момент разработки эта сущность вообще вылетела у меня из головы :(
Загрузка своего дизайна осуществляется с помощью доп. поля заказа с типом «файл». Такой тип поля есть только в доп. полях заказа, его нет ни в полях покупателя, ни в полях адреса. С помощью довольно древнего плагина ajaxForm происходит ajax-загрузка изображения на сервер к корзине покупателя.
Далее перетаскивание изображения в контейнере осуществляется с помощью jquery ui draggable, масштабирование изображения колесом мыши – самописное (не буду его здесь приводить, т.к. данный кусок кода еще нуждается в оптимизации). Полученные размеры и смещение изображения записываются в доп. поле заказа в виде текста.
Таких изображений можно загрузить до 3х штук, под каждое из них существует свое доп. поле заказа, номер доп. поля хранится в localStorage и меняется при добавлении очередного товара со своим дизайном в корзину.
Отдельная тема – очистка поля с типом файл при удалении товара с дизайном (для простоты было принято что количество товаров в с дизайнами в корзине менять будет нельзя, но удаляться товар-дизайн должен при удалении товара, к которому он принадлежит). Методом проб и ошибок (а также разговоров с одним из разработчиков платформы) был найден ajax-запрос для очистки поля с файлом. Вот код такого запроса:
В целом взаимодействие с дизайнами в корзине можно сделать темой отдельной статьи.
Все в тот же localStorage я записываю автоматически определенный регион и даю покупателю возможность его изменить.
Благо, gosso – клиент трудолюбивый, он согласился сам создавать свой блок для условий самовывоза и доставки под каждый регион, а я вывожу контент всех таких блоков на отдельной странице и делаю к ней ajax-запрос для получения этого контента. Вот и весь секрет :)
С удовольствием отвечу на вопросы клиентов о той или иной функции и возможности ее реализации на их сайтах, а также на вопросы коллег о той или иной не описанной или недостаточно подробной описанной здесь функции.
Пишите на e-mail: iam@insalesguru.ru, а также в скайп: anastasya.kachalova и телеграм: @Kachalova
Всем спасибо за прочтение и до новых встреч!
Сегодня я готова ответить на этот вопрос и представить вниманию широкой общественности новый дизайн сайта Gosso.ru.
Должна сразу предупредить, что данная статья будет с уклоном в техническую сторону дела. Она будет полезна для разработчиков шаблонов под InSales и немного полезна для пользователей в плане того что будет содержать реализуемые «фичи» для магазина на InSales.
Поехали!
Оптимизация и быстродействие
Магазин принимает около 500 заказов в день, имеет около 90 000 товаров и несколько тысяч товарных категорий.Это делает невозможным использование полного списка категорий, т.к. он будет формироваться по 30+ секунд.
Также ввиду особенностей InSales при использовании в каком-либо виде иерархии категорий (например, при выводе подкатегорий, при выводе цепочки текущих категорий и т.д.) платформа разворачивает вообще всю структуру категорий, что не может не сказываться на быстродействии. Поэтому мне сразу же пришлось кешировать всю работу с иерархией категорий с помощью liquid-тега cache (по-моему его даже в документации ни insales, ни shopify нет).

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

Фичи и их реализация
Избранное
Нужно отметить, что делался сайт на каркасе тем InSales, очень с моей точки зрения удобном и функциональном, на нем же сделаны их бесплатные темы «Фортуна», «Карбон» и некоторые другие.В каркасе по умолчанию есть работа с избранным, но хранится оно в cookie (вообще технология прошлого века, давно пора отходить от их использования по поводу и без, давно же уже есть localStorage), но клиент хотел чтобы избранное хранилось в личном кабинете покупателя, для чего мне пришлось создать дополнительное поле покупателя, спрятать его из интерфейса (обычными стилями и jquery hide) и отправлять ajax-запросы на его обновление.
Все оказалось не так просто как на словах! Insales для каждого доп. поля покупателя еще и формирует свой id значения, уникальный для каждого покупателя.
Соответственно, при первой записи доп. поля нужно как-то получить этот id значения и сохранить его (например, в тот же localStorage). Пример моего кода (для вышеназванного каркаса тем InSales):
self.saveFavoritesToField = function(favorites, callback){
showPreloader();
var fieldId = localStorage['fieldId'];
/* нам надо определить id значения поля перед тем как его записывать */
if (typeof fieldId == 'undefined' || fieldId == '') {
$('.js-client-field-id').load('/client_account/contacts form#contacts', function(){
fieldId = $('.js-client-field-id input[name="client[fields_values_attributes][3681475][id]"]').val();
self.postClientField(fieldId, favorites, callback);
localStorage['fieldId'] = fieldId;
});
} else {
self.postClientField(fieldId, favorites, callback);
}
};
self.postClientField = function(fieldId, favorites, callback){
$.ajax({
url: '/client_account/contacts',
method: 'post',
data: '_method=put&client[fields_values_attributes][3681475][hack]=&client[fields_values_attributes][3681475][id]=' + fieldId + '&client[fields_values_attributes][3681475][value]=' + JSON.stringify(favorites),
success: callback,
error: function(){
localStorage['fieldId'] = ''; //если пост завершился ошибкой, значит юзер у нас скорее всего перелогинился в другой ЛК, нужно снова получить id поля (проверка что юзер залогинен – вообще в другом месте)
self.saveFavoritesToField(favorites, callback);
}
});
};
Число 3681475 в коде, само собой, нужно заменить на id поля в реальном проекте.
Все, теперь метод saveFavoritesToField можно использовать для сохранения избранных товаров в доп. поле покупателя. Done!
Выбор готового дизайна

Одновременно на страницу такое количество товаров грузить – не вариант. Благо, они поделены на категории, и в макете для десктопа и планшета у нас всплывающее окно. Ок, делаем отдельный шаблон для категории с каталогами (без шапки и подвала), грузим его через jquery load. Готово.
Но в мобильной версии у нас всплывающего окна нет. Здесь я использовала API плагина owl carousel, который создает карусель дизайнов и ajax-запросы к json категории дизайнов.
Другой вопрос – привязка дизайна к товару. Она осуществляется путем записи все в тот же localStorage javascript-объекта с соответствием товар-дизайн. Уже позже я подумала о том что было бы логичнее и правильнее записывать это в комментарий к позиции заказа. Но на момент разработки эта сущность вообще вылетела у меня из головы :(
Загрузка своего дизайна

Далее перетаскивание изображения в контейнере осуществляется с помощью jquery ui draggable, масштабирование изображения колесом мыши – самописное (не буду его здесь приводить, т.к. данный кусок кода еще нуждается в оптимизации). Полученные размеры и смещение изображения записываются в доп. поле заказа в виде текста.
Таких изображений можно загрузить до 3х штук, под каждое из них существует свое доп. поле заказа, номер доп. поля хранится в localStorage и меняется при добавлении очередного товара со своим дизайном в корзину.

var fieldId = designItem.design.fieldId; //id поля текущего дизайна
var fieldsValuesAttributes = {};
fieldsValuesAttributes[fieldId] = {
hack: fieldId,
field_id: fieldId,
_destroy: 1
};
$.ajax({
url: '/cart_items.json',
method: 'post',
dataType: 'JSON',
data: {
order: {
fields_values_attributes: fieldsValuesAttributes
}
},
success: function(){}
});
В целом взаимодействие с дизайнами в корзине можно сделать темой отдельной статьи.
Показ условий доставки для региона РФ
Как известно, у инсейлс есть свой собственный геотаргетинг. С его помощью можно определить регион покупателя, и сделать что-то если это какой-то определенный регион.Все в тот же localStorage я записываю автоматически определенный регион и даю покупателю возможность его изменить.
Благо, gosso – клиент трудолюбивый, он согласился сам создавать свой блок для условий самовывоза и доставки под каждый регион, а я вывожу контент всех таких блоков на отдельной странице и делаю к ней ajax-запрос для получения этого контента. Вот и весь секрет :)
Заключение
Это описание минимальной части всех фич, используемых на сайте, и их реализации. У клиента еще масса идей для новых фич, да и со старыми еще есть куда стремиться и что оптимизировать.С удовольствием отвечу на вопросы клиентов о той или иной функции и возможности ее реализации на их сайтах, а также на вопросы коллег о той или иной не описанной или недостаточно подробной описанной здесь функции.
Пишите на e-mail: iam@insalesguru.ru, а также в скайп: anastasya.kachalova и телеграм: @Kachalova
Всем спасибо за прочтение и до новых встреч!
0 комментариев