Друзья! Мы с вами дошли до корзины, я вас поздравляю. На самом деле данный урок будет проще относительно предыдущего. Начнем мы с вами с миникорзины, для начала создадим чанк нашей миникорзины minicart.tpl:
<div id="msMiniCart" class="cart {$total_count > 0 ? 'full' : ''}"> <div class="empty"> <a href="{$_modx->makeUrl(8)}" class="inliner vam"> <span class="carticon"> <i class="fa fa-shopping-cart"></i> <span class="ms2_total_count count">0</span> </span> <div class="cart-info hidden-sm"> <span class="title">Корзина</span> <span class="info"> <span class="ms2_total_cost">0</span> <i class="fa fa-ruble"></i> </span> </div> </a> </div> <div class="not_empty"> <a href="{$_modx->makeUrl(8)}" class="inliner vam"> <span class="carticon"> <i class="fa fa-shopping-cart"></i> <span class="ms2_total_count count">{$total_count}</span> </span> <div class="cart-info hidden-sm"> <span class="title">Корзина</span> <span class="info"> <span class="ms2_total_cost">{$total_cost}</span> <i class="fa fa-ruble"></i> </span> </div> </a> </div> </div>
И в чанке header сделаем вызов сниппета msMiniCart:
{$_modx->runSnippet('!msMiniCart', [ 'tpl' => '@FILE chunks/minicart.tpl' ])}
И что мы видим? У нас заработала миникорзина!
Отлично! Перейдем к нашей корзине. Логика здесь будет аналогична. Сначала создаем чанк cart.tpl:
<div id="msCart" class="table-responsives"> {if !count($products)} <div class="alert alert-info">{'ms2_cart_is_empty' | lexicon}</div> {else} <table class="table table-cart"> <tbody> <tr class="header"> <th class="cart-image"> </th> <th class="">Наименование</th> <th class="">Количество</th> <th class="">Цена</th> <th class="">Удалить</th> </tr> {foreach $products as $product} <tr id="{$product.key}"> <td class="cart-image"> {if $product.image?} <img src="{$product.image}" alt="{$product.pagetitle | htmlent}" title="{$product.pagetitle | htmlent}"> {else} <img src="{$_modx->getPlaceholder('+noimage')}" alt="{$product.pagetitle | htmlent}" title="{$product.pagetitle | htmlent}"/> {/if} </td> <td class=""><a href="{$product.id | url}">{$product.pagetitle}</a><br> {if $product.options?} <div class="small"> {$product.options | join : '; '} </div> {/if} </td> <td class="count"> <form method="post" class="ms2_form" role="form"> <input type="hidden" name="key" value="{$product.key}"> <div class="form-group"> <input type="number" name="count" value="{$product.count}" max-length="4" class="input-sm form-control"> шт. <button class="btn btn--cart" type="submit" name="ms2_action" value="cart/change"><i class="fa fa-refresh" aria-hidden="true"></i></button> </div> </form> </td> <td class="price"><span>{$product.price}</span> {'ms2_frontend_currency' | lexicon}</td> <td class=""> <form method="post" class="ms2_form"> <input type="hidden" name="key" value="{$product.key}"> <button class="btn btn--cart" type="submit" name="ms2_action" value="cart/remove" title="Удалить"><i class="fa fa-times" aria-hidden="true"></i> </button> </form> </td> </tr> {/foreach} <tr class="footer"> <th class="total" colspan="2">Итого:</th> <th class="total_count"><span class="ms2_total_count">{$total.count}</span> шт.</th> <th class="total_cost"><span class="ms2_total_cost">{$total.cost}</span> {'ms2_frontend_currency' | lexicon}</th> <th> </th> </tr> </tbody> </table> <div class="text-center"> <a href="{$_modx->makeUrl(9)}" class="btn btn-blue">Оформить заказ</a> </div> {/if} </div>
И теперь вызовем сниппет msCart в шаблоне корзины:
{$_modx->runSnippet('!msCart', [ 'tpl' => '@FILE chunks/cart.tpl' ])}
Сейчас реализуем с вами оформление заказа. Создаем чанк order.tpl:
<form class="form-horizontal ms2_form" id="msOrder" method="post"> <div class="row"> <div class="col-md-6"> <h4>{'ms2_frontend_credentials' | lexicon}:</h4> <hr class="lines"> {foreach ['email','receiver','phone'] as $field} <div class="form-group input-parent row"> <label class="col-sm-3 control-label" for="{$field}"> {('ms2_frontend_' ~ $field) | lexicon} <span class="required-star">*</span> </label> <div class="col-sm-9"> <input type="text" id="{$field}" placeholder="{('ms2_frontend_' ~ $field) | lexicon}" name="{$field}" value="{$form[$field]}" class="form-control{($field in list $errors) ? ' error' : ''}"> </div> </div> {/foreach} <div class="form-group input-parent row"> <label class="col-sm-3 control-label" for="coupon_code">Скидочный купон</label> <div class="col-sm-9"> <input type="coupon_code" id="coupon_code" placeholder="XXXXX-XXXX-XXXX-XXXX" name="coupon_code" value="{$order.coupon_code}" class="form-control"> </div> </div> <div class="form-group input-parent row"> <label class="col-sm-3 control-label" for="comment"> <span class="required-star">*</span> {'ms2_frontend_comment' | lexicon}</label> <div class="col-sm-9"> <textarea name="comment" id="comment" placeholder="{'ms2_frontend_comment' | lexicon}" class="form-control{('comment' in list $errors) ? ' error' : ''}">{$form.comment}</textarea> </div> </div> </div> <div class="col-md-6"> <h4>{'ms2_frontend_address' | lexicon}:</h4> <hr class="lines"> {foreach ['index','region','city'] as $field} <div class="form-group input-parent row"> <label class="col-sm-3 control-label" for="{$field}"> <span class="required-star">*</span> {('ms2_frontend_' ~ $field) | lexicon} </label> <div class="col-sm-9"> <input type="text" id="{$field}" placeholder="{('ms2_frontend_' ~ $field) | lexicon}" name="{$field}" value="{$form[$field]}" class="form-control{($field in list $errors) ? ' error' : ''}"> </div> </div> {/foreach} <div class="form-group input-parent row"> <label class="col-sm-3 control-label" for="street"> <span class="required-star">*</span> {'ms2_frontend_street' | lexicon}</label> <div class="col-sm-9"> {foreach ['street','building','room'] as $field} <div class="form-group"> <input type="text" id="{$field}" placeholder="{('ms2_frontend_' ~ $field) | lexicon}" name="{$field}" value="{$form[$field]}" class="form-control{($field in list $errors) ? ' error' : ''}"> </div> {/foreach} </div> </div> </div> </div> <div class="row"> <div class="col-md-6" id="payments"> <h4>{'ms2_frontend_payments' | lexicon}:</h4> <hr class="lines"> <div class="form-group row"> <label class="col-sm-3 control-label"><span class="required-star">*</span> {'ms2_frontend_payment_select' | lexicon}</label> <div class="col-sm-9"> {foreach $payments as $payment index=$index} {var $checked = !$order.payment && $index == 0 || $payment.id == $order.payment} <div class="checkbox"> <label class="payment input-parent"> <input type="radio" name="payment" value="{$payment.id}" id="payment_{$payment.id}" {$checked ? 'checked' : ''}> {if $payment.logo?} <img src="{$payment.logo}" alt="{$payment.name}" title="{$payment.name}"/> {else} {$payment.name} {/if} {if $payment.description?} <p class="small"> {$payment.description} </p> {/if} </label> </div> {/foreach} </div> </div> </div> <div class="col-md-6" id="deliveries"> <h4>{'ms2_frontend_deliveries' | lexicon}:</h4> <hr class="lines"> <div class="form-group row"> <label class="col-sm-3 control-label"> <span class="required-star">*</span> {'ms2_frontend_delivery_select' | lexicon} </label> <div class="col-sm-9"> {foreach $deliveries as $delivery index=$index} {var $checked = !$order.delivery && $index == 0 || $delivery.id == $order.delivery} <div class="checkbox"> <label class="delivery input-parent"> <input type="radio" name="delivery" value="{$delivery.id}" id="delivery_{$delivery.id}" data-payments="{$delivery.payments | json_encode}" {$checked ? 'checked' : ''}> {if $delivery.logo?} <img src="{$delivery.logo}" alt="{$delivery.name}" title="{$delivery.name}"/> {else} {$delivery.name} {/if} {if $delivery.description?} <p class="small"> {$delivery.description} </p> {/if} </label> </div> {/foreach} </div> </div> </div> </div> <hr/> <div class="well row"> <div class="offset-sm-2 col-sm-10"> <h3>{'ms2_frontend_order_cost' | lexicon}: <span id="ms2_order_cost">{$order.cost ?: 0}</span> {'ms2_frontend_currency' | lexicon} </h3> <button type="submit" name="ms2_action" value="order/submit" class="btn btn-blue ms2_link"> {'ms2_frontend_order_submit' | lexicon} </button> </div> </div> </form>
Вызовем сниппет msOrder в шаблоне оформления заказа:
{$_modx->runSnippet('!msOrder', [ 'tpl' => '@FILE chunks/order.tpl' ])}
Но это еще не все. После того, как пользователь оформит заказ, должна отобразится так называемая страница “Спасибо”. За ее отображение отвечает сниппет msGetOrder. И, конечно, нам с вами необходимо создать чанк getorder.tpl:
<p>Уважаемый покупатель! Ваш заказ успешно оформлен и поставлен в очередь на обработку. В ближайшее время с вами свяжется наш специалист для уточнения деталей заказа. Заказу был присвоен номер:</p> <div class="text-center"> <span class="order_num">{$order.num}</span> </div> <div id="msCart" class="msgetorder"> <div class="table-responsives"> <table class="table table-striped"> <tr class="header"> <th class="image"> </th> <th class="title">{'ms2_cart_title' | lexicon}</th> <th class="count">{'ms2_cart_count' | lexicon}</th> <th class="price">{'ms2_cart_cost' | lexicon}</th> </tr> {foreach $products as $product} <tr> <td class="image"> {if $product.image?} <img src="{$product.image}" alt="{$product.pagetitle | htmlent}" title="{$product.pagetitle | htmlent}" width="40"/> {else} <img src="{$_modx->getPlaceholder('+noimage')}" alt="{$product.pagetitle | htmlent}" title="{$product.pagetitle | htmlent}" width="40"/> {/if} </td> <td class="title"> {if $product.id?} <a href="{$product.id | url}">{$product.name}</a> {else} {$product.name} {/if} {if $product.options?} <div class="small"> {$product.options | join : '; '} </div> {/if} </td> <td class="count">{$product.count} {'ms2_frontend_count_unit' | lexicon}</td> <td class="price">{$product.price} {'ms2_frontend_currency' | lexicon}</td> </tr> {/foreach} <tr class="footer"> <th class="total" colspan="2">{'ms2_cart_total' | lexicon}:</th> <th class="total_count"> <span class="ms2_total_count">{$total.cart_count}</span> {'ms2_frontend_count_unit' | lexicon} </th> <th class="total_cost"> <span class="ms2_total_cost">{$total.cart_cost}</span> {'ms2_frontend_currency' | lexicon} </th> </tr> </table> </div> <h4> {'ms2_frontend_order_cost' | lexicon}: {if $total.delivery_cost} {$total.cart_cost} {'ms2_frontend_currency' | lexicon} + {$total.delivery_cost} {'ms2_frontend_currency' | lexicon} = {/if} <strong>{$total.cost}</strong> {'ms2_frontend_currency' | lexicon} </h4> </div>
И вызовем сниппет msGetOrder сразу после msOrder. Не переживайте, msGetOrder и msOrder не помешают друг другу в работе. Они оба отслеживают GET-параметр msorder в адресной строке.
{$_modx->runSnippet('!msGetOrder', [ 'tpl' => '@FILE chunks/getorder.tpl' ])}
Вот мы с вами и реализовали практически весь функционал интернет-магазина. У нас осталось совсем малое – карточка товара.