Автор Тема: Несколько блоков выбранных категорий  (Прочитано 534 раз)

04 Декабрь 2019, 15:43:04
  • Новичок
  • *
  • Сообщений: 4
  • Репутация: +0/-0
  • Сообщество PrestaShop
    • Просмотр профиля
Добрый день. Заранее извиняюсь, если такая тема уже поднималась, не смог найти решение.. Несколько дней назад впервые познакомился с PrestaShop (v. 1.7.6.1 Тема - AngarTheme). И столкнулся с такой проблемой:
Существует некое дерево категорий:

Главная категория (-название блока)
 -Кат.1
   -Кат.1.1
   -Кат.1.2
   -.....
 -Кат.2
   -Кат.2.1
   -Кат.2.2
   -.....
И т.д.

 Для вывода блока категорий используется модуль "Ссылки дерева категорий" - так он у меня называется в меню Module Manager (папка \ps_categorytree). Он выводит все существующие категории в один блок. А мне нужно, чтобы было несколько блоков. Чтобы каждый из которых выводил подкатегории определенной категории (той, которую я определю сам. Некоторые категории вообще не должны показываться в этих блоках). Таким образом:

Блок1
------
Категория1 (-название блока)
  -Кат.1.1
  -Кат.1.2
  -.....

Блок2
------
Категория2 (-название блока)
  -Кат.2.1
  -Кат.2.2
  -.....
И т.д.

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

В файле ps_categorytree.tpl есть такой код:
<div class="block-categories block">
{* AngarTheme *}
<div class="h6 text-uppercase facet-label">
<a href="{$categories.link nofilter}" title="{l s='Categories' d='Shop.Theme.Catalog'}">{if $page.page_name == 'index'}{l s='Categories' d='Shop.Theme.Catalog'}{else}{$categories.name}{/if}</a>
</div>

    <div class="block_content">
<ul class="tree dhtml">
{categories nodes=$categories.children}
</ul>
</div>

</div>
Может, просто продублировать его столько раз, сколько нужно блоков, и выводить в каждом не $categories.name в качестве заголовка и $categories.children в качестве списка категорий, а $categories[id нужной категории].name и $categories[id нужной категории].children. Я не силен в данном синтаксисе, и вообще новичок в таких делах)) Но, думаю, смысл понятен. Если нельзя так напрямую, может есть какой-то другой способ достать эти подкатегории заранее, и уже их использовать в этих кусках кода. Если кто-то знает, прошу помочь. Но, как я уже сказал, я тут новичок, поэтому не стоит делать допущения о наличии у меня каких-то особых знания программирования или работы движка. Это для того, чтобы я не переспрашивал несколько раз)

04 Декабрь 2019, 16:47:59
Ответ #1
  • Ветеран
  • *****
  • Сообщений: 33325
  • Репутация: +26771/-0
    • Просмотр профиля
Бесплатных нет, платные с такими функциями есть.
Можно клонировать модуль и установить условие выводить дерево для определенной категории.
Можно в шаблоне поставить условие
{$node.name = 'Наименование категории'}...
04 Декабрь 2019, 20:12:05
Ответ #2
  • Новичок
  • *
  • Сообщений: 4
  • Репутация: +0/-0
  • Сообщество PrestaShop
    • Просмотр профиля
Бесплатных нет, платные с такими функциями есть.
Можно клонировать модуль и установить условие выводить дерево для определенной категории.
Можно в шаблоне поставить условие
{$node.name = 'Наименование категории'}...

А что такое "Наименование категории"? Ее название? У меня могут быть несколько категорий с одним и тем же названием.... Как программа поймет какую именно ей нужно выводить... как-то странно.. И в каком именно месте нужно ставить такое условие? Вот весь код шаблона:
{* AngarTheme *}
{function name="categories" nodes=[] depth=0}
  {strip}
    {if $nodes|count}

        {foreach from=$nodes item=node}
