Back to Catalog Support

ASM Forward Media
ASM Forward Media

I need to render categories menu in sidebar, with active menu items and toggle animation.

Currently i have it with staticMenu (from Pages by Rainlab plugin):

for sidebar partial

<div id="sidebar">
{% if sideMenu.menuItems %}
    {% for item in sideMenu.menuItems%}
        <p class="category-title">{{ item.title }}</p>
        {% partial "layout/sidebar-items" items=item.items class="category" %}
    {% endfor %}
{% endif %}
</div>

for recursive items

<ul class="{{ class }}">
{% for item in items %}
    <li class="{{ item.class }} {{ item.isActive or item.isChildActive ? 'active' : '' }} {{ item.isChildActive ? 'up' : '' }} {{ item.items ? 'category' : '' }}">
        {% if item.items %}<span class="toggle"></span>{% endif %}
        {% spaceless %}
            <a href="{{ item.url }}">
                {{ item.title }} 
            </a>
        {% endspaceless %}
        {% if item.items %}
            {% partial 'layout/sidebar-items' items=item.items class="" %}
        {% endif %}
    </li>
{% endfor %}
</ul>

so i have good menu but with some manual edits on category added into Catalog

Is it posible to do that or analogue in "categories" component? Currently i stopped here

{% set category_list = categories.product_categories %}
{% if category_list %}
{% for category in category_list %}
    {% set oldDepth = depth ?: 0 %}
    {% set depth = category.nest_depth %}
    {% set active = category.slug == categories.currentProductCategorySlug %}
    {% set hasChilds = category.hasChildren %}
    {% if depth == 0 %}
        {% set items = category.getChildren %}
        <p class="category-title {% if active %}active{% endif %}">
            {% spaceless %}
            <a href="{{ category.url }}" class="{% if category.slug == categories.currentProductCategorySlug %}active{% endif %}">
                {{ category.name }}
            </a>
            {% endspaceless %}
        </p>
    {% elseif depth == 1 %}
        {#% if oldDepth < depth %}
            <ul>
        {% endif %}

        {% if oldDepth > depth %}
            </ul>
        {% endif %#}
    {% endif %}
{% endfor %}
{% endif %}

Last updated

Tiipiik
Tiipiik

Did you take a look at the categories componeent with the menu_list selected as render view ?

I think it's exactly what you need. You can even override it to match your toggle animation.

ASM Forward Media
ASM Forward Media

yes, i saw that, i started with it, but can't manage to do proper

<ul class=VARIABLE></ul> 

nesting

the problem is: i already have markup and css, that i just need to reproduce... not with element margin

so far i need conditions (depth changing) or childs array in my logic

Last updated

ASM Forward Media
ASM Forward Media

today's code

{% set category_list = categories.product_categories %}
{% if category_list %}
    {% set depth = 0 %}
    {% for category in category_list %}
        {% set oldDepth = depth %}
        {% set depth = category.nest_depth %}
        {% set isActive = category.slug == categories.currentProductCategorySlug %}{# category.isActive #}
        {% set isChildActive = 0 %}{# category.isChildActive #}
        {% set hasChilds = 0 %}{# category.hasChildren #}
        {% if oldDepth > depth %}
            {% for idx in 1..(oldDepth-depth) %}
                </li></ul>
            {% endfor %}
        {% elseif depth > 0 and oldDepth == depth %}
            </li>
        {% endif %}
        {% if depth == 0 %}
            <p class="category-title {% if active %}active{% endif %}">
                {% spaceless %}
                <a href="{{ category.url }}" class="{% if isActive %}active{% endif %}">
                    {{ category.name }}
                </a>
                {% endspaceless %}
            </p>
        {% elseif depth == 1 %}
            {% if oldDepth < depth %}
                <ul class="category">
            {% endif %}
            <li class="{% if hasChilds %}category{% endif %} {% if isActive %}active{% endif %} {% if isChildActive %}up{% endif %}">
                {% if hasChilds %}<span class="toggle"></span>{% endif %}
                {% spaceless %}
                <a href="{{ category.url }}">
                    {{ category.name }}
                </a>
                {% endspaceless %}
        {% elseif depth > 1 %}
            {% if oldDepth < depth %}
                <ul>
            {% endif %}
            <li class="{% if hasChilds %}category{% endif %} {% if isActive %}active{% endif %} {% if isChildActive %}up{% endif %}">
                {% spaceless %}
                <a href="{{ category.url }}">
                    {{ category.name }}
                </a>
                {% endspaceless %}
        {% endif %}
    {% endfor %}
    {% if depth > 0 %}
        {% for idx in 1..(depth) %}
            </li></ul>
        {% endfor %}
    {% endif %}
{% endif %}

Lack of implementation (way to know):

  • category.isActive (by slug working now)
  • category.isChildActive
  • category.hasChildren

Is it posible to implement this on category class (component or something) ?

Last updated

Tiipiik
Tiipiik

Looks interesting, I'll check that and add it to the plugin.

Tiipiik
Tiipiik

Can you test by adding this code after line 127 in Components/Categories.php ?

    $categories->each(function ($category) {
        $category->isActive = $category->slug == $this->currentProductCategorySlug;
        $category->hasChildren = Category::hasChildren($category->slug);
    });

With isChildActive do you want to know if a given category as an active child ?

Last updated

ASM Forward Media
ASM Forward Media

With isChildActive do you want to know if a given category as an active child ?

Yes, menu parent must be opened to draw it's active children, so this would be helpful

Your code makes this exception on use

exception 'BadMethodCallException' with message 'Call to undefined method October\Rain\Database\QueryBuilder::hasChildren()' in /home/.../vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:1999

Currently i stayed with code in first post, its reccursial and easy (except staticMenu component chain dependency).

Last updated

Tiipiik
Tiipiik

Oh yeah, here is the code of the hasChildren function :

public static function hasChildren($categoryUrl)
{
    $category = Category::whereSlug($categoryUrl)->firstOrFail();

    $children = self::whereParentId($category->id)->get();

    if (isset($children) && sizeof($children) != 0) {
        return true;
    }

    return false;
}

1-8 of 8