Сейчас мы с вами реализуем один из интересных функционалов для нашего интернет-магазина, а именно вывод сгруппированных характеристик товара. К сожалению, автор miniShop2 не предусмотрел такую возможность из коробки. Но мы же с вами не лыком шиты, верно?
Реализовывать вывод сгруппированных характеристик мы будем на основе сниппета msProductOption, который идет в комплекте с miniShop2. Приведу сразу код модернизированного сниппета getcharacters:
<?php $product = !empty($product) && $product != $modx->resource->id ? $modx->getObject('msProduct', array('id' => $product)) : $modx->resource; if (!($product instanceof msProduct)) { return "[msProductOptions] The resource with id = {$product->id} is not instance of msProduct."; } if ($data = $product->getOne('Data')) { $optionKeys = $data->getOptionKeys(); } if (empty($optionKeys)) { return ''; } $productData = $product->loadOptions(); $options = array(); $catoptions = array(); foreach ($optionKeys as $key) { // Filter by key if (!empty($onlyOptions) && $onlyOptions[0] != '' && !in_array($key, $onlyOptions)) { continue; } elseif (in_array($key, $ignoreOptions)) { continue; } $option = array(); foreach ($productData as $dataKey => $dataValue) { $dataKey = explode('.', $dataKey); if ($dataKey[0] == $key && (count($dataKey) > 1)) { $option[$dataKey[1]] = $dataValue; } } $option['value'] = $product->get($key); // Filter by groups $skip = !empty($groups) && !in_array($option['category'], $groups) && !in_array($option['category_name'], $groups); if ($skip || empty($option['value'])) { continue; } $options[$key] = $option; if($option["type"] == 'combo-boolean'){ if($option['value'][0] == 1 || $option['value'][0] == "Да"){ $option['value'][0] = "Да"; }else{ $option['value'][0] = "Нет"; } } if(strlen($option['value'][0])){ $catoptions[$option['category']]['name'] = $option['category_name']; $catoptions[$option['category']]['items'][] = $option; } } if($tpl){ $pdoTools = $modx->getService('pdoTools'); return $pdoTools->getChunk($tpl, array( 'cats' => $catoptions, )); }else{ echo "<pre>"; print_r($catoptions); echo "</pre>"; }
Надеюсь, вы заметили, что модернизация коснулась только конца сниппета, следовательно, принимает он все те же параметры, что и msProductOption. Код сниппета нужно сохранить в файле core/elements/snippets/getcharacters.php. Все логику модернизации я подробно расскажу в видео к этому уроку. А мы с вами тем временем должны создать чанк cat_option.tpl:
{foreach $cats as $cat} <h4 class="table-title">{$cat.name}</h4> <table class="table table-bordered table-middle table-dark"> <tbody> {foreach $cat.items as $option} <tr data-key="{$option.key}" data-value="{$option.value[0]}"> <td style="width: 70%;"> {$option.caption} </td> <td style="width: 30%; text-align: center;"> {if $option_type == "combo-options"?} {var $values = $value | split} {foreach $values as $val} <span class="label label-default">{$val}</span> {/foreach} {$option_measure_unit} {else} {if $option.value is array} {$option.value | join : ', '} {else} {$option.value} {/if} {if $option.measure_unit?} {$option.measure_unit} {/if} {/if} </td> </tr> {/foreach} </tbody> </table> {/foreach}
На данном чанке у вас должна нарисоваться полная картина всех преимуществ Fenom и логики его работы. Я сам лично сделал ни один подобный функционал. Согласитесь, что все довольно гибко, главное знать всю логику работы. А нам с вами осталось вызвать сниппет в шаблоне карточки товара, для вывода наших характеристик:
{'@FILE snippets/getcharacters.php' | snippet : [ 'tpl' => '@FILE chunks/cat_option.tpl' ]}
Сейчас мы реализуем отзывы о товаре. Данный блок мы уже разбирали в уроке “Отзывы о товаре в MODx Revo” и здесь у нас принцип не изменится. Мы также будем использовать компонент EasyComm из modStore.pro. Для реализации отзывов о товаре просто перепишем вызовы сниппетов на Fenom синтаксис. И тогда у нас часть шаблона с вкладками примет следующий вид:
<div class="product-tabs"> <ul class="nav nav-tabs responsive" id="myTab" role="tablist"> <li class="nav-item"> <a class="nav-link active" id="characters-tab" data-toggle="tab" href="#characters" role="tab" aria-controls="characters" aria-selected="true">Характеристики</a> </li> <li class="nav-item"> <a class="nav-link" id="delievery-tab" data-toggle="tab" href="#delievery" role="tab" aria-controls="delievery" aria-selected="false">Доставка и оплата</a> </li> <li class="nav-item"> <a class="nav-link" id="reviews-tab" data-toggle="tab" href="#reviews" role="tab" aria-controls="reviews" aria-selected="false">Отзывы</a> </li> </ul> <div class="tab-content" id="myTabContent"> <div class="tab-pane fade show active" id="characters" role="tabpanel" aria-labelledby="characters-tab"> {'@FILE snippets/getcharacters.php' | snippet : [ 'tpl' => '@FILE chunks/cat_option.tpl' ]} </div> <div class="tab-pane fade" id="delievery" role="tabpanel" aria-labelledby="delievery-tab"> {$_modx->getPlaceholder('+delieveryinfo')} </div> <div class="tab-pane fade" id="reviews" role="tabpanel" aria-labelledby="reviews-tab"> <div class="customer-review"> {$_modx->runSnippet('!ecMessages', [])} </div> <div class="leave-review"> {$_modx->runSnippet('!ecForm', [])} </div> </div> </div> </div>
Заметили, что мы еще вывели информацию о доставке и оплате из конфигурации ClientConfig? Думаю, что вы сами сможете создать данный параметр и заполнить его тестовой информацией. А как это сделать я покажу в видео.
БОНУС! Хотите, чтобы сниппет в поиске у вас выглядел примерно так:
Мы с вами реализовали блок с отзывами, поэтому сможем сделать аналогичную штуку. Просто добавьте вот этот блок после блока с ценой в шаблоне товара:
<div class="hidden" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating"> <span itemprop="ratingValue">{$_modx->runSnippet('!ecThreadRating', ['tpl' => 'ratingTpl'])}</span> звезд - основано на <span itemprop="reviewCount">{var $output = '!ecMessagesCount' | snippet: ['tpl' => 'ratingTpl'])} {$output ?: '1'}</span> отзывах </div>
Данный блок с микроразметкой, позволит вам получить звездочки в Google.