2

I am looking to filter entries by a given month regardless of year. The filter would be based on a custom Date/Time input. My last goal would allow them to be paginated.

{% set firstDayOfMonth = year ~ "-" ~ month ~ "-01" %}
{% set daysInThisMonth = firstDayOfMonth|date('t') %}
{% set lastDayOfMonth  = year ~ "-" ~ month ~ "-" ~ daysInThisMonth %}

{% set thisMonthsEntries = craft.entries.section('messages').messageDate('and', '>= ' ~ firstDayOfMonth, '<= ' ~ lastDayOfMonth) %}

{% paginate thisMonthsEntries as entriesOnPage %}
    {% for entry in entriesOnPage %}
        {# ... whatever your code does... #}
    {% endfor %}
{% endpaginate %}

This is my original code. My first guess is I would need to have an array of years and loop through each year applying to the above code, however I am unclear on how to get a unique list of years that my entries are related too. Then I would probably have multiple sets of entries which would then need to be merged some how for output.

1

I think you are right and there's no chance to do what you want with parameters on a single ElementCriteriaModel.

You could definitely do it with many queries, the first one to get your years array, then one for each year. Merging them is simple with Twig's merge filter. But then you'd end up with a manually composed array of entry models and don't have the convenience of a single ElementCriteriaModel. Methods like getNext() or – important in your case – the {% paginate %} tag won't work with an array of entry models!

Let's skip the paginate problem for now and look at that query flood, you'd produce. Sure, Craft has the {% cache %} tag, but if your entries are modified regularly, there'll always be people who access the uncached version.

But what about another solution, why not do a single query to get all your "messages" entries and filter them in your template with a simple conditional:

{# Get all `messages` entries #}
{% set entries = craft.entries.section('messages') %}

{# Loop through all entries with a `messageDate` month of `myMonth` regardless the year #}
{% for entry in entries if entry.messageDate|date('m') == myMonth %}
    {{ entry.title }}
{% endfor %}

You'd still have no solution yet for your pagination problem, but this should be way less expensive on performance, and it's really easy to implement.

  • I will need pagination due to the amount of entries that will be on the page. Which makes me think, if there is a lot of overhead to filter the way I need, my UX for filtering might need to change. I may need to have the client offer a drop-down for year as well as month. – aran Aug 12 '14 at 18:30
  • You mean you're backpedaling to .messageDate('and', '>= ' ~ firstDayOfMonth, '<= ' ~ lastDayOfMonth)? – carlcs Aug 12 '14 at 18:51
  • 1
    Using a single ElementCriteriaModel is probably your best bet to get pagination implemented. All other methods would require a custom replication.. – carlcs Aug 12 '14 at 18:55

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.