Вывести опции по категориям

Здравствуйте!

Пытаюсь сделать универсальный вариант для интернет-магазина, где будут категории смартфоны, аксессуары, ноутбуки, планшеты и т.д

У всех категорий свои опции, но для клиента хочется сделать вывод более понятным и удобным. Пример:



То есть, основные характеристики, процессор, дисплей и т.д, а под ними уже выводить необходимые опции.

Во всех категориях названия опций и сами опции будут отличаться, не хочется делать для каждой категории свой шаблон, т.к это долго и сложно в управлении в дальнейшем.

Подскажите, есть ли какие-то способы реализации?

Использую: minishop2, mSearch2.
Ivan
06 сентября 2018, 15:37
modx.pro
1
1 164
0

Комментарии: 3

Андрей Перевезенцев
19 сентября 2018, 12:38
0
Присоединяюсь. Удалось реализовать?
    Ivan
    23 октября 2018, 14:49
    0
    Пока нет, есть вариант делать вывод через MIGX, но в таком случае это запарно, т.к придется заполнять 2 раза одно и тоже, чтоб и в фильтре были значения и визуально в карточке товара.

    Как вариант можно использовать платный компонент — msextrafields, как попробую — отпишу.
    Ivan
    24 октября 2018, 13:37
    0
    Если решение кому пригодится:

    Создаем сниппет msProductOptionsEx

    <?php
    /** @var modX $modx */
    /** @var array $scriptProperties */
    
    $tpl = $modx->getOption('tpl', $scriptProperties, 'tpl.msProductOptions');
    if (!empty($input) && empty($product)) {
        $product = $input;
    }
    
    $emptyGroupName = $modx->getOption('emptyGroupName', $scriptProperties, 'Empty');
    $groupSortBy = $modx->getOption('groupSortBy', $scriptProperties, 'rank');
    
    $product = !empty($product) && $product != $modx->resource->id
        ? $modx->getObject('msProduct', $product)
        : $modx->resource;
    if (!($product instanceof msProduct)) {
        return "[msProductOptions] The resource with id = {$product->id} is not instance of msProduct.";
    }
    
    $ignoreOptions = array_map('trim', explode(',', $modx->getOption('ignoreOptions', $scriptProperties, '')));
    $onlyOptions = array_map('trim', explode(',', $modx->getOption('onlyOptions', $scriptProperties, '')));
    $groups = !empty($groups)
        ? array_map('trim', explode(',', $groups))
        : array();
    /** @var msProductData $data */
    if ($data = $product->getOne('Data')) {
        $optionKeys = $data->getOptionKeys();
    }
    if (empty($optionKeys)) {
        return '';
    }
    $productData = $product->loadOptions();
    
    $optionCategories = array();
    $categoryIds = 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;
        }
    
        $categoryId = $option['category'];
        if (empty($categoryId)) {
            $categoryId = 0;
        }
    
        if (!isset($optionCategories[$categoryId])) {
            $optionCategories[$categoryId] = array(
                'name' => $categoryId ? $option['category_name'] : $emptyGroupName,
                'id' => $option['category'],
                'rank' => $categoryId ? $option['category'] : PHP_INT_MAX,
                'idx' => count($optionCategories),
                'options' => array()
            );
            $categoryIds[] = $categoryId;
        }
        $optionCategories[$categoryId]['options'][$key] = $option;
    }
    
    /** @var pdoFetch $pdoFetch */
    $pdoFetch = $modx->getService('pdoFetch');
    $categories = $pdoFetch->getCollection('modCategory', array('id:IN' => $categoryIds));
    
    switch ($groupSortBy) {
        case 'rank':
            foreach ($categories as $category) {
                $categoryId = $category['id'];
                if (!isset($optionCategories[$categoryId])) {
                    continue;
                }
    
                $optionCategories[$categoryId]['rank'] = intval($category['rank']);
            }
    
            uasort($optionCategories, function($a, $b) {
                if ($a['rank'] == $b['rank']) {
                    return 0;
                }
    
                return ($a['rank'] < $b['rank']) ? -1 : 1;
            });
            break;
        case 'name':
            uasort($optionCategories, function($a, $b) {
                return strcmp($a['name'], $b['name']);
            });
            break;
        case 'idx':
            uasort($optionCategories, function($a, $b) {
                if ($a['idx'] == $b['idx']) {
                    return 0;
                }
    
                return ($a['idx'] < $b['idx']) ? -1 : 1;
            });
            break;
    }
    
    return $pdoFetch->getChunk($tpl, array(
        'groups' => $optionCategories,
    ));

    Вызываем сниппет, где требуется вывести свойства товаров по группам:

    [[!msProductOptionsEx?
      &tpl=`tpl.msProductOptionsEx`
      &groupEmptyName=`Без группы`
      &groupSortBy=`rank`
    ]]

    Чанк tpl.msProductOptionsEx:

    {foreach $groups as $group}
        <div class="group">
            <h4>{$group.name}</h4>
            <div class="group-options">
                {foreach $group.options as $option}
                    <div class="form-group">
                        <label class="col-md-2 control-label">{$option.caption}:</label>
                        <div class="col-md-10 form-control-static">
                            {if $option.value is array}
                                {$option.value | join : ', '}
                            {else}
                                {$option.value}
                            {/if}
                        </div>
                    </div>
                {/foreach}
            </div>
        </div>
    {/foreach}
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      3