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

Ну что, с теорией разобрались, пора приступать к практике.
Сегодня мы создадим несколько товаров, выведем их на сайте, добавим в корзину и оформим. Наверное, этот урок будет интересен только совсем начинающим работать в 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:
Если у вас есть вопросы по сегодняшней теме - задавайте!

36 комментариев

Александр
Василий, если я хочу вывести товары не строчками, а таблицей 4 строки по 3 товара, то это нужно править только tpl.msProducts.row (делать заполнение товарами через pdoResources)?
Василий Наумкин
Да, нужно править только tpl.msProducts.row, только непонятно, причем здесь pdoResources?
Вообще, забудь про pdoResources когда работаешь с товарами miniShop2 - msProducts умеет всё тоже самое и даже больше.
Саша Туманов
Актуально тоже! А как править tpl.msProducts.row, чтобы получить вывод по три, например, товара в строчке? Есть какая то штатная фишка для этого? Для getResourses всегда пользовался дополнительными чанками, типа first, last, n-th. А тут, чтобы выводилось по три штуки пришлось в сниппете msProducts внутри формирующего вывод цикла свои условия добавлять, типа if($row['idx'] % 3){ ... } и так далее. Если есть возможность так не изворачиваться, расскажите пожалуйста! Или может где описано, да пропустил..
Иван Климчук
В twitter bootstrap и много где это решается версткой. Блоки просто друг за другом располагаются, условия для разбиения по строкам не требуется, если сверстано толково и по сетке, то они сами расставятся, как нужно.
Василий Наумкин
Для getResourses всегда пользовался дополнительными чанками, типа first, last, n-th
В pdoResources и msProducts это тоже работает.
А так в Bootstrap есть верстка блоками - http://getbootstrap.com/css/#grid
<div class="row">
    [[msProducts?
        &tpl=`@INLINE
        <div class="col-md-3">
            [[+pagetitle]] - [[+price]]
        </div>`
    ]]
</div>
Александр
Ваш вариант выводит 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
Василий Наумкин
Чтобы не залазило в футер, весь блок товаров с классами col-md-3 должен быть внутри блока с классом row.
Также еще бывает полезно добавить после этого блока
<div class="crearfix"></div>
Александр
Если col-md-3 обернуть в row , то выводится по одному товару в каждой строчке т.е в столбик получается. Попробовал в шаблоне категорий прописать вместо:

[[!pdoPage?
    &element=`msProducts`
]]
вот так:

<div class="row">
    [[msProducts?
    &tpl=tpl.msProducts.row
    ]]
</div>
вылазить в футер перестали, но распределение по рабочей области беспорядочное (разные интервалы и отступы)
Василий Наумкин
Вот именно второй вариант верный. А дальше нужно читать про float.
Александр
Спасибо. Дописал в шаблоне вот так:

<div class="row">
    float: left !important;
    [[msProducts?
    &tpl=tpl.msProducts.row
    ]]
