I currently have multiple sections like so:

{% for craft.entries.section('mySection').type('oneType')... %}
   ... {% endfor %}
{% for craft.entries.section('mySection').type('anotherType')... %}
   ... {% endfor %}

But I would rather have a single loop like this:

{% for craft.entries.section('mySection').order('type, title')... %}

However, the type referred to in order() will in the DB query refer to craft_elements.type which in this case always will be Entry.

Is it possible to order by entry type?

3 Answers 3


You could use Craft's group filter for this, but you'll lose the ability to use the paginate tag to paginate your entries by doing so.

{% set entries = craft.entries.section('mySection').order('title') %}
{% set entriesByType = entries|group('type') %}

{% for type, entriesInType in entriesByType %}
    <h3>{{ type }}</h3>

    {% for entry in entriesInType %}
        <p>{{ entry.title }}</p>
    {% endfor %}
{% endfor %}

Craft doesn't join the entrytypes table when you query for entries. You could order by typeId, but that's probably not what you want.

Fortunatelly there's an elements.buildElementsQuery event, that allows to modify element queries.

craft()->on('elements.buildElementsQuery', function(Event $event) {
    $query = $event->params['query'];

    if (strpos($query->order, 'entrytypes') !== false) {
        $query->join('entrytypes entrytypes', 'entrytypes.id = entries.typeId');

Add this code to the init() method of your business logic plugin and you can now order by your entry type handles.

{% set entries = craft.entries({
    section: 'mySection',
    order: 'entrytypes.handle desc, title asc',
}) %}

You could use my Preparse Field plugin, which let's you run twig code when an entry is saved, and saves the result of the twig as plain text in the field.

If you just wanted to sort alphabetically by entry type name, you could put something like this in your preparse field settings:

{{ entry.type | lower }}

And then go:

{% for craft.entries.section('mySection').order('myPreparseField, title')... %}

Or, you could do more advanced logic if you want some custom order, like:

{{ entry.type=='type1' ? 1 : (entry.type=='type2' ? 2 : 3) }}

Make sure you get rid of whitespace in the output, either by not adding any to your code (like above), or by using {{ spaceless }} or - on tags.

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.