Вывод каталога товаров и оформление заказа

Ну что, с теорией разобрались, пора приступать к практике.

Сегодня мы создадим несколько товаров, выведем их на сайте, добавим в корзину и оформим. Наверное, этот урок будет интересен только совсем начинающим работать в MODX и тем, кто впервые видит miniShop2.

Итак, все товары miniShop2 должны принадлежать категории товаров — создадим её. Это можно сделать через контекстное меню, или переключением класса имеющегося ресурса:
Категория товаров — это ресурс MODX c необычным внешним видом и свойствами. В первую очередь, конечно, видно что поле content вынесено на вторую вкладку, а на его месте расположена таблица вложенных ресурсов.

Теперь нам нужно создать несколько товаров и вывести их на сайте. Здесь тоже ничего сложного — это делается или через контекстное меню, или кнопкой в категории:
У товара нужно заполнить название, цену и другие нужные характеристики, и после этого его можно показывать посетителям.

Сниппет msProducts

Это основной сниппет для вывода каталога miniShop2. Он основан на pdoTools и обладает всеми его возможностями. В отличии от pdoResources, сниппет msProducts умеет:
  • Присоединять и выбирать свойства товара из таблицы msProductData
  • Присоединять и выбирать свойства производителя товара из таблицы msVendor
  • Присоединять и выбирать картинки из галереи товара — таблицы msProductFile
  • Фильтровать товары по их связям (параметры &link, &master и &slave)
  • Форматировать цену и вес, согласно системным настройкам.
  • При выводе цены и веча вызывать события для системных плагинов, которые могут их изменить (система скидок msDiscount)
  • Поддержка мультикатегорий товаров MS2. Это когда один товар выводится в разных категориях.
Конечно, вы можете пользоваться pdoResources для вывода каталога, но msProducts делает это гораздо лучше.

Простейший вызов msProducts выглядит так:
[[msProducts]]
Это выведет все товары, которые являются потомками текущей страницы на глубине вложения до 10.

[[msProducts?
	&parents=`4,5`
	&depth=`0`
]]
Это выведет только непосредственных потомков категорий 4 и 5.

Обычно вывод каталога комбинируют с постраничной разбивкой:
[[!pdoPage?
	&element=`msProducts`
	&limit=`10`
]]
[[!+page.nav]]


Вы уже знаете, как работает pdoTools, поэтому всегда можете включить &showLog=`1` и посмотреть, каким образом присоединяются таблицы, чтобы сортировать по полям товара:
[[!pdoPage?
	&element=`msProducts`
	&limit=`10`
	&sortby=`Data.price`
	&sortdir=`ASC`
]]
[[!+page.nav]]


Рекомендую еще прочитать отдельную заметку про msProducts.

Шаблоны товаров и категорий

Как мы помним, внешний вид ресурсов в MODX регулируется шаблонами. Нам нужно создать 2 новых: категория и товар.

Я просто копирую один из существующих шаблонов и меняю у него область контента. Например, вот так выглядит моя категория:
<!DOCTYPE html>
<html>
	<head>
		[[$Head]]
	</head>
	<body>
		[[$Navbar]]
		<div class="container">
			[[$Crumbs]]
			<div id="content" class="inner">
				<h3>[[*pagetitle]]</h3>
				[[!pdoPage?
					&element=`msProducts`
				]]
				[[!+page.nav]]
			</div>
			[[$Footer]]
		</div>
	</body>
</html>
В основном содержимом страницы у нас вывод её названия и вложенных товаров.

Кстати, для редактирования шаблонов и чанков я настоятельно рекомендую вам компонент Ace.

Теперь осталось только назначить наш шаблон категориям и мы увидим наш каталог. Строка товара оформляется стандартным чанком сниппета msProducts — tpl.msProducts.row.


С товарами всё еще проще — нам нужно использовать уже готовый чанк msProduct.content. В нём выводится галерея товара, его основные свойства и форма добавления в корзину.

Советую еще указать шаблон по умолчанию для товаров в настройке ms2_template_product_default.

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

Корзина и оформление заказа

За вывод корзины отвечает сниппет msCart, который нужно вызывать на отдельной странице, некэшированным.

