Множественные категории товаров в MODx Evolution + избавление от дублей товаров

Понадобилось мне навесегда избавиться от дублей (заказчику это очень не нравилось и Яндексы всякие с ним были солидарны), в общем погуглил-погуглил, нашел решение, но для Revolution.

По сути, получается очень удобный выбор категорий, в которых товар может содержаться. Выбирать можно как галочками, так и списком с множественным выбором (с помощью Ctrl+click). Красота да и только.

Сама идея отсюда — мной (не без помощи комментариев) допилена для Evolution и вот что получилось.

Ну, начнем, пожалуй. Все создаем по очереди.

 

Чанк {{tplCatMultiCheck}}

Чанк я сделал для более красивого и информативного вывода чекбоксов. Показывает окошко чекбокса, имя категории и серым ее ID (иногда чтобы не искать полезно делжать перед глазами — заказчика не парит и мне в помощь)

[+pagetitle+] <span style="color:grey;">(id: [+id+])</span>==:[+id+]:||

 

Параметр (TV) [*catMultiCheck*]

Тип ввода: CheckBox (можно поставить и «Множественный выбор» — это уж кому как больше нравится)

Возможные значения:

@EVAL return $modx->runSnippet ('Ditto', array ('startID'=>0, 'depth'=>2, 'where'=>'isfolder=1', 'sortBy'=>'{"id":"ASC"}', 'tpl'=>'tplCatMultiCheck'));

Доступ шаблонов: products

После сохранения — в админке появятся категории. Теперь подробно разжую зачем это нужно (новичкам пригодится):

  • @EVAL Собака указывает на то, что сейчас будем работать с PHP, MySQL, да Бог еще знает с чем. Eval — это функция такая в PHP есть, она позволяет выполнять php-код прямо из переменной.
  • return — думаю, это понятно, что результат должен быть как-то возвращен, да?
  • $modx->runSnippet — вызов сниппета. Первым в скобках перед запятой указывается имя сниппета, а после запятой — массив с переменными. Не парьтесь, суйте переменные в массив, «там» разберутся и все ваши переменные будут доступны сниппету без обращения к массиву. Дальше об этом подробнее будет, будем вызывать свой сниппет.
  • ‘Ditto’ — см. выше. Есть такой Ditto в MODx — управляет материалами.

Теперь про то, что мы суем в массив.

  • ‘startID’=>0, — откуда ничинаем. У меня все категории в корне лежат, так что стоит ноль.
  • ‘depth’=>2, — глубина. Как много в этом слове. Если поставить 1 — будем копаться только в текушем уровне, т.е. подкатегории не найдутся. Поэтому два. Если есть под-подкатегории — ставьте три.
  • ‘where’=>’isfolder=1’, — проверяем на категорию (контейнер). Мне нужны только контейнеры, поэтому 1. Если нужны НЕ контейнеры — ставим ноль. Вообще, where здесь (кстати, регистр следует соблюдать) указывает на то, что дальше будет реальный WHERE SQL-запроса на тот случай, если нужно руками выбрать что-то как в нашем случае.
  • ‘sortBy’=>'{«id»:»ASC»}’, — сортировка. Тут особо даже сказать нечего.
  • ‘tpl’=>’tplCatMultiCheck’ — показываем пальцем на шаблон (тут указан чанк, но можно и имя файла указать).

Все это добро должно быть одной строкой.

 

Сниппет [[getIDLikeByTV]]

Отдельное спасибо комментатору Сергей со страницы автора решения для [Revo]- часть кода предложена им, допилена мной.

<?php
if(!isset($tmplvarid)) $tmplvarid = 1;
if(!isset($like)) $like = '';
if($like == '1') {
 $like = 15;
 $this_all_url = 1;
} else {
 $this_all_url = $like;
}

$ids_arr = array();

