Loop through entries with custom ordering, showing one from each category then start loop again I have a channel with entries that may or may not have a custom date field populated.

I'd like the display a list of entries, looping through each category, showing one entry from each category. Then just start the loop again.

Then, show the rest of the entries which don't have the date field populated. I guess they would just have to be just ordered by postDate, but still only showing one per category each loop.

So (assuming there are 3 categories in total)...


Entry - 4th April - Category 1
Entry - 6th April - Category 2
Entry - 8th April - Category 3
Entry - 5th April - Category 1 - start the loop through categories again
Entry - 7th April - Category 2
Entry - 9th April - Category 3
Entry - Category 1
Entry - Category 2
Entry - Category 3


Note that the dates appear jumbled, as the categories are the thing dictating the order. Date order is a factor, but secondary to the looping of the categories.

This is the code I have so far, all it does is output the entries but with the ones without date fields populated appearing first.

{% for entry in craft.entries.section('heroes').order('date') %}

    {% if entry.date|length %}

        &lt;article&gt;
            &lt;h3&gt;&lt;a href="{{ entry.url }}"&gt;{{ entry.title }}&lt;/a&gt; - {{ entry.date|date("j") }}{{ entry.date|date("S") }} {{ entry.date|date("F") }} {{ entry.date|date("Y")}} - {% for category in entry.genre %}{{ category.title }}{% endfor %}&lt;/h3&gt;
        &lt;/article&gt;

    {% else %}

        &lt;article&gt;
            &lt;h3&gt;&lt;a href="{{ entry.url }}"&gt;{{ entry.title }}&lt;/a&gt;&lt;/h3&gt;
        &lt;/article&gt;

    {% endif %}

{% endfor %}


Hope that makes sense! Any help will be appreciated.
I'd suggest breaking your problem down into code which gathers the IDs of each of the types of entries first, then outputs them....roughly like this (very much untested!! - but should be enough to understand the approach):

{# Arrays to store the IDs of the entries as we find them #}
{% set noDateIDs = [] %}
{% set dateIDs = [] %}

{% for entry in craft.entries.section('heroes').order('date') %}

    {% if entry.date|length %}
        {% set dateIDs = dateIDs|merge([entry.id])} %}
        {# Or of course you could output the data you want here directly but I like to keep my building and output separate for clarity #}
    {% else %}
        {% set noDateIDs = noDateIDs|merge([entry.id])}  %}
    {% endif %}

{% endfor %}

{% set noDateIDsString = noDateIDs|join(', ') %}
{% set dateIDsString = dateIDs|join(', ')  %}

{# Now actually output the dated entries #}
{% for entry in craft.entries.section('heroes').id(noDateIDsString).find() %}

    &lt;article&gt;
        &lt;h3&gt;&lt;a href="{{ entry.url }}"&gt;{{ entry.title }}&lt;/a&gt; - {{ entry.date|date("j") }}{{ entry.date|date("S") }} {{ entry.date|date("F") }} {{ entry.date|date("Y")}} - {% for category in entry.genre %}{{ category.title }}{% endfor %}&lt;/h3&gt;
    &lt;/article&gt;

{% endfor %}

{# Output the undated ones ordered by postDate #}
{% for entry in craft.entries.section('heroes').id(dateIDsString).order('postDate') %}

        &lt;article&gt;
            &lt;h3&gt;&lt;a href="{{ entry.url }}"&gt;{{ entry.title }}&lt;/a&gt;&lt;/h3&gt;
        &lt;/article&gt;

{% endfor %}


This approach is very useful generally in Craft, and is documented really well here in 'Manipulating Craft's ElementCriteriaModel objects with Twig' by Jérôme Coupé of Webstoemp