У него есть три чанка: оформление одного товара tpl.msCart.row, оформление всей таблицы tpl.msCart.outer и вывод пустой корзины tpl.msCart.empty.


За оформление заказа отвечает сниппет msOrder, его обычно располагают ниже корзины.
У него есть чанк общего оформления tpl.msOrder.outer, чанк для способа доставки tpl.msOrder.delivery, метода оплаты tpl.msOrder.payment и сообщения об успешном оформлении tpl.msOrder.success.

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

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

В общем, всё максимально автоматизированно.

Заключение

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

Всё делается стандартными сниппетами, у всех у них есть прописанные параметры, в комплекте идут чанки оформления.

Если что-то непонятно — вы всегда можете зайти на страницу сниппет и посмотреть описание параметров. Например вот, msCart:


Если у вас есть вопросы по сегодняшней теме — задавайте!

Следующая заметка
Компонент поиска и фильтрации mSearch2
Предыдущая заметка
Обзор интерфейса miniShop2


Комментарии (36)

  1. Александр 06 августа 2014, 22:31 # 0
    Василий, если я хочу вывести товары не строчками, а таблицей 4 строки по 3 товара, то это нужно править только tpl.msProducts.row (делать заполнение товарами через pdoResources)?
    1. Василий Наумкин 06 августа 2014, 23:06 # 0
      Да, нужно править только tpl.msProducts.row, только непонятно, причем здесь pdoResources?

      Вообще, забудь про pdoResources когда работаешь с товарами miniShop2 — msProducts умеет всё тоже самое и даже больше.
      1. Саша Туманов 09 августа 2014, 23:37 # 0
        Актуально тоже! А как править tpl.msProducts.row, чтобы получить вывод по три, например, товара в строчке? Есть какая то штатная фишка для этого?
        Для getResourses всегда пользовался дополнительными чанками, типа first, last, n-th. А тут, чтобы выводилось по три штуки пришлось в сниппете msProducts внутри формирующего вывод цикла свои условия добавлять, типа if($row['idx'] % 3){… } и так далее.
        Если есть возможность так не изворачиваться, расскажите пожалуйста!
        Или может где описано, да пропустил…
        1. Иван Климчук 10 августа 2014, 04:37 # +1
          В twitter bootstrap и много где это решается версткой. Блоки просто друг за другом располагаются, условия для разбиения по строкам не требуется, если сверстано толково и по сетке, то они сами расставятся, как нужно.
          1. Василий Наумкин 10 августа 2014, 06:12 # 0
            Для getResourses всегда пользовался дополнительными чанками, типа first, last, n-th
            В pdoResources и msProducts это тоже работает.

            А так в Bootstrap есть верстка блоками — getbootstrap.com/css/#grid
            <div class="row">
            	[[msProducts?
            		&tpl=`@INLINE
            		<div class="col-md-3">
            			[[+pagetitle]] - [[+price]]
            		</div>`
            	]]
            </div>
            1. Александр 11 августа 2014, 21:03 # 0
              Ваш вариант выводит 3-и колонки повторяющихся товаров.
              Сделал вот такой вариант:
              <div class="col-md-3 ms2_product">
              	<div class="row">
              		<img src="[[+thumb:default=`[[++assets_url]]components/minishop2/img/web/ms2_small.png`]]" width="120" height="90" />
              	</div>
              	<div class="row span10 col-md-10">
              		<form method="post" class="ms2_form">
              			<a href="[[~[[+id]]]]">[[+pagetitle]]</a>
              			<span class="row flags">[[+new]] [[+popular]] [[+favorite]]</span>
              			<span class="row price">[[+price]] [[%ms2_frontend_currency]]</span>
              			[[+old_price]]
              			<button class="btn btn-default" type="submit" name="ms2_action" value="cart/add"><i class="glyphicon glyphicon-barcode"></i> [[%ms2_frontend_add_to_cart]]</button>
              			<input type="hidden" name="id" value="[[+id]]">
              			<input type="hidden" name="count" value="1">
              			<input type="hidden" name="options" value="[]">
              		</form>
              		<p><small>[[+introtext]]</small></p>
              	</div>
              </div>
              <!--minishop2_popular <i class="glyphicon glyphicon-star" title="[[%ms2_frontend_popular]]"></i>-->
              <!--minishop2_new <i class="glyphicon glyphicon-flag" title="[[%ms2_frontend_new]]"></i>-->
              <!--minishop2_favorite <i class="glyphicon glyphicon-bookmark" title="[[%ms2_frontend_favorite]]"></i>-->
              <!--minishop2_old_price <span class="old_price">[[+old_price]] [[%ms2_frontend_currency]]</span>-->
              
              Почему-то первая строка выводится нормально а дальше даже в футер залазят товары. Менял только tpl.msProducts.row
              1. Василий Наумкин 11 августа 2014, 21:14 # 0
                Чтобы не залазило в футер, весь блок товаров с классами col-md-3 должен быть внутри блока с классом row.

                Также еще бывает полезно добавить после этого блока
                <div class="crearfix"></div>
                1. Александр 11 августа 2014, 21:57 # 0
                  Если col-md-3 обернуть в row, то выводится по одному товару в каждой строчке т.е в столбик получается.
                  Попробовал в шаблоне категорий прописать вместо:
                  [[!pdoPage?
                  	&element=`msProducts`
                  ]]
                  
                  вот так:
                  <div class="row">
                  	[[msProducts?
                  	&tpl=tpl.msProducts.row
                  	]]
                  </div>
                  
                  вылазить в футер перестали, но распределение по рабочей области беспорядочное (разные интервалы и отступы)
                  1. Василий Наумкин 11 августа 2014, 22:21 # 0
                    Вот именно второй вариант верный. А дальше нужно читать про float.
                    1. Александр 11 августа 2014, 23:11 # 0
                      Спасибо.
                      Дописал в шаблоне вот так:
                      <div class="row">
                      	float: left !important;
                      	[[msProducts?
                      	&tpl=tpl.msProducts.row
                      	]]
                      </div>
                      
                      И все заработало.
      2. Саша Туманов 11 августа 2014, 22:28 # 0
        Спасибо, за предыдущий ответ!
        Еще появился вопрос. Во время верстки корзины возникла необходимость слегка отформатировать вывод свойств товара (color, size). В чанке они вызываются как [[+option.color]] и получается «Цвет: glace;». Хотелось бы сделать «Цвет» сереньким, а после значения убрать точку с запятой.
        Подскажите пожалуйста где можно отловить формирование строчки «Цвет: glace;», чтобы внести коррективы (завернуть «Цвет:» в span например)?
        Рассмотрел getChunk в pdotools, но не разобрался :(
        1. Василий Наумкин 11 августа 2014, 22:31 # 0
          Вот этот быстрый плейсхолдер выводит строку с цветом в корзине.
          1. Саша Туманов 11 августа 2014, 22:36 # 0
            Ахтыжё! Вчера ведь только об этом читал :)
            Спасибо большое, а то уже в какие то дебри полез!
            1. Василий Наумкин 11 августа 2014, 22:37 # 0
              На здоровье!
        2. Александр 15 августа 2014, 21:55 # 0
          Василий, кнопка обязательно должна быть обернута в
          <form>
          ? В
          <div>
          не работает.
          1. Василий Наумкин 15 августа 2014, 21:59 # 0
            Конечно, форма обязательна — именно она и отправляется на сервер для добавления товара в корзину.
          2. Александр 15 августа 2014, 22:07 # 0
            Спасибо.
            1. Andrey Aksyuta 19 сентября 2014, 10:13 # 0
              Василий, вопрос в следующем, есть ли возможность настроить так, чтобы при изменении размеров товара менялась его цена?
                1. Andrey Aksyuta 19 сентября 2014, 10:36 # 0
                  ООоо)) оперативно) сейчас буду изучать) Спасибо)
                  1. Andrey Aksyuta 21 сентября 2014, 10:56 # 0
                    Еще раз здравствуйте, я вчера вечером создал демо-сайт который 24 часа живет, чтобы попробовать ваши платные «допы» для минишопа, а сегодня утром, уже ничго не работает))
                    Даже по ссылке test.modx.pro/create по которой вчера создавал ничего не происходит)
                    перекидывает на админку хостинга.
                    Подскажите, то что я вчера накидал в демо пропало? можно попасть по другому адресу, а не s6706.test.modx.pro? можно по новой создать демо?

                    P.S. нашел кнопку добавить демосайт… а что с моим вчерашним?( по новой все создавать?)))) как то я не удачно решил попробовать демо)))
                    1. Василий Наумкин 21 сентября 2014, 10:59 # 0
                      Теперь это делается на хостинге, можно накидывать заново.
                      1. Andrey Aksyuta 21 сентября 2014, 11:06 # 0
                        Понятно, пока ждал ответ и пытался разобраться, так и понял))) я не удачный выбрал момент))) ну чтож)) теперь действительно удобнее будет)) да и хостинг будет активнее пользоваться)))

                        p.s. жаль что вчерашнее «накидывание» не вернуть))))
                  2. Andrey Aksyuta 19 сентября 2014, 10:35 # 0
                    Вот здесь нашел чтото похожее, но не совсем понятно как это работает…
                    bezumkin.ru/modx/minishop2/admin/912/
                  3. Сергей Лелеко 20 сентября 2014, 20:37 # 0
                    Привет!
                    Штатно можно создать такого рода вывод каталога, что если есть под категории в текущей категории, то выводится список этих под категорий, а если только товары то сразу список товаров? Мне пока единственный вариант видится использовать If
                    1. Иван Петров 01 октября 2014, 13:08 # 0
                      Можно ли сделать количество товара дробным, одна цифра после запятой?
                      и установить начальное значение, например, 1.5, с которого начинается отсчет товара?
                      То, что считает этот сниппет [[ms2_frontend_count_unit]] вижу, но где он сам размещается, не пойму.
                      Буду благодарен за любую подсказку.
                      1. Василий Наумкин 01 октября 2014, 13:19 # 0
                        Нет, нельзя, только редактированием исходников.
                        1. Иван Петров 01 октября 2014, 15:12 # 0
                          Спасибо. И еще три вопроса:)
                          1. Где можно задать лимит количества товара, т.е. чтобы больше данного числа в корзину добавить было нельзя? И можно ли этот лимит вынести в свойства товара?
                          2. Можно ли добавить две цены, т.е. если количество товара меньше некоторого n, то считается по одной цене, а если больше, то по другой?
                          3. Василий, а на платной консультации в скайпе, можете подсказать, что именно в исходниках править? В том числе, хотелось бы убрать отрицательные значения количества товара. В корзину с минусом добавить нельзя, но глаза мозолит.
                          1. Василий Наумкин 01 октября 2014, 15:18 # 0
                            1. Нигде нельзя. Можно расширить класс корзины и управлять количеством и ценами там.
                            2. Можно добавить новое поле в товар и расширить класс корзины, чтобы переключать цену там.
                            3. Вот честно, никакого желания нет. Исходники открыты, рядом лежит бесплатный курс по разработке дополнения — разбирайся, это всегда полезно.
                            1. Иван Петров 01 октября 2014, 15:30 # 0
                              Спасибо.
                      2. Иван Петров 06 октября 2014, 00:17 # 0
                        При переключении вариантов доставки с различной стоимостью итоговая сумма заказа не меняется без обновления страницы. Отключил все сторонние скрипты, не помогло. В какую сторону хоть смотреть?:( Буду благодарен за любую подсказку.
                        1. Иван Петров 09 октября 2014, 00:45 # 0
                          Кроме выше описанного, не работают кнопки очистить форму и сделать заказ. До этого делал на тестовом сайте, все работает. Разница между двумя сайтами только в установке Офиса — на сайте, где не отправляется заказ.
                          1. Василий Наумкин 09 октября 2014, 06:03 # 0
                            Хоть бы сайт показал.

                            Открывай консоль браузера и смотри ошибки javascript.
                            1. Иван Петров 14 октября 2014, 13:20 # 0
                              Да вроде нет ошибок. Убрал офис, все равно не пашет c25752.tmweb.ru/barxat
                              1. Василий Наумкин 14 октября 2014, 13:30 # 0
                                Я бы удивился, если бы заработало.

                                У тебя кнопки снаружи формы. Чтобы работать, они должны быть внутри тега form.
                                1. Иван Петров 14 октября 2014, 13:47 # +1
                                  бгг я идиот. Огромное спасибо! Извини, что на такой тупняк пришлось отвлечься)
                          Добавление новых комментариев отключено.