Is there a way to only fetch categories that have been assigned to a minimum of entries, i.e. 4?

Currently I fetch categories like this:

{% set productIds = craft.entries.section('products').ids() %}
{% set categories = craft.categories.relatedTo({ sourceElement: productIds }) %}

I know I can now do the following to only display content for categories which have been assigned to at least four entries:

{% set entries = craft.entries.section('products').relatedTo(category) %}
{% if entries|length > 4 %}
{% endif %}

But is there a way to apply this logic to the craft.categories query?


What you can always do in situations, where the default parameters are not enough, is to "collect" element IDs and pass them to the id param of a new criteria model.

So loop through all categories and merge the category IDs matching you condition to an array:

{% set topCategoriesIds = mainCategoriesIds|merge([category.id]) %}

When you're done, get your filtered categories from these IDs:

{% set categories = craft.categories.id(topCategoriesIds) %}
  • Thank you Carl. I don't fully follow. How does that give me categories that are related to equal or more than 4 entries? If I understand correctly, this still creates an extra loop and query, so performance wise there is no gain to my original way, is there?
    – Katrin
    Aug 25 '15 at 7:54
  • No, it is really the same to your idea, so no performance gains at all. The only difference is, that you can now query for them with a single criteria model. I thought that's what you needed, as this allows you to paginate the results or do other things not possible when having the conditional in your "output loop".
    – carlcs
    Aug 25 '15 at 8:00
  • That makes sense and am sure would come in very handy in other scenarios. For my current situation, I was looking to see if there was a way to adapt the craft.categories query so that I didn't have to create an additional entries query and loop.
    – Katrin
    Aug 25 '15 at 8:14
  • No, unfortunatelly there's no way to add your custom conditional to the relatedTo param in your query. What about wrapping the output loop in cache tags? How is your PHP/MySQL knowledge, you could write a custom plugin to get them with a single query from the database?
    – carlcs
    Aug 25 '15 at 8:21
  • Yes, definitely a good call on the caching. My PHP knowledge is limited. I could maybe dabble something together, but it isn't absolutely necessary right now and am happy to use what I've got. Thanks for your ideas :)
    – Katrin
    Aug 25 '15 at 10:31

Short answer: There is no way to apply this sort of logic to the craft.categories query. The way I have set this up is good. It can be improved performance wise by wrapping the queries around a {% cache %} tag.

As Carl has pointed out in his answer, the matching categories could also be merged into an array and added to a new query, which could then be used for pagination etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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