<p>You should be able to do this with a recursive <a href="http://twig.sensiolabs.org/doc/tags/macro.html" rel="nofollow">macro</a>.
Here is a macro <code>alphaList</code> which is passed a list of categories (in alphabetic order). For each category, it outputs that category, and then if that category has any children, it calls itself on an alphabetic list of those children.</p>

<p>To get the children of a category <code>c</code>, you combine <a href="https://craftcms.com/docs/templating/craft.categories#descendantOf" rel="nofollow">descendantOf</a> with <a href="https://craftcms.com/docs/templating/craft.categories#descendantDist" rel="nofollow">descendantDist</a> of <code>1</code>: <code>craft.categories.descendantOf(c).descendantDist(1)</code></p>

<p>To get the initial list of top level categories, you use the <a href="https://craftcms.com/docs/templating/craft.categories#level" rel="nofollow">level</a> parameter: <code>craft.categories.level(1)</code>. That will mix together categories from all your category groups, so probably you want to specify the <a href="https://craftcms.com/docs/templating/craft.categories#group" rel="nofollow">group</a>: <code>craft.categories.group('myGroup').level(1)</code>.</p>

<pre><code>{% import _self as self %}

{% macro alphaList(cats) %}
{% import _self as self %}
  {% for c in cats %}
    &lt;li&gt;
      {{c.link}}
      {% set children = craft.categories.descendantOf(c).descendantDist(1) %}
      {% if children|length %}
        &lt;ul&gt;
          {{ self.alphaList(children.order('title')) }}
        &lt;/ul&gt;
      {% endif %}
    &lt;/li&gt;
  {% endfor %}
{% endmacro %}

{% set topCats - craft.categories.level(1) %}
&lt;ul&gt;
  {{ self.alphaList(topCats.order('title')) }}
&lt;/ul&gt;
</code></pre>

CC BY-SA 3.0
2016-02-14T06:41:32.473Z
2016-02-14T06:41:32.473Z
Marion Newlevant
<p>New to Craft. I'm outputting a list of all the categories in my site.</p>

<p>When I do this:</p>

<pre><code>&lt;ul class="cat-list"&gt;
    {% nav category in craft.categories %}
      &lt;li&gt;
        &lt;a href="{{ category.url }}"&gt;{{ category.title }}&lt;/a&gt;
        {% ifchildren %}
            &lt;ul&gt;
                {% children %}
            &lt;/ul&gt;
        {% endifchildren %}
      &lt;/li&gt;
    {% endnav %}
</code></pre>

<p></p>

<p>I end up with (for example):</p>

<ul>
<li>Legumes

<ul>
<li>Peas</li>
<li>Beans</li>
<li>Lentils</li>
</ul></li>
<li>Meat

<ul>
<li>Ground Beef</li>
</ul></li>
<li>Fruit

<ul>
<li>Peach</li>
<li>Banana</li>
<li>Strawberry</li>
<li>Grapes</li>
</ul></li>
</ul>

<p>I'd like those to be alphabetical, though, so Fruit, Legumes, and Meat, are listed in that order, with their children also listed in alphabetical order in the nested list.</p>

<p>However, when I do THIS:</p>

<pre><code>&lt;ul class="cat-list"&gt;
    {% nav category in craft.categories.order('title') %}
      &lt;li&gt;
        &lt;a href="{{ category.url }}"&gt;{{ category.title }}&lt;/a&gt;
        {% ifchildren %}
            &lt;ul&gt;
                {% children %}
            &lt;/ul&gt;
        {% endifchildren %}
      &lt;/li&gt;
    {% endnav %}
</code></pre>

<p></p>

<p>The entire list gets flattened, alphabetized, and then spit back out into a nonsensical hierarchy, like so:</p>

<ul>
<li>Beans</li>
<li>Banana</li>
<li>Fruit

<ul>
<li>Grapes</li>
<li>Ground Beef</li>
</ul></li>
<li>Lentils</li>
<li>Meat

<ul>
<li>Peas</li>
<li>Peach</li>
<li>Strawberry</li>
</ul></li>
</ul>

<p>Is there any way to alphabetize by one level at a time, without completely reinventing the way Craft handles categories? Thanks!</p>

CC BY-SA 3.0
2016-02-15T16:58:36.283Z
it would be nice to have Craft do the "right" thing here IMO or implement a sort order on the {% nav %} tag. Sent a bug / feature request (not sure which is more appropriate IMO)...
RitterKnight
<templating>
How do I sort categories by title while preserving hierarchy?
# How do I sort categories by title while preserving hierarchy?

(Asked by: username_0 on 2016-02-14)

New to Craft. I'm outputting a list of all the categories in my site.
When I do this:

    {% nav category in craft.categories %}
      
        {{ category.title }}
        {% ifchildren %}
            
                {% children %}
            
        {% endifchildren %}
      
    {% endnav %}


I end up with (for example):

Legumes


Peas
Beans
Lentils

Meat


Ground Beef

Fruit


Peach
Banana
Strawberry
Grapes


I'd like those to be alphabetical, though, so Fruit, Legumes, and Meat, are listed in that order, with their children also listed in alphabetical order in the nested list.
However, when I do THIS:

    {% nav category in craft.categories.order('title') %}
      
        {{ category.title }}
        {% ifchildren %}
            
                {% children %}
            
        {% endifchildren %}
      
    {% endnav %}


The entire list gets flattened, alphabetized, and then spit back out into a nonsensical hierarchy, like so:

Beans
Banana
Fruit


Grapes
Ground Beef

Lentils
Meat


Peas
Peach
Strawberry


Is there any way to alphabetize by one level at a time, without completely reinventing the way Craft handles categories? Thanks!

**Tags:** templating
> **Comments:**
> **username_1**: it would be nice to have Craft do the "right" thing here IMO or implement a sort order on the {% nav %} tag. Sent a bug / feature request (not sure which is more appropriate IMO)...  

---

## 1 answers

### Answer by username_2 on 2016-02-14. Score: 3

You should be able to do this with a recursive macro.
Here is a macro alphaList which is passed a list of categories (in alphabetic order). For each category, it outputs that category, and then if that category has any children, it calls itself on an alphabetic list of those children.
To get the children of a category c, you combine descendantOf with descendantDist of 1: craft.categories.descendantOf(c).descendantDist(1)
To get the initial list of top level categories, you use the level parameter: craft.categories.level(1). That will mix together categories from all your category groups, so probably you want to specify the group: craft.categories.group('myGroup').level(1).
{% import _self as self %}

{% macro alphaList(cats) %}
{% import _self as self %}
  {% for c in cats %}
    
      {{c.link}}
      {% set children = craft.categories.descendantOf(c).descendantDist(1) %}
      {% if children|length %}
        
          {{ self.alphaList(children.order('title')) }}
        
      {% endif %}
    
  {% endfor %}
{% endmacro %}

{% set topCats - craft.categories.level(1) %}

  {{ self.alphaList(topCats.order('title')) }}


---