<li>
{if $page.page_name == 'product'}
<a href="{$node.link}" {if $node.id == $product.id_category_default}class="selected"{/if}>
{$node.name}
</a>
{else}
<a href="{$node.link}" {if $page.page_name == 'category'}{if $node.id == $category.id}class="selected"{/if}{/if}>
{$node.name}
</a>
{/if}

{if $node.children}
<ul>
{categories nodes=$node.children depth=$depth+1}
</ul>
{/if}
</li>
        {/foreach}

    {/if}
  {/strip}
{/function}


<div class="block-categories block">
{* AngarTheme *}
<div class="h6 text-uppercase facet-label">
<a href="{$categories.link nofilter}" title="{l s='Categories' d='Shop.Theme.Catalog'}">{if $page.page_name == 'index'}{l s='Categories' d='Shop.Theme.Catalog'}{else}{$categories.name}{/if}</a>
</div>

    <div class="block_content">
<ul class="tree dhtml">
{categories nodes=$categories.children}
</ul>
</div>

</div>
05 Декабрь 2019, 11:53:08
Ответ #3
  • Ветеран
  • *****
  • Сообщений: 16670
  • Репутация: +14630/-5
  • Сообщество PrestaShop
    • Просмотр профиля
Лучше id категорий использовать, а не название. Названия могут повторятся, id нет.
05 Декабрь 2019, 11:56:54
Ответ #4
  • Ветеран
  • *****
  • Сообщений: 33325
  • Репутация: +26771/-0
    • Просмотр профиля
{if $node.id == ...
если названия повторяются
05 Декабрь 2019, 17:35:17
Ответ #5
  • Новичок
  • *
  • Сообщений: 4
  • Репутация: +0/-0
  • Сообщество PrestaShop
    • Просмотр профиля
{if $node.id == ...
если названия повторяются

Спасибо, но в каком месте нужно его вставлять? Код начинается с:
{function name="categories" nodes=[] depth=0}
  {strip}
    {if $nodes|count}
        {foreach from=$nodes item=node}
Если я правильно понял, $nodes - Это массив, из которого будут выводиться категории. Т.е. мне нужно, чтобы этот $nodes был не массивом со всеми категориями, а массивом с подкатегориями нужной мне категории. Если я ставлю условие, как вы предложили внутри цикла:
{foreach from=$nodes item=node}
    {if $node.id == 13}
То мне выводится просто вместо всех категорий в блоке, категория с id=13. А мне нужно, чтобы выводились ее подкатегории, а сам блок назывался названием этой категории. Т.е. мне нужно где-то раньше использовать это условие? {if $node.id == ...

Или вы имели ввиду, чтобы я выставил такие условия для вывода каждой категории внутри блока? Т.е. при добавлении новой подкатегории внутри категории, мне придется лезть в код и вручную ее туда прописывать. Это будет очень неудобно.
Мне нужно выставить условие на вывод дерева для определенной категории, чтобы все его подкатегории выводились автоматически. Условие для вывода отдельных категорий внутри блока делать совершенно непрактично.
05 Декабрь 2019, 22:23:30
Ответ #6
  • Ветеран
  • *****
  • Сообщений: 16670
  • Репутация: +14630/-5
  • Сообщество PrestaShop
    • Просмотр профиля
Все правильно в цикле
{foreach from=$nodes item=node}
    {if $node.id == 13}
            тут разделитель блоков категорий, выводите все под-категории для категории с id 13.
06 Декабрь 2019, 02:51:23
Ответ #7
  • Новичок
  • *
  • Сообщений: 4
  • Репутация: +0/-0
  • Сообщество PrestaShop
    • Просмотр профиля
Все правильно в цикле
{foreach from=$nodes item=node}
    {if $node.id == 13}
            тут разделитель блоков категорий, выводите все под-категории для категории с id 13.
В общем всем спасибо, я посидел немного и разобрался в логике шаблона.
Распишу, может кому-то пригодится. Как я и говорил, мне на место этого $nodes, нужно подсунуть $node, id которого равен 13. Оставляем главную функцию без изменений. Она принимает исходный массив, обрабатывает и возвращает список категорий, которые нам нужны в то место, из которого мы ее вызываем.
{function name="categories" nodes=[] depth=0}
  {strip}
    {if $nodes|count}
        {foreach from=$nodes item=node}
<li>
{if $page.page_name == 'product'}
<a href="{$node.link}" {if $node.id == $product.id_category_default}class="selected"{/if}>
{$node.name}
</a>
{else}
<a href="{$node.link}" {if $page.page_name == 'category'}{if $node.id == $category.id}class="selected"{/if}{/if}>
{$node.name}
</a>
{/if}

{if $node.children}
<ul>
{categories nodes=$node.children depth=$depth+1}
</ul>
{/if}
</li>
        {/foreach}
    {/if}
  {/strip}
{/function}

Далее вместо стандартного блока категорий, который отправляет на функцию родительскую категорию:
<div class="block-categories block">
{* AngarTheme *}
<div class="h6 text-uppercase facet-label">
<a href="{$categories.link nofilter}" title="{l s='Categories' d='Shop.Theme.Catalog'}">{if $page.page_name == 'index'}{l s='Categories' d='Shop.Theme.Catalog'}{else}{$categories.name}{/if}</a>
</div>

    <div class="block_content">
<ul class="tree dhtml">
{categories nodes=$categories.children}
</ul>
</div>

</div>

Мы пишем свои блоки (Столько сколько нужно)
<div class="block-categories block">
{* AngarTheme *}
<div class="h6 text-uppercase facet-label">
<a href="{$a_.link nofilter}" title="{$a_.name}">{$a_.name}</a>
</div>

    <div class="block_content">
<ul class="tree dhtml">
{categories nodes=$a_.children}
</ul>
</div>

</div>
<div class="block-categories block">
{* AngarTheme *}
<div class="h6 text-uppercase facet-label">
<a href="{$b_.link nofilter}" title="{$b_.name}">{$b_.name}</a>
</div>

    <div class="block_content">
<ul class="tree dhtml">
{categories nodes=$b_.children}
</ul>
</div>

</div>
В которых я уже вместо $categories поставил $a_ и $b_, которые будут у нас категориями, под-категории которых мы хотим выводить. И далее просто добавляем функцию (выше этих блоков по тексту), которая будет вытаскивать эти категории из массива  $categories.
{$a_=[]}{$b_=[]}{$f_=$categories.children}
{if $f_|count}
{foreach from=$f_ item=node_}
{if $node_.id ==13}
{$a_=$node_}
{/if}
{if $node_.id ==25}
{$b_=$node_}
{/if}
{/foreach}
{/if}
Где 13 и 25 - id категорий, под-категории которых мы хотим выводить в  блоках. Я в синтаксисе не разбираюсь, просто сделал по аналогии с первой функцией, возможно можно было сделать правильнее и проще. Может вообще эта функция не нужна, и из родительского массива можно как-то выдернуть нужную нам категорию напрямую используя id.

Можно также унифицировать. Если кому-то надо выводить все категории, являющиеся прямыми потомками главной, блоками. Вот решение еще проще. Верхнюю функцию также не трогаем, а блок для вывода категорий помещаем в цикл:
{if $categories.children|count}
{foreach from=$categories.children item=node_}
{if $node_.children}
<div class="block-categories block">
{* AngarTheme *}
<div class="h6 text-uppercase facet-label">
<a href="{$node_.link nofilter}" title="{$node_.name}">{$node_.name}</a>
</div>

    <div class="block_content">
<ul class="tree dhtml">
{categories nodes=$node_.children}
</ul>
</div>

</div>
{/if}
{/foreach}
{/if}
Если какую-то категорию не хотим выводить блоком, ставим внутрь цикла: {if $node_.id !=10}, где 10 айди вашей категории.
И все, не надо клонировать никакие модули и прочее. Может кому-то пригодиться.