$query = $modx->db->query("
 SELECT `id`, `contentid`
 FROM `".$modx->db->config['table_prefix']."site_tmplvar_contentvalues`
 WHERE tmplvarid=".intval($tmplvarid)." AND value LIKE '%:$like:%'
");

$result = $modx->db->makeArray($query);

foreach ($result as $ar) {
 array_push($ids_arr,$ar['contentid']);
}

$ids_str = implode(',',$ids_arr);

$res = $modx->runSnippet('Ditto', array(
 'parents' => $like,
 'tpl' => 'shopStuff',
 'paginate' => '1',
 'sortBy' => 'menuindex',
 'sortDir' => 'ASC',
 'documents' => $ids_str
));

return $res.$item.$all_prod;
?>

 

Шаблоны (вызов сниппета для вывода товаров)

Шаблоны main, category (опять же, у меня).

<div id="prod-list">
  [!getIDLikeByTV?tmplvarid=`23`&like=`[*id*]`!]
</div>

Здесь вот что стоит отметить —  tmplvarid=`23` — это ID TV-параметра catMultiCheck. Какой у вас показывает — тот и ставьте вместо 23.

0

Множественные категории товаров в MODx Evolution + избавление от дублей товаров: 31 комментарий

  1. Денис

    Привет, блин вот такая проблема. Сделал как все описано, но появляется ошибочка:
    «syntax error, unexpected T_CONSTANT_ENCAPSED_STRING, expecting ‘)’ in Z:\home\блабла\manager\includes\document.parser.class.inc.php(814) : eval()’d code on line 31»
    На 31 строчке: «var $documentName;»
    В чем проблема как решить? Просто необходима такая штука, а то дублей будет огого.

    1. merinovkv Автор записи

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

  2. Чек

    Помогите решать вопрос. Вот мой сайт itbc.kiev.ua. Я хочу выбирать одной статье несколько категорий. Весь мозг уже проел как это сделать… =( Я могу даже вам дать доступ к сайту и заплатить денег… Я создал всё что выговорите, но я не могу понят куда выводить сниппет…

    У меня кстати таже ошибка

    Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING, expecting ‘)’ in Z:\home\localhost\www\itbc.kiev.ua\manager\includes\document.parser.class.inc.php(814) : eval()’d code on line 31

    https://dl.dropbox.com/u/14799845/%D1%83%D0%B4%D0%B0%D0%BB%D0%B8%D1%82%D1%8C_1.jpg

    skype: al-4ek

    Спасибо за любую помощь

    1. merinovkv Автор записи

      Денег — это хорошо 🙂 пытался сегодня достучаться до вас в скайпе…
      В моем примере сниппет выводится в шаблоне с помощью

      [!getIDLikeByTV?tmplvarid=`23`&like=`[*id*]`!]


      Но никто не запрещает затолкать его в чанк и оттуда вызывать.

      Сниппет, , возможно, придется переписать для большей универсальности. На данный момент то, что есть — писалось под Shopkeeper для работы с товарами.

      Напишите мне в аську 177633964 или ответьте в скайпе, посмотрим, что можно с этим сделать.

  3. cronost

    Спасибо, за описанное решение. А как обстоит дело с url к продукту из разных категорий? Ведь по умолчанию url примерно так выглядит — ‘домен/product/tema1/thema2/название продукта’. И если с разных тем на один и тот же продукт будут разные URL вести, то это не решает проблему дублей — для поисковика это будут разные страницы. Или я что-то неправильно понимаю?

    1. merinovkv Автор записи

      Как оно работает посмотрите здесь: http://www.centre-flower.ru
      Смысл в том, что товар у вас фактически лежит, например, в категории CAT_1, а выводим мы его галочками в нескольких категориях, например в CAT_2 и CAT_3. Ссылки получаются на CAT_1.
      Один камрад сделал проще — убрал в урле путь к товару, оставив только product_name.html.

  4. Женя

    Добрый день. Подскажите, пожалуйста, все сделал как описано, однако на странице вызова

    &tpl или не содержит каких-либо плейсхолдеров, или является неверным названием чанка, блоком кода или именем файла. Пожалуйста, проверьте его.

    В общем не нравится ему ченк, в чем может быть проблема? Заранее спасибо.

  5. merinovkv Автор записи

    Если появляется такое сообщение, значит чанк или не существует, или вы его как-то криво вызываете. Проверьте корректность вызова чанка и вообще его существование (имя, например)

  6. Женя

    Извините, что таким способом, что-то не нашел я на Дискусе вставку изображений:

    TV

    chunk

    Вроде все правильно ввел, однако ченка все равно не видно и ID для TV тоже правильно задал при вызове на странице:

    [!getIDLikeByTV?tmplvarid=`30`&like=`[*id*]`!] /* ID моего TV - 30 */

    Посмотрите, пожалуйста, может Вы ошибку найдете, я раз 20 перепроверил.

    1. merinovkv Автор записи

      Попробуйте вместо вызова чанка написать, например,
      ‘tpl’=>'[+pagetitle+]’
      или вообще убрать вызов чанка, чтобы убедиться, что дело в синтаксисе чанка. Возможно, где-то есть символ, криво распознающийся.

  7. Женя

    Спасибо за ответ. Но, похоже, что до ченка дело не доходит, чтобы я не писал в TV, все равно результат:

    &tpl или не содержит каких-либо плейсхолдеров, или является неверным названием чанка, блоком кода или именем файла. Пожалуйста, проверьте его.

    Чешу затылок в недоумении 🙁

    1. merinovkv Автор записи

      не думаю ))
      в TV возможные значения собираются вот такой штукой:
      @EVAL return $modx->runSnippet ('Ditto', array ('startID'=>0, 'depth'=>2, 'where'=>'isfolder=1', 'sortBy'=>'{"id":"ASC"}', 'tpl'=>'tplCatMultiCheck'));
      То есть, вызывается Ditto с параметрами. НО! Для того, чтобы сам MODx распознал это дело как список — в конце надо добавитть ||
      Попробуйте вставить так:
      @EVAL return $modx->runSnippet ('Ditto', array ('startID'=>0, 'depth'=>2, 'where'=>'isfolder=1', 'sortBy'=>'{"id":"ASC"}'));
      То есть, убрать вызов чанка. Что получится? Должен появиться список категорий (не важно пока, как он будет выглядеть). Если не получилось — посмотрите в сторону вызова Ditto, вероятно, просто у вас нечего выводить, посмотрите на вложенность, на родителя, откуда берете категории, на знаки ‘ и `
      Могу вам с большой долей вероятности сказать, что если категории появятся — значит что-то неправильно написано в чанке. А если не появятся — значит надо смотреть в сторону вызова Ditto.

  8. Женя

    🙂
    Возможно я вызов сниппета не там делал, извините. На странице Редактирования рессурса (товара) конструкция появляется и выглядит так:

    Stranica nastroek tovara

    Но при вызове сниппета на странице категории и на странице карточки товара (установил в настройках галочки — для мальчиков, для девочек и для наглядности на изображении установлены все). На странице карточки товара выводит текст — Записей не найдено, а на странице категории товаров — &tpl или не содержит каких-либо плейсхолдеров, или является неверным названием чанка, блоком кода или именем файла. Пожалуйста, проверьте его.

    ??? 🙁
    Подскажите, пожалуйста, что это за чекбокс в самом низу без подписи?
    И второй вопрос записей не найдено — может я что-то не так делаю или не те галочки устанавливаю (какой должен быть вывод в итоге и почему товар для которого я указал 2 разные категории показывается в списке только одной — той, в которой он расположен).

    дерево моих категорий:

    главная

    для мальчиков
    гели для душа
    парфюмерия

    для девочек
    гели для душа
    парфюмерия

    В любом случае спасибо за потраченное время на меня.

    1. merinovkv Автор записи

      Начну с конца, пожалуй 🙂
      Сниппет [[getIDLikeByTV]] — это как раз то, что выводит товары под галочками. Вызов сниппета надо вставить в шаблоне, где у вас выводятся товары (вместо существующего вывода), я об этом в статье написал:

      Шаблоны (вызов сниппета для вывода товаров)

      Шаблоны main, category (опять же, у меня).

      [!getIDLikeByTV?tmplvarid=`23`&like=`[*id*]`!]


      Здесь вот что стоит отметить — tmplvarid=`23` — это ID TV-параметра catMultiCheck. Какой у вас показывает — тот и ставьте вместо 23.

      Что за пустой чекбокс — не знаю, возможно, надо посмотреть фаербагом и поправить чанк, чтобы сначала был разделитель, а потом категория.

  9. Женя

    Просидел целый день, ничего не получилось 🙁

    Если можно, еще задам пару вопросов последних, если не получится, буду дублировать товар, чего не хотелось изначально:

    Данные в Параметр (TV) [*catMultiCheck*] заносятся в настройках товара или в настройках категории?

    Товар должен быть вне выбранной категории или все-равно?

    Имеет значение где должны быть товары в каталоге МОДх или Шопкипере?

    На этом все, спасибо.

    1. merinovkv Автор записи

      Параметр (TV) должен быть у товара, если вы об этом.
      Абсолютно все равно, где будет товар. Если галочка стоит на категории — товар будет отображаться в ней.
      У меня товары в MODx.
      Если совсем не будет получаться — стукните через форму справа, скиньте логинопароль и адрес, где можно посмотреть, что у вас не получается. «Будем посмотреть»

  10. Женя

    Есть на свете Бог 😉
    Заработало!!! Товар то не выводило в самой категории, ругалось на &tpl (прям в месте вывода каталога и писало ошибку), ну а вечер утра мудренее. Версия MODx 1.0.7, shopkeeper 1.3.4, а в такой связке (не знаю кто из них виноват 🙂 ), шаблон ченка shopStuff находится не в админке, а отдельно в файле, поэтому в сниппете getIDLikeByTV нужно было путь указать явно:

    < ?php if(!isset($tmplvarid)) $tmplvarid = 1; if(!isset($like)) $like = ''; if($like == '1') { $like = 15; $this_all_url = 1; } else { $this_all_url = $like; } $ids_arr = array(); $query = $modx->db->query("
    SELECT `id`, `contentid`
    FROM `".$modx->db->config['table_prefix']."site_tmplvar_contentvalues`
    WHERE tmplvarid=".intval($tmplvarid)." AND value LIKE '%:$like:%'
    ");

    $result = $modx->db->makeArray($query);

    foreach ($result as $ar) {
    array_push($ids_arr,$ar['contentid']);
    }

    $ids_str = implode(',',$ids_arr);

    $res = $modx->runSnippet('Ditto', array(
    'parents' => $like,
    'tpl' => '@FILE:assets/snippets/shopkeeper/chunks/ru/chunk_shopStuff.tpl',
    'paginate' => '1',
    'sortBy' => 'menuindex',
    'sortDir' => 'ASC',
    'documents' => $ids_str
    ));

    return $res.$item.$all_prod;
    ?>

    Вот, может кому-нибудь пригодится, кто будет использовать новую версию MODx или Shopkeeper.

  11. Женя

    Появляются новые вопросы при использовании данного метода:

    1. не могу вывести пагинацию (подскажите пожалуйста куда копать, ведь в сниппете getIDLikeByTV — paginate включен, а на странице не выводится)

    2. Отвалился AnythingRating, в смысле он не обрабатывается а выводит вызов сниппета, т.е. [!AnythingRating? &atrGrp=`grpName` &atrId=`[+id+]`!] — так и выводит под каждым товаром код как я написал, а не выполняет его?!?

    з.ы. шепотом: упс, наверное слишком много вопросов задаю.

  12. Женя

    Спасибо за полезную статью, очень удобно выстраивать каталог таким способом, все работает, пагинацию прикрутил, рейтинг тоже заработал.

  13. Женя

    Добрый день. Подскажите, пожалуйста, как при таком выводе сделать фильтрацию, ведь Ditto запускается через runSnippet и обычными методами не отфильтровать?!

  14. Мадина

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

    1. merinovkv Автор записи

      К сожалению, давно не работал с Evo, уже не вспомню с ходу. Посмотрите в сторону Ditto, как он умеет работать с TV. Можно написать свой сниппет, который будет выводить те контейнеры, которые нужно.

      1. Денис

        Может все таки есть варианты как вывести эти категории, притащили старый сайт, нужно доделать, вот воткнулся с последней проблемой, как вывести эти ссылки на доп категории

Добавить комментарий