I have an array of products that has already been filtered by a brand category. I want to display them in a list ordered by a size category. This is working, but I think there must be a better way:

{% set productList = craft.entries(params) %} 
  {# where params includes a relatedTo parameter already #}

    {% for size in sizes %}
        {% for product in productList %}
            {% if product.sizeCategory.first.id == size.id %}
                {{ product.title }}<br />
            {% endif %}
        {% endfor %}
    {% endfor %}

2 Answers 2


First, grab the list of your products, filtered by category:

{% set productList = craft.entries(...).relatedTo(...) %}

Group all products by size using the group filter

{% set productList = productList | group('sizeCategory.first.whatever')

Now you have an array of arrays. The keys in the array hold the various values of the size variable, and the values of the array hold the arrays of entries within those size groups. (Within the groups, any ordering parameters you set on the original ElementCriteriaModel should be retained.)

To sort the groups according to the array size, you can use SuperSort's ksort functionality:

{% set productList = productList | supersort('ksort', false, SORT_NUMERIC) %}

To finish, just loop through this list of lists, outputting them in whatever style/markup you want:

{% for size, products in productList %}

    {{ size }}

    {% for product in products %}

        {{ size }}
        {{ product.whatever }}

    {% endfor %}

{% endfor %}

You should be able to order them using a combination of the order method (if needed) and group twig filter.

{% set productList = craft.entries.(params).order('title')|group('myCategoriesField.first().title') %}

The problem here is that the products might end up being displayed in the order that the size categories were created (i.e. postDate) and not the category 'size' title. If this is a problem then your solution may in fact be the only way. Have a look at this question for alternative answer and discussion of some of the issues.

  • They probably end up being sorted in the order in which they get found in the title ordered entries list. So first entry "Anton" got the category "Xylophone" assigned and this makes "Xylophone the first key in the grouped "productList" array.
    – carlcs
    Commented Apr 3, 2015 at 0:16
  • This probably could be solved by sorting the array using something like that SuperSort plugin. {% do productList|supersort(ksort) %} should probably be the method one needs here.
    – carlcs
    Commented Apr 3, 2015 at 0:22
  • Thanks for your help! I had used that question for testing out solutions before I posted my own question. I still don't quite understand why using the group twig filter didn't work for me, but the results it returned were not in the same order as the list of categories in the size category group. For example, my size categories are 4, 10, 25 320, 1280 (added to Craft in the order I want them displayed - in other words, the ids are in the correct order). The group filter returned the list as 4, 10, 1280, 320, 25...???
    – Chandra
    Commented Apr 6, 2015 at 19:39
  • @carlcs I tried the SuperSort plugin. The product list was sorted correctly for the size category field using {% set sortedProducts = productList | supersort('sortAs', '{sizeCategory.first}', SORT_NUMERIC) %} but it seems to be ignoring the order parameters I set in the original params. In other words, I need it ordered by size, then by two other custom numeric fields.
    – Chandra
    Commented Apr 6, 2015 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.