2

I'm using Craft 3 and have created a section (channel type) for my project entries. At the bottom of each project page I have my Prev and Next Project buttons. How do I target the first and last project entry based upon the post date? I want to add some space between the buttons when they're together, but dispense with it on the first and last entries because.

Below is my current code from my project _entry template for the buttons:

{% set params = {section: 'projectEntries', order: 'postDate desc', limit: null} %}
{% set entry_prev = entry.getPrev(params) %}
{% set entry_next = entry.getNext(params) %}

Then on the buttons I'm using an if statement to show the next or prev URLs.

To target the first entry I've tried using :

{% if craft.entries.section('projectEntries').order('postDate desc').one() %}
    show alt button code
{% else %}
    show regular button code
{% endif %}

Which shows my alt button code, but shows it on every project page, instead of just on the first entry.

What do I need to do?

Thanks,

Richard

1 Answer 1

2

The conditional {% if craft.entries.section('projectEntries').order('postDate desc').one() %} basically just tests if the craft.entries.section query returns an entry or not. Obviously, that would evaluate to true on every entry template.

Instead, you probably want to test if the first entry returned by the above query is the same as the current entry. A good way to do that, is to compare the entry IDs:

{% set firstEntry = craft.entries.section('projectEntries').order('postDate desc').one() %}

{% if entry.id == firstEntry.id %}
    ...

To test for the last entry, you could do something like this (notice that the only difference from the above query is that the sort order is reversed):

{% set lastEntry = craft.entries.section('projectEntries').order('postDate asc').one() %}

{% if entry.id == lastEntry.id %}
    ...

If, however, you have access to the entry_prev and entry_next variables within the Twig block that renders the buttons, you can avoid extra database queries altogether by simply checking if those variables are null or not:

{% if not entry_prev %}
    {# No previous entry; the current entry must be the first #}
    ...
{% elseif not entry_next %}
    {# No next entry; the current entry must be the last #}
    ...
{% else %}
    {# The current entry is neither the first nor last #}
    ...
{% endif %}

If you can't use the entry_prev and entry_next variables, a more optimized way to do it than pulling the first and last entries would be to do something like the below – note the use of ids() instead of all(); this is an optimization due to it being cheaper to just pull the entry IDs instead of the full entry models:

{% set allEntryIds = craft.entries.section('projectEntries').order('postDate desc').ids() %}

{% set firstEntryId = allEntryIds|first %}
{% set lastEntryId = allEntryIds|last %}

{% if entry.id == firstEntryId %}
    {# The current entry is the first one #}
    ...
{% elseif entry.id == lastEntryId %}
    {# The current entry is the last one #}
    ...
{% else %}
    {# The current entry is neither the first nor the last #}
    ...
{% endif %}
3
  • 1
    Thanks for the reply Mats! Your answer worked perfectly. Commented Jul 27, 2018 at 18:38
  • I used your ids() method in the end, which enabled me to leave off padding on the first and last buttons of my project entries pagination, and then add some padding on the buttons for everything else. Commented Jul 27, 2018 at 19:16
  • I added an alternative approach to the answer; if you've access to the entry_prev and entry_next variables within the Twig block rendering the buttons, simply testing those values would be the most performant way to achieve your goal. Commented Jul 27, 2018 at 19:40

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.