FENOM'енальный курс. Часть 5. Миникорзина и корзина товаров с помощью Fenom.

Шаблон MAGAZINE вы можете скачать по ссылке.

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

И что мы видим? У нас заработала миникорзина!

FENOM&#39;енальный курс. Часть 5. Миникорзина и корзина товаров с помощью Fenom.

Отлично! Перейдем к нашей корзине. Логика здесь будет аналогична. Сначала создаем чанк 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'
])}
	

Вот мы с вами и реализовали практически весь функционал интернет-магазина. У нас осталось совсем малое – карточка товара.

FENOM'енальный курс. Часть 5. Миникорзина и корзина товаров с помощью Fenom.

0 Число голосов: 5
4
5
1
5

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

  1. Ирина 23 марта 2019, 16:50 # 0
    Есть ли возможность прикрепления файла покупателем в minishop2?
    1. Петропавловский Артем 23 марта 2019, 16:54 # 0
      Да, можно воспользоваться готовым решением msOrderFiles или написать свой плагин-обработчик.
      1. Ирина 26 марта 2019, 14:28 # 0
        Благодарю, спасибо за ваши уроки.
    2. vk 05 августа 2019, 00:53 # 0
      Добрый день,Подсмотрел у Вас в одном из видео в списке конфигураций что-то вроде ...delivery… но не понял, когда и для чего ее назначили. Возможно ли напомнить.Спасибо.С уважением.
      1. Александр 02 сентября 2019, 19:44 # 0
        delivery — это варианты доставки

      Наши клиенты

      Многие компании уже доверяют нам. Будьте в их числе!

      Хотите реализовать проект?

      Контакты

      Напишите нам - мы расскажем вам много интересного!


      Пермь, шоссе Космонавтов 252, офис 218