Jesse Spielman
Jesse Spielman

Reputation: 341

How do I access part of a list in Jinja2

I'm trying to use the jinja2 templating langauge to return the last n(say, 5) posts in my posts list:

{% for recent in site.posts|reverse|slice(5) %}
    {% for post in recent %}
        <li> <a href="/{{ post.url }}">{{ post.title }}</a></li>
    {% endfor %}
{% endfor %}

This is returning the whole list though. How do you strip the first or last n elements?

Upvotes: 34

Views: 49169

Answers (8)

Abc Xyz
Abc Xyz

Reputation: 1424

{% for recent in site.posts[-5:][::-1] %}
    {% for post in recent %}
        <li> <a href="/{{ post['url'] }}">{{ post['title'] }}</a></li>
    {% endfor %}
{% endfor %}
  1. [-5:] - last 5 posts
  2. [::-1] - reverse order

Upvotes: 2

pratik soni
pratik soni

Reputation: 61

To get the last element, get total index from the array list.

For example, your object name is foundappointmentlog.

{% set total=foundappointmentlog|length %} //it return length
{{foundappointmentlog[total-1].appointment_result}}  // here you get your last value using index 

Upvotes: -2

mattgately
mattgately

Reputation: 1032

For me, the following simple code works and doesn't require the whole chain of jinja filters. Simply use the list filter to convert to list and then do normal array slicing (note the parantheses):

{% for recent in (site.posts | list)[-5:] %}
  {% for post in recent %}
    <li> <a href="/{{ post.url }}">{{ post.title }}</a></li>
  {% endfor %}
{% endfor %}

I had the same problem, but my data was in a sequence rather than a list and this code handles both.

Upvotes: 5

Andrew
Andrew

Reputation: 669

@Andrey's answer has the right idea. However, to fully solve your question:

{% for recent in site.posts|batch(5)|list|last|reverse %}
        <li> <a href="/{{ recent.url }}">{{ recent.title }}</a></li>
{% endfor %}

Alternatively:

{% for recent in site.posts|reverse|batch(5)|first %}
        <li> <a href="/{{ recent.url }}">{{ recent.title }}</a></li>
{% endfor %}

Whichever one you use depends on your preferences.

Upvotes: 2

joemurphy
joemurphy

Reputation: 606

I had the same problem too. It's a simple answer. This retrieves the last five items in site.posts:

{% for recent in site.posts[-5:] %}
    {% for post in recent %}
        <li> <a href="/{{ post.url }}">{{ post.title }}</a></li>
    {% endfor %}
{% endfor %}

Upvotes: 24

Rico Schiekel
Rico Schiekel

Reputation: 189

this is a bit simpler I think without the use of the slice filter:

{% for post in site.posts | reverse | list[0:4] %}
  <li>&raquo; <a href="/{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}

another way is to use the loop controls extension:

{% for post in site.posts | reverse %}
  {%- if loop.index > 4 %}{% break %}{% endif %}
  <li>&raquo; <a href="/{{ post.url }}">{{ post.title }}</a></li>
{%- endfor %}

Upvotes: 18

Andrey Vlasovskikh
Andrey Vlasovskikh

Reputation: 16838

I came up with the following code:

{% for x in xs | batch(n) | first %}
    ...
{% endfor %}

The batch(n) filter splits a list xs into sublists of length n, then the first filter selects the first of these sublists.

Upvotes: 12

Garrett
Garrett

Reputation: 49836

Try subscript notation, as in normal Python. For example, to take the last 5 posts and display them in reverse order:

import jinja2
tmpl = """\
{%- for col in posts[-5:]|reverse|slice(3) -%}
    {%- for post in col -%}
        {{ post }}
    {%- endfor -%}
    <br>
{%- endfor -%}"""
jinja2.Template(tmpl).render(posts=[1,2,3,4,5,6,7])

produces: u'76<br>54<br>3<br>'

Upvotes: 5

Related Questions