1

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)...

  1. Entry - 4th April - Category 1
  2. Entry - 6th April - Category 2
  3. Entry - 8th April - Category 3
  4. Entry - 5th April - Category 1 - start the loop through categories again
  5. Entry - 7th April - Category 2
  6. Entry - 9th April - Category 3
  7. Entry - Category 1
  8. Entry - Category 2
  9. 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 %}

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

    {% else %}

        <article>
            <h3><a href="{{ entry.url }}">{{ entry.title }}</a></h3>
        </article>

    {% endif %}

{% endfor %}

Hope that makes sense! Any help will be appreciated.

2

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() %}

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

{% endfor %}

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

        <article>
            <h3><a href="{{ entry.url }}">{{ entry.title }}</a></h3>
        </article>

{% 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

  • You can probably pass the ids directly as an array rather than doing that string conversion, not sure on that... – Jeremy Daalder Feb 28 '16 at 5:04
  • Apologies, I rephrased my question. Your answer is great for weeding out the ones without dates but I still need to loop through the categories, first and foremost. – MikeeBee Feb 28 '16 at 7:00
  • Just to finish off our slack convo it's easy to loop over categories. Within you could e.g. loop dates and get the 1st entry for that cat on that date. I still don't think that's quite what you want - the better approach would be list all the events that are under a category by date, or list events on a date by ctaegory. Looping both categories and dates is tricky & I am not even convinced the output would make much sense from a presentation point of view so I'd advise talking to the client more and showing them more real world examples of where this might not make much sense. Just my 2c! – Jeremy Daalder Feb 29 '16 at 1:27
  • Agreed. The output will make no sense and be unhelpful to the user. I'm pushing back to the client in the hope that they see sense! Still might have to do it though :/ – MikeeBee Feb 29 '16 at 6:05

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.