Данный урок будет задевать не только конкретные опции, а вообще все опции в целом. Логика их добавления примерно одинакова. Для цвета мы будем использовать платный компонент msOptionsColor из modstore.pro.
Начнем непосредственно с выбора цвета. Для активации вкладки “Цвета” у товаров, нам необходимо перейти в системные настройки и задать значение для ключа msoptionscolor_working_templates – идентификатор шаблона товара. Должно получиться примерно как на скриншоте:

Теперь у нас должна быть активна вкладка “Цвета” у товаров с шаблоном, имеющим id 11 ( в моем случае). Предлагаю вам выбрать товар, жертву экспериментов, на котором мы с вами будем проводить опыты. Сразу напомню, что мы еще будем реализовывать размеры товаров, поэтому желательно выбрать такой товар, где есть и то и другое. Например, кроссовки:

Заметили появившуюся вкладку цвета? Сейчас мы с вами будем с ней работать. Только перед тем как приступить заполните цвета и размеры так же как у меня на скриншоте выше. Заполнили? Отлично! Открываем вкладку цвета и видим, какие именно опции нам необходимо отредактировать:

Кликаем “редактировать” и заполняем соотношение цвета текстового и цвета визуального:


Отлично! Все получилось и цвета можно выводить в карточке товара. За это у нас отвечает сниппет msOptionsColor, который мы вызываем в шаблоне на месте наших цветов товара:
{$_modx->runSnippet('msOptionsColor', [
'options' => 'color',
'tpl' => '@FILE chunks/color_product.tpl'
])}
И, конечно, нужно создать чанк color_product.tpl:
{foreach $colors as $name => $color}
<div class="product-color">
<div class="sub-title">Выберите цвет:</div>
<div class="colors">
{foreach $color as $row index=$index}
<div class="item form-check form-check-inline">
<input class="form-check-input" type="radio" name="options[{$name}]" value="{$row.value}" {$index ? '' : 'checked'}>
{if $row.pattern?}
<div>
<img alt="" title="{$row.value}" class="img-rounded" style="background-image:url({$row.pattern});width:25px;height:25px;">
</div>
{else}
<div>
<img alt="" title="{$row.value}" class="img-rounded" style="background-color:#{$row.color};width:25px;height:25px;">
</div>
{/if}
</div>
{/foreach}
</div>
</div>
{/foreach}
Отлично! Цвета мы вывели. Приступим к размерам?
Для вывода размеров я использую сниппет getsizes, который производит сортировку значений размеров. Тут тоже важно заметить, что постоянно возникает проблема с сортировкой опций. Сниппет getsizes:
<?php
$id = $modx->resource->id;
$pdoTools = $modx->getService('pdoTools');
$product = $modx->getObject("msProduct", $id);
$sizes = $product->get("size");
if(count($sizes)){
asort($sizes);
$row['options'][] = $sizes;
$res = $pdoTools->getChunk('@FILE chunks/size_product.tpl', $row);
$modx->setPlaceholder("sizes", $res);
}
И, конечно, чанк size_product.tpl (обратите внимание как он вызван в API):
{foreach $options as $name => $values}
{foreach $values as $value => $val}
<span class="pick-size-class {if $value == 0}active{/if}">
<input class="hidden" type="radio" name="options[size]" value="{$val}" id="size[{$val}]" required {$value ? '' : 'checked'}/>{$val}
</span>
{/foreach}
{/foreach}
Как вы успели заметить данный сниппет сортирует опции и выставляет плейсхолдер sizes, который мы можем обработать в шаблоне:
{'@FILE snippets/getsizes.php' | snippet : []}
{if $_modx->getPlaceholder('sizes')?}
<div class="product-size">
<div class="sub-title">Выберите размер (<a href="#" data-toggle="modal" data-target="#sizetable">уточнить</a>):</div>
{$_modx->getPlaceholder('sizes')}
</div>
{/if}
Блок размеров был написан недостаточно красиво, кто улучшит его и напишет в комментариях свое решение, ждет бонус от меня, конечно, если ваше решение будет иметь право на жизнь.
А теперь вернемся с вами к нашей задаче. В начале статьи я написал, что мы затронем не только конкретные опции, а вообще опции в целом, как их выводить и принцип их работы. Пожалуй, до следующего урока я оставлю данный вопрос открытым, а вам предлагаю посмотреть на сходства размеров и цветов, так же увидеть в чем их различия. Дам маленькую подсказку: HTML-форма и ее элементы.
<?php if(!$id){ $id = $modx->resource->id; } $pdoTools = $modx->getService("pdoTools"); $product = $modx->getObject("msProduct", $id); if ($product){ $sizes = $product->get("size"); if(count($sizes)){ asort($sizes); $row['options'][] = $sizes; $res = $pdoTools->getChunk("@FILE chunks/tpl_sizes.tpl", $row); //$modx->setPlacegolder("sizes", $res); return $res; } }И тогда его можно будет вызвать вот так:{$_modx->runSnippet("@FILE snippets/get_sizes.php", ['id' => $id])}То есть в параметр «id» передавать идентификатор интересующего нас ресурса.{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 | htmlent}</a><br> {if $product.options?} {foreach $product.options as $key => $option} {if $key in ['modification','modifications','msal']}{continue}{/if} {set $caption = $product[$key ~ '.caption']} {set $caption = $caption ? $caption : ('ms2_product_' ~ $key) | lexicon} {if $option is array} {$caption} - {$option | join : '; '} <br> {else} {$caption} - {$option} <br> {/if} {/foreach} {/if} </td> <td class="count"> <form method="post" class="ms2_form form-inline" role="form"> <input type="hidden" name="key" value="{$product.key}"> <div class="form-group"> <input type="number" name="count" value="{$product.count}" max-legth="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> руб.</td> <td class="nds_price"> <span>{$product.cost}</span> руб. </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}Я намеренно вывел кусок с выводом товаров полностью. Обратите внимание на конструкции с $product.options<img alt="" title="{$row.value}" class="img-rounded" style="background-image:url({$row.pattern});width:25px;height:25px;">— почему img, а не div? img без srс и в добавок с пустым alt — дважды не валидно)