</div>
И все заработало.
Саша Туманов
Спасибо, за предыдущий ответ! Еще появился вопрос. Во время верстки корзины возникла необходимость слегка отформатировать вывод свойств товара (color, size). В чанке они вызываются как [[+option.color]] и получается "Цвет: glace;". Хотелось бы сделать "Цвет" сереньким, а после значения убрать точку с запятой. Подскажите пожалуйста где можно отловить формирование строчки "Цвет: glace;", чтобы внести коррективы (завернуть "Цвет:" в span например)? Рассмотрел getChunk в pdotools, но не разобрался :(
Василий Наумкин
Вот этот быстрый плейсхолдер выводит строку с цветом в корзине.
Саша Туманов
Ахтыжё! Вчера ведь только об этом читал :) Спасибо большое, а то уже в какие то дебри полез!
Василий Наумкин
На здоровье!
Александр
Василий, кнопка обязательно должна быть обернута в
<form>
? В
<div>
не работает.
Василий Наумкин
Конечно, форма обязательна - именно она и отправляется на сервер для добавления товара в корзину.
Александр
Спасибо.
Andrey Aksyuta
Василий, вопрос в следующем, есть ли возможность настроить так, чтобы при изменении размеров товара менялась его цена?
Andrey Aksyuta
ООоо)) оперативно) сейчас буду изучать) Спасибо)
Andrey Aksyuta
Еще раз здравствуйте, я вчера вечером создал демо-сайт который 24 часа живет, чтобы попробовать ваши платные "допы" для минишопа, а сегодня утром, уже ничго не работает)) Даже по ссылке tefile.modx.pro/create по которой вчера создавал ничего не происходит) перекидывает на админку хостинга. Подскажите, то что я вчера накидал в демо пропало? можно попасть по другому адресу, а не http://s6706.tefile.modx.pro? можно по новой создать демо?
P.S. нашел кнопку добавить демосайт... а что с моим вчерашним?( по новой все создавать?)))) как то я не удачно решил попробовать демо)))
Василий Наумкин
Теперь это делается на хостинге, можно накидывать заново.
Andrey Aksyuta
Понятно, пока ждал ответ и пытался разобраться, так и понял))) я не удачный выбрал момент))) ну чтож)) теперь действительно удобнее будет)) да и хостинг будет активнее пользоваться)))
p.s. жаль что вчерашнее "накидывание" не вернуть))))
Andrey Aksyuta
Вот здесь нашел чтото похожее, но не совсем понятно как это работает... https://bezumkin.ru/modx/minishop2/admin/912/
Сергей Лелеко
Привет! Штатно можно создать такого рода вывод каталога, что если есть под категории в текущей категории, то выводится список этих под категорий, а если только товары то сразу список товаров? Мне пока единственный вариант видится использовать If
Иван Петров
Можно ли сделать количество товара дробным, одна цифра после запятой? и установить начальное значение, например, 1.5, с которого начинается отсчет товара? То, что считает этот сниппет [[ms2_frontend_count_unit]] вижу, но где он сам размещается, не пойму. Буду благодарен за любую подсказку.
Василий Наумкин
Нет, нельзя, только редактированием исходников.
Иван Петров
Спасибо. И еще три вопроса:) 1. Где можно задать лимит количества товара, т.е. чтобы больше данного числа в корзину добавить было нельзя? И можно ли этот лимит вынести в свойства товара? 2. Можно ли добавить две цены, т.е. если количество товара меньше некоторого n, то считается по одной цене, а если больше, то по другой? 3. Василий, а на платной консультации в скайпе, можете подсказать, что именно в исходниках править? В том числе, хотелось бы убрать отрицательные значения количества товара. В корзину с минусом добавить нельзя, но глаза мозолит.
Василий Наумкин
1. Нигде нельзя. Можно расширить класс корзины и управлять количеством и ценами там. 2. Можно добавить новое поле в товар и расширить класс корзины, чтобы переключать цену там. 3. Вот честно, никакого желания нет. Исходники открыты, рядом лежит бесплатный курс по разработке дополнения - разбирайся, это всегда полезно.
Иван Петров
Спасибо.
Иван Петров
При переключении вариантов доставки с различной стоимостью итоговая сумма заказа не меняется без обновления страницы. Отключил все сторонние скрипты, не помогло. В какую сторону хоть смотреть?:( Буду благодарен за любую подсказку.
Иван Петров
Кроме выше описанного, не работают кнопки очистить форму и сделать заказ. До этого делал на тестовом сайте, все работает. Разница между двумя сайтами только в установке Офиса - на сайте, где не отправляется заказ.
Василий Наумкин
Хоть бы сайт показал.
Открывай консоль браузера и смотри ошибки javascript.
Иван Петров
Да вроде нет ошибок. Убрал офис, все равно не пашет http://c25752.tmweb.ru/barxat
Василий Наумкин
Я бы удивился, если бы заработало.
У тебя кнопки снаружи формы. Чтобы работать, они должны быть внутри тега form.
Иван Петров
бгг я идиот. Огромное спасибо! Извини, что на такой тупняк пришлось отвлечься)
bezumkin.ru
Личный сайт Василия Наумкина
Прямой эфир
Александр Наумов
23.07.2024, 00:20:37
Василий, спасибо большое!!
Василий Наумкин
01.07.2024, 11:56:41
Да, верно, именно так. А в контроллере, скорее всего, ловить данные методом post.
Василий Наумкин
26.06.2024, 09:38:15
О, точно, вылезает если не залогинен. Спасибо, исправил!
Василий Наумкин
09.04.2024, 04:45:01
> Ошибка 500 Это не похоже на ошибку Nginx, это скорее всего ошибка PHP - надо смотреть его логи. ...
Василий Наумкин
20.03.2024, 21:21:52
Volledig!
Андрей
14.03.2024, 13:47:10
Василий! Как всегда очень круто! Моё почтение!
russel gal
09.03.2024, 20:17:18
> А этот стоило написать хотя бы затем, чтобы получить комментарий от юзера, который ничего не писал...
Александр Наумов
27.01.2024, 03:06:18
Василий, спасибо! Извини, тупанул.
Василий Наумкин
22.01.2024, 07:43:20
Давай-давай!
Василий Наумкин
24.12.2023, 14:26:13
Спасибо!