Наверх

Как сделать мультикатегории на MODX с TV-шкой

В разделе «Репосты» расположены чужие статьи, которые мне понравились или показались полезными.

Всем привет.
Недавно глубоко озадачился этим решением и в результате которого нехитрым (почти) способом можно сделать мультикатегории.
Подходит данное решение для сайтов у которых, наверное не более 5..10к товаров. На больших, думаю, будет тормозить, (не проверял) так что обратная связь приветствуется.

И так, что нам нужно?
  • MODX Revolution
  • TV поле multi
  • Знания sql
  • Знания fenom
  • Бутылочка с пузыриками (выбирайте по вкусу)
1. Создаем TV с нужным именем, у нас это multi.
1.1. В параметрах выбора у нас Тип — список множественный выбор, в возможных значениях, я обычно вписываю @EVAL (вам следует, использовать другой вариант, если хотите чтобы в MODX 3 у вас это дело не слетело (оно не поддерживается в 3-ке):
@EVAL return $modx->runSnippet('pdoResources',array(
'parents'=>4,
'where'=>'{"isfolder:=":1}','depth'=>5,'limit'=>0,'sortby'=>'{"pagetitle":"ASC"}',
'tpl'=>'@INLINE [[+pagetitle]] - ([[#[[+parent]].pagetitle]])==[[+id]]',
'outputSeparator'=>'||','tplWrapper'=>'@INLINE Нет==||[[+output]]'));
В tpl Вы можете сделать как хочется вам у меня маска вывода такая: КАТЕГОРИЯ (родительская категория «на всякий случай»).
В parents — родители из которых брать категории.
where — можно или Isfolder или template использовать — как хотите.
1.2. В параметрах вывода выбираем РАЗДЕЛИТЕЛЬ , (запятая).
1.3. остальное по вкусу. (для каких шаблонов и названия, описания)
В товаре теперь у нас есть TV-шка которая складирует ID дополнительных категорий.
2. настраиваем вывод pdoResource:
2.1. Сложность в том что мультиселект хранит данные в формате: 23||67||288 те с разделителем ||. поэтому выражения с where типа:
a) 'where'=> ["multi:IN" => [99,88] ]
б) 'where'=> ["multi:=" => 88]
в) 'where'=> ["multi:LIKE" => "%88%"]
Не будут корректно работать.
1й вернет товары у которых только одна доп категория, которая равна 88 или 99.
2й вернет товары у которых только одна доп категория, которая равна только 88.
3й вернет все товары, у которых встречаются совпадения с 88. (те 23||67||288 — этот товар попадет в выборку.)
4й вообще даже так записывать — не верно, ведь у нас тут не показана выборка по parent = 88 или 99 а она по умолчанию есть и получиться что нужно указывать корневую Parents = 33, но тогда попадут все товары, значит в where еще нужно дописать parent:IN 88 99. Но и этого мало.

2.2. В общем, нам нужно залайкать в нескольких вариантах multi те.:
LIKE '%|88' и LIKE '88|%' и LIKE '%|88|%' и = '88'
Как видно мы ищем совпадение в конце, совпадение в начале, совпадение в середине и чистое совпадение.
Есть странный глюк в разборе where и если вы захотите написать все в стиле прилежного MODX-сера:
'where'=> ["multi:LIKE" => "%|88","OR:multi:LIKE" => "88|%","OR:multi:LIKE" => "%|88|%","multi:=" => "88"]
Это логично, и читаемо, но массив переменных это зло. И в массиве будет уничтожены (точнее перезаписаны данные) угадайте какие?
Ключ в массиве должен быть уникальным, а значит OR:multi:LIKE у нас останется единственный последний («OR:multi:LIKE» => "%|88|%"). Поэтому нам нужно или поставить пробелы дополнительные чтобы ключ отличался или переписать наш код в более sql ориентированный вариант, что и сделаем ниже (вообще опускаю еще некоторые проблемы которые могут (возможно) возникнуть).

Важно сказать что вывод товаров в категории будет работать только непосредственно в конечных категориях, потому что на входе у нас 1 категория будет активная (ниже объясню почему) структура такая:
Каталог (33) (кат)
— Майки (кат) (55)
— — майка простая артикул 001 (товар) (345) (доп кат 801 и 77)
— — желетка-майка артикул 453 (товар) (987) (доп кат 88)
— Туфли (кат) (88)
— --Туфли с правой ногой (кат) (801)
— --Туфли с левой ногой (кат) (802)
— Брюки (кат) (77)
2.3. Выборка в результате у нас будет такая для вывода ресурсов на фронте:
{set $itzx = $_modx->resource.id} // в зависимости от категории
{'!pdoResources' | snippet : [
    'limit' => 0,
    'hideContainers' => '1',
    'parents' => '33', 
    'includeTVs' => 'multi', // нужно обязательно добавить, иначе выборка не стработает.
    'processTVs' => 'multi',
    'where' => [ 
0 => "(`TVmulticat`.`value` LIKE '%|"~$itzx~"' OR `TVmulticat`.`value` LIKE '"~$itzx~"|%' OR `TVmulticat`.`value` LIKE '%|"~$itzx~"|%' OR `TVmulticat`.`value` = '"~$itzx~"' OR parent = "~$itzx~")" ,
1=> [ _ ДРУГИЕ УСЛОВИЯ КАКИЕ_ТО _ ]],
]}
Важный момент обработки массивов. в начале нужно указать 0 => чтобы при обработке это получилось отдельное условие в скобках, потому что после скобок будет идти стандартный AND Например по умолчанию далее идут pulished = 1 deleted = 0, и нам важно чтобы выражение с лайками в скобках воспринималось БД при запросе одним целым, а уже 1 => вы можете добавить свои нужные условия, например template.
а вот строка
OR parent = "~$itzx~"
нужна чтобы товары конкретной категории так же были приравнены к «своим».

Из последнего следует маленький нюанс, что корректно данное решение будет работать только в каталогах, где вывод товаров идет непосредственно в конечных категориях.
Те если мы заходим в категорию Майки (55), мы видим все 2 майки.
Если зайдем в категорию Туфли 88, то мы тут увидим только желетку-майку id987. ну и отдельным сниппетом (блоком) выбор категорий 801 и 802. а уже если зайдем в Туфли с правой ногой id801, то увидим товары которые с правой ногой и дополнительный товар Майка простая, что нам и нужно.

Если необходима поддержка отображения вложенностей, то это немного другая сказка, которую я смогу рассказать как-нибудь в другой раз.
Но суть там другая, проще создать отдельную таблицу в которой хранить id категории и id товара.
Тогда можно будет через join цеплять входящие в множество категории все товары к ним.
Но проще установить Minishop2 для каталога и не заниматься фигней. :)
Надеюсь, не утомил и жажду утолил.
Всего хорошего!

PS. теперь можно открыть прохладную шипучку и релакснуть.

Источник: modx.pro/solutions/23005


0 комментариев

    Авторизация

    через сервис Loginza:


    Шаблоны MODX

    1 2 Дальше »

    Объектная
    модель
    MODX