Друзья! Мы с вами дошли до корзины, я вас поздравляю. На самом деле данный урок будет проще относительно предыдущего. Начнем мы с вами с миникорзины, для начала создадим чанк нашей миникорзины 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'
])}
Вот мы с вами и реализовали практически весь функционал интернет-магазина. У нас осталось совсем малое – карточка товара.