lucas.sanner54070
lucas.sanner54070

I realized while developing my plugin that October doesn't provide an option to get hierarchical URLs based on nested categories/sub-categories.
After much searching I finally came across this feature request
So where is the October team regarding this feature ?
Is there an alternative option or a workaround currently ?

Last updated

mjauvin
mjauvin

Do you mean for the Rainlab.Blog plugin in particular?

mjauvin
mjauvin

This comment in the thread you referenced suggests it's already supported:

https://github.com/rainlab/blog-plugin/issues/29#issuecomment-329514378

lucas.sanner54070
lucas.sanner54070

Actually Jan Vince refers to the nested category support.
But the hierarchical URLs is still not supported as you can read at the end of the thread:
So now only to solve a hierarchical URLs...

mjauvin
mjauvin

Wouldn't it be trivial to modify the component partial to build hierarchical urls out of those hierarchical categories, though?

mjauvin
mjauvin

For example, the items.htm partial would look like this:

{% for category in categories %}
    {% set postCount = category.post_count %}
    {% set url = parent ? parent.slug ~ '/' ~ category.slug : category.slug %}
    <li {% if category.slug == currentCategorySlug %}class="active"{% endif %}>
        <a href="{{ url }}">{{ category.name }}</a>
        {% if postCount %}
            <span class="badge">{{ postCount }}</span>
        {% endif %}

        {% if category.children|length > 0 %}
            <ul>
                {% partial __SELF__ ~ "::items"
                    categories=category.children
                    currentCategorySlug=currentCategorySlug
                    parent=category
                %}
            </ul>
        {% endif %}
    </li>
{% endfor %}
lucas.sanner54070
lucas.sanner54070

It's a good idea but even though it gives the correct paths I get an error
as the whole problem is about the url segments.

I tried to use the wilcard parameter

url=/category/:path*

It works as long as I don't use an optional parameter at the end of the url. But I need optional parameters like pagination id etc...

I go in circle for days on that one. I guess it could be settled in the routes.php file but I'm not skilled enough to figure out how.

mjauvin
mjauvin

Yes, I used category.slug but that bypasses the categoryPage component property... so it's better to use {{ category.url }} which means the setUrl() method in Category model needs a little overhaul to make it work with nested categories.

lucas.sanner54070
lucas.sanner54070

I already did that

    $path = $this->slug;
    $parents = $this->getParents();

    foreach ($parents as $parent) {
        $path .= $parent->slug.'/'.$path;
    }   

    $params = [ 
        'id'   => $this->id,
        'slug' => $this->slug,
        'path' => $path
    ]; 

but as I said it works as long as I don't use an optional parameter at the end of the url which is not a acceptable solution.

Last updated

mjauvin
mjauvin

What does your CMS category page look like?

lucas.sanner54070
lucas.sanner54070

here it is

title = "Category"
url = "/category/:path*"
layout = "default"
is_hidden = 0 

[songList]
pageNumber = "{{ :page }}" 
categoryFilter = "{{ :path }}" 
songsPerPage = 2 
noSongsMessage = "No songs found"
sortOrder = "title asc"
categoryPage = "category"
songPage = "song"
==
<div class="container col-sm-9">
{% component 'songList' %}
</div>
mjauvin
mjauvin

why don't you use this:

url = "/category/:parent/:category/:page?"

[songList]
pageNumber = "{{ :page }}" 
categoryFilter = "{{ :category }}" 
lucas.sanner54070
lucas.sanner54070

I did but again, it will work only if I'm on the second category level. eg:

http://mydomain.com/category/style/rock

and with the optional parameter:

http://mydomain.com/category/style/rock/2

Now if I go up one level it will give:

http://mydomain.com/category/default/style

or

http://mydomain.com/category/default/style/2

The null value of the parent parameter is replaced with the "default" value.
It's a catch 22 and it's due to the fact that you cannot set an optional parameter in the middle of the path. eg:

url = "/category/:parent?/:category/:page?"

:parent? won't be taken into account as an optional parameter.
I'm afraid we need the big guns for this one but I haven't found any relevant piece of information so far.

mjauvin
mjauvin

You can (in addition) create a page without the subcategory like this which will cover the case when it is not a subcategory:

url = "/category/:category/:page?"

[songList]
pageNumber = "{{ :page }}" 
categoryFilter = "{{ :category }}" 

And use a partial that will get called for both pages to render your content.

lucas.sanner54070
lucas.sanner54070

Good call! I think it's the most reasonable way to tackle this problem without too much difficulty.
However, to get it work properly a constraint has to be append to the optional parameter:

url = "/category/:category/:page?|^[0-9]+$"

otherwise http://mydomain.com/category/style/2 and http://mydomain.com/category/style/rock will match the same pattern.

mjauvin
mjauvin

Yes, exactly. Let me know how that goes.

1-16 of 16