Тема "dummy" для разработчиков

golubevmark

Здравствуйте, меня зовут Голубев Марк, и я занимаюсь Front-end разработками в компании. Сегодня я вам представлю тему "dummy" для front-end разработчиков.

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


Немного особенностей:

- Я использовал препроцессор Stylus ( http://stylus-lang.com/ ) для генерации CSS файлов. Людям знакомым с препроцессорами, это должно значительно упростить разработку. Исходники расположены в /css/styl/ разделах приложения.

- JavaScript местами был полностью переписал и структурирован. Почти всю JS логику внутри шаблонов я вынес в отдельные файлы, чтобы не мешать код шаблона и скриптов. (Несколько моих рекомендации по оформлению JS я дам ниже)

- Файлы CSS/JS были перенесены в соответствующие подпапки, в корне темы теперь располагаются только шаблоны и системный theme.xml файл с настройками.

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

!!! Хочу обратить внимание что тема для "Магазина" без установленной темы для "Сайта" работать не будет. Это следствие наследования приложений.


Исходники:

скачать dummy на github

Инструкция по началу работы с Dummy для разработчиков: https://developers.webasyst.ru/templates/design-themes/dummy/


Рекомендации:

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

- По мере расширения JS функционала старайтесь создавать js файлы, которые будут содержать функцию конструктор. Далее подключите его асинхронно в теле шаблона через "getScript" и инициализируйте, передавая нужные параметры.

пример шаблон: "checkout.html":

... в конце шаблона

<script>
( function($) {
    $.getScript("{$wa_theme_url}js/checkout.js", function() {
        new Checkout({
            $wrapper: $(".s-checkout-page")
        })
    });
})(jQuery);
</script>

P.S.

На данный момент я представил вам alpha-версию темы, которая будет постепенно дополняться и расширяться. От заинтересованных в этом вопросе людей я бы хотел услышать ваше мнение и рекомендации.

5 июля 2016
  • Zorca Studio 18 февраля 2016 09:24

    Спасибо! Выпилил Stylus и собрал на SASS, все супер!!!

  • Александр 18 февраля 2016 09:42

    Предлагаю отказаться от использования собственной функции отрисовки меню: renderNavItem(например в файле sidebar.html). Функции wa_print_tree вполне достаточно, тем более она выполняется быстрее.

    Добавить произвольную ссылку можно так:

    {if $wa->currentUrl() != $wa_app_url}
        {$_pages[] = [
            id => "all_posts",
            name => "[`All posts`]",
            url => "{$wa_app_url}"
        ]}
    {/if}

    *думаю идея понятна, но если нужно могу предоставить пример работающего кода

    Хотя это не столь важно... Насколько заметил она универсальна для всех приложений, возможно стоит ее определить в файле index.html единожды и вызывать через {call renderNavItem}? Файлы sidebar.html включены же в index.html - она там должна быть видна.

  • golubevmark Webasyst 18 февраля 2016 10:33

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

    Насчёт wa_print_tree идею записал, подумаю.

  • golubevmark Webasyst 19 февраля 2016 08:35

    Александр, про wa_print_tree:

    1. Не могли бы поделиться мнением как вы планировали делать пометку активного раздела ?

    <li class="is-active" ... >

    2. и пометки активных вложенных разделов, используя wa_print_tree ?

    <ul>
            <li>...</li>
            <li>...</li>
            <li class="is-selected has-sub-menu">
                <a>...</a>
                <ul>
                    <li>...</li>
                    <li>...</li>
                    <li class="is-selected has-sub-menu">
                        <a>...</a>
                        <ul>
                            <li class="is-selected">
                                <a>...</a>
                            </li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li>...</li>
        </ul>
  • Александр 19 февраля 2016 09:35

    Да, это небольшой недостаток данной функции, можно пометить только один активный раздел и нельзя изменить имя класса(selected). Но можно пройтись javascript по всем родителям тегам <li> задав им класс "selected", начиная от текущего активного пункта. Так же в этой функции используется идентификатор страницы для определения активного пункта, в каждом приложении способ получить его может отличаться. Именно по этому позже предложил определить вашу функцию единожды и вызывать в подключаемых шаблонах используя {call}.

    Давайте я набросаю примерную реализацию(с функцией wa_print_tree), но выложу ее позже, сегодня уже не успею.

  • golubevmark Webasyst 19 февраля 2016 09:57

    Александр, не стоит. Я примерно понимаю алгоритм. Ну и сложность с выделением активного элемента.

    {wa_print_tree tree=$_pages collapsible_class="has-sub-menu" elem='<a href=":url">:name</a>'}

    Использовать JS для добавления классов по моему не лучшая идея. Я стараюсь избегать подобного подхода.

    Я обсудил этот вопрос с коллегами. В будущем wa_print_tree будет модернизирован, и позволит решить большую часть трудностей. До этого момента остановлюсь на текущем решении.

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

  • Владимир Сергеев 19 февраля 2016 10:14

    Пардон, поправился.
    Почему нельзя использовать такую функцию:

    {function side_pages_tree}
    {foreach $items as $item}
    
    	{if empty($item.hide)}	
    		<li class="{if !empty($item.childs)}has-sub{/if}{if $wa->currentUrl() == $item.url} selected{/if}">
    			<a href="{$item.url}" title="{$item.name}">
    				{$item.name}
    			</a>
    			
    			{if !empty($item.childs)}
    				<ul class="sub-menu">
    					{side_pages_tree items=$item.childs}
    				</ul>
    			{/if}
    		</li>
    	{/if}
    {/foreach}
    {/function}
    {side_pages_tree items=$wa->site->pages()}	
  • golubevmark Webasyst 19 февраля 2016 10:18

    Владимир, ваш алгоритм копирует мой ;)

  • Александр 20 февраля 2016 03:18

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

    Если есть возможность переделать функцию, то я бы предложил создать еще одну отдельно для формирования именно страниц.

    Меня еще смущает подход определения активного элемента по url - всегда он корректно работает? Например у первой ветки адрес вложенного элемента совпадает с адресом начала второй ветки.

  • Можно попробовать в функцию передавать имя глобальной переменной.

    {function name="myfun" item=[] global=""}
        {if !empty($global)}
            {$active_id = $wa->globals("`$global`")}
        {/if}
        {if $item.id == $active_id|default:0}item with id = {$item.id} active{/if}
    {/function}

    И уже в шаблоне page.html присвоить значение:

    {$wa->globals("page_shop_active",$page.id)}

    Затем при выводе передаем значения:

    {foreach $wa->shop->pages() as $_p}
        {myfun item=$_p global="page_shop_active"}
    {/foreach}

    И тогда такую функцию можно будет использовать для страниц и для альбомов Фото



  • golubevmark Webasyst 20 февраля 2016 07:40

    Небольшой итог нашего обсуждения, относительно вывода списка страниц:

    У меня есть "кастомный вывод дерева страниц", в нём можно реализовать любые "хотелки" ( неймнинг активного класса, метка классом родителя-родителей, и т.д. ).

    Вам такой подход не понравился, и вы предложили вариант использовать функцию wa_print_tree. Которая, на данный момент, обладает меньшим функционалом. Чтобы ее привести к моему "кастомному" виду, нужно реализовать связь с page.html через $wa->globals (чтобы передать id активной страницы). В случае, если я хочу сделать подцветку родителя, в котором лежит активная ссылка (а она нужна, чтобы визуально показать иерархию, т.к. ul > ul без класса скрыты ), то добавить немного JS кода.

    С одной стороны вы правы, следует использовать по максимуму возможности фреймворка и не плодить свои "велосипеды". С другой стороны если у разработчика стоит задача оформить как в макете, а wa_print_tree не позволяет это сделать в полном объеме, то мой вариант ему будет полезнее.

    Итог: когда будет обновлена функция wa_print_tree, я её внедрю, а "кастомный вариант" оставлю в коде закомментированном виде.

  • Евгений Леман 29 марта 2016 15:07

    Имеется косяк с зачеркнутой ценой. Как и в теме default и, как следствие, в 90% всех создающихся в мире тем для магазина :) Зачеркнутая цена должна убираться, если не указана для артикула. Допустим у нас продается молоко с выбором объема: 0,5л / 1л / 2л. Цены соответственно: 50 Р / 100 Р / 200 Р. Много у нас на складе скопилось литровых упаковок, срок годности заканчивается... ставим им зачернутую цену в 100 рублей и текущую в 80 руб. Что увидим на витрине? Сначала, если по умолчанию выбрано, например, 0.5 л, - ничего не увидим. Переключим на литровую упаковку и будет "80 руб. (100 руб.)". Зачем переключаем на двухлитровую и получаем "200 руб. (100 руб.)". "Фигасе вы цену в 2 раза подняли" - подумал клиент, закрывая страницу.

  • Syrnik.com 29 марта 2016 15:22

    Я там обычно сравнение price и compare_price ставлю и зачеркнутую показываю, только если она меньше

  • golubevmark Webasyst 30 марта 2016 03:14

    Евгений, спасибо за ваше замечание. Я изучу проблему и сделаю поправки

  • Евгений Леман 30 марта 2016 04:12

    2Сергей:
    Ну такой подход уже индивидуален. По-хорошему же, особенно когда речь идет о массовом использовании или примере-копирки для всех(default), то выводить таки нужно. Может магазин этим хотел сказать "Цены растут! Скорее!". Ведь не зря же админ указывал эту зачеркнутую цену. Ну а если зря, то это уже его косяк. С нас, как говорится, взятки гладки.

    2Марк:
    Тут в дефолтных семействах изначально не тот подход :) Выводить блок зачеркнутой цены нужно всегда. Просто ставить ему display:none по умолчанию, если этой цены нет. А через JS уже управлять его видимостью. Вставлять его лишь при необходимости, прописывая весь HTML-код блока в js, считаю в корне неправильным подходом. Это ломает мухо-котлетный подход. Правильный подход в JS один:

    if(compare_price) $compare.html(that.currencyFormat(compare_price)).show();
    else $compare.hide();
  • Александр 30 марта 2016 05:31

    Евгений, вы ошибаетесь на счет темы Дефолт, судя по этому коду:

    if (compare_price) {
    	if (!this.add2cart.find(".compare-at-price").length) {
    		this.add2cart.prepend('<span class="compare-at-price nowrap"></span>');
    	}
    	this.add2cart.find(".compare-at-price").html(this.currencyFormat(compare_price)).show();
    } else {
    	this.add2cart.find(".compare-at-price").hide();
    }

    происходит ровно то что вы описываете.

    А вот для обсуждаемой темы следует учесть этот момент.

  • Александр 30 марта 2016 05:43

    В файле dummy.shop.css есть строки:

    .s-checkout-page .s-steps-wrapper .s-step-wrapper .s-step-content .s-payment-options .s-payment-item .s-payment-content.is-hidden {
        display: block;
    }

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

    Так же не совсем понятно почему для способов доставки для скрытия доп полей используется смена стилевого свойства display прописыванием его в атрибут style, а для способов оплаты предполагается использование переключение класса is-hidden. Ведь в обоих случаях можно использовать одинаковый способ скрытия формы с доп. полями.

  • Евгений Леман 30 марта 2016 05:58

    Да, в дефолтной теме есть такой код. Не смотрел в JS, т.к. он всё равно не работает. В детали уже не вдавался :) Вот результат: https://gyazo.com/5157931d3ebd8d2ecf0eeefcedcb2f22

    Свежая установка без каких-либо изменений в шаблонах. Зачеркнутая цена в примере, как можно догадаться, указана только у "64Гб-Золотой". При переключении даже на исходный SKU "16Гб-Золотой" она остается, хотя её там не было до этого и быть не должно.

  • Александр 30 марта 2016 08:43

    Не может быть, внимательно посмотрите в настройки каждого артикула. Код работает!

  • Евгений Леман 30 марта 2016 09:37

    Отнюдь! https://demo1-ru.webasyst.com/headphones/audio-tec...

    Вот пример с демо. Зайдите в админку и посмотрите детали этого товара. У синего цвета есть зачеркнутая цена. На витрине же она вовсе не хочет выводиться. И этот баг существовал еще года 3 назад.

  • Александр 31 марта 2016 06:16

    Евгений, все же вы ошибаетесь - скрипт работает исправно, в указанном вами примере проблема в том что массив $sku_features_selectable не содержит данных о зачеркнутой цене:


    Это проблема товара именно на этом демо.

    Сделайте тест на своей установке и вы увидите что все работает.

  • Евгений Леман 31 марта 2016 06:36

    Александр, в чем прикол этих споров? Когда сказали и показали, что ошибка имеется. Если гифки вам лень смотреть, то зайдите в админку демо: https://demo1-ru.webasyst.com/webasyst/shop/?actio...
    Затем установите зачеркнутую цену для... ну например одного лишь артикула "64Гб-Золото": https://gyazo.com/7d1bdbda708ba7578d42bf35755c807a
    Сохраните, перейдите во фронтенд и попереключайте. Единожды выбрав на витрине "64гб-золото" вы всегда будете видеть его зачеркнутую цену на всех других артикулах. К чему этот оффтоп-спор не понимаю и предлагаю его удалить.

  • Евгений Леман 31 марта 2016 06:42

    Кстати в product.js от темы dummy есть еще недочет с зачеркнутыми ценами. Если мы выбираем какую-то услугу, то зачеркнутая цена убирается. Нужно туда-обратно переключить характеристику товара, чтобы она появилась. При этом в теме default и вовсе не идет перерассчет с учетом выбранной услуги(создайте услугу со стоимостью в 100 раз больше стоимости самого артикула для бОльшей наглядности). Лепить гифки лень. Марк и сам проверит, а Александра прошу поверить на слово :)

  • Александр 31 марта 2016 09:08

    Евгений, спор потому что вы неправы. Если вы делаете тест, то делайте его качественно. Вы же не разобрались в проблеме и указываете на то место где проблемы нет. Я вам специально указал что на демо сайте Вебасист пример приводить не стоит - там некорректно срабатывает выборка массива $sku_features_selectable, а это не проблема скрипта управляющего отображением зачеркнутой цены.

    Описанной вами проблемы для темы dummy с зачеркнутыми ценами и взаимодействием с услугами не может быть - в текущем архиве зачеркнутая цена может быть спрятана только если артикул отсутствует и только для варианта покупки по характеристикам. В любом другом случае она просто изменяет свое значение на величину стоимости услуги(есть небольшое уточнение от 18 февраля 2016 15:03 в этой ветке).

  • Евгений Леман 31 марта 2016 09:29

    Вот уж действительно... Если человек - Александр, то это надолго. Skype: e-leman
    Милости просим.

  • Евгений Леман 2 апреля 2016 06:07

    С cart.js также есть небольшой недочет. Но это уже разумнее считать багом приложения. Суть в том, что при клике на чекбокс услуг нам в ответе не приходит data.discount_numeric, по которому легко можно определить наличие скидки. При выборе варианта в селекте всё ок. В половине случаев, как и в теме dummy, требуется скрывать блок скидки, если её нет. Отсутствие discount_numeric заставляет лепить костыли. И этот баг тоже был еще с самых первых версий, т.к. я помню, как еще в марте 2013 лепил костыль, который вырезал " руб." из значения data.discount, чтобы по оставшейся части проверить наличие скидки :)

  • Евгений Леман 2 апреля 2016 06:21

    Ну и раз уж про удобство заговорил, то даю еще 1 оффтоп-реквест. Добавьте в ответы еще и affiliate_numeric. Облегчило бы жизнь и дизайнерам и интеграторам.

  • golubevmark Webasyst 7 апреля 2016 09:26

    Баг, связанный с формированием compare цены, все же имел место быть. Исправил, правда в связи с будущим обновлением исходники на github обновятся позже, ближе к маю.

  • golubevmark Webasyst 4 июля 2016 17:25

    Сегодня наконец-то выложили на github остальные темы семейства dummy для blog, hub, photos, helpdesk, а также обновили site, shop.

    source: https://github.com/webasyst/dummy-theme

    Как всегда, буду рад вашим конструктивным комментариям.

  • Файл header.layout.html не отображается в списке файлов приложения Сайт.



Чтобы добавить комментарий, зарегистрируйтесь или войдите