Is there a way to find the current entry's index? So I want to know how many news items has been posted before the current one.

So when I'm looking at the first news item, it should show "no.1", and for news item 15 show "no.15" and so on.

What I have currently is getting all news items, ordered by date, loop through them until I find the one I'm on, and show the loop.index, which seems like it might be a bit slow, especially when we get to item number 100, 200 and so on.


There's no way to do that without a query to the DB.

Not sure if this is really faster, but try to only query for the IDs and see how this performs for you. Another thing you could do, is to add your conditional directly to the for loop tag:

{% set entryIds = craft.entries.section('news').order('postDate asc').ids() %}

{# Get the position of this entry's ID within our IDs array #}
{% set position = '' %}
{% for key, value in entryIds if value == entry.id %}
    {% set position = key + 1 %}
{% endfor %}

{# Get the amount of total entries #}
{% set total = entryIds|length %}

{{ entry.title }} (no. {{ position }} / {{ total }})

If you are not interested in the total number, here's another way to get the position. The syntax is simpler, though it does not perform better, as you still need to query for the entries:

{# Get this entry + all entries posted before it #}
{% set postDateParam = '<= ' ~ entry.postDate|date('c') %}
{% set entryIds = craft.entries.section('news').order('postDate asc').postDate(postDateParam).ids() %}

{# Count them #}
{% set position = entryIds|length %}

{{ entry.title }} (no. {{ position }})
  • Would it be possible to do a custom DB query to get all news items that have a postDate lower than the one I'm currently on? If so, I could just do {{ olderEntries | length }}, right? – peirix Dec 8 '14 at 14:51
  • Yep. But then you would need two queries. One for position / older entries and one for total. My solution gives you both numbers (+ 3rd using math) with just one IDs query. The Twig code is fast!! – carlcs Dec 9 '14 at 1:40
  • Well, I don't really need to know the total. All I need is the text "no. 2". And, yeah, I've noticed that twig is fast. It just kinda feels dirty to use a loop to find that number. – peirix Dec 9 '14 at 10:01
  • It only enters the loop once because of the conditional added to the syntax. But yeah, if you don't need that other numbers, you can leave it out. Will update the answer, @peirix! – carlcs Dec 9 '14 at 10:24

You can use Twig's attribute function.

For array's it is 0-indexed, so if you want the first element, it's:

{% set entries = craft.entries.section('news').find() %}

{% if entries|length %}
    {{ attribute(entries, 0).title }}
{% endif %}

The second would be {{ attribute(entries, 1).title }}, etc.

  • Hm. Think you may have misunderstood the question. I'm not looking to get an entry given an index. It's the other way around. I'm on a entry page, and I want to find the current entry's index. So when I'm viewing a news item, I want to find out how many news items that have been posted before this one. – peirix Dec 7 '14 at 12:34
  • Ahh, I misunderstood. @carlcs's solution looks good, then. craftcms.stackexchange.com/a/5138/57 – Brad Bell Dec 7 '14 at 16:13

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.