Cannot get index of item in array with Nunjucks for loop
Asked Answered
L

4

11

I'm having some trouble getting indexes of a items in an array from a Nunjucks {% for %} loop.

The array I am targeting is simple and looks like this

pages[1,2,3]

And this is the Nunjucks loop

{% for i,p in data.tickets.pages %}
  {{ i }} : {{ p }}
{% endfor %}

The problem is

{{ p }} outputs 1,2,3 but {{ i }} doesn't output anything.

If anyone can tell me how to fix this, I'd much appreciate it.

Lousy answered 23/8, 2017 at 17:23 Comment(0)
L
33

To get the index in a for loop use loop.index (loop.index starts with a 1)
To get the standard behavior (start with a 0) use loop.index0

data.tickets.pages = [1, 2, 3];

Template code (loop.index)

{% for page in data.tickets.pages %}
  {{loop.index}}: {{ page }}
{% endfor %}

Output

1:1
2:2
3:3

Template code (loop.index0)

{% for page in data.tickets.pages %}
  {{loop.index0}}: {{ page }}
{% endfor %}

Output

0:1
1:2
2:3

See Also the nunjucks docs

  • loop.index: the current iteration of the loop (1 indexed)
  • loop.index0: the current iteration of the loop (0 indexed)
  • loop.revindex: number of iterations until the end (1 indexed)
  • loop.revindex0: number of iterations until the end (0 based)
  • loop.first: boolean indicating the first iteration
  • loop.last: boolean indicating the last iteration
  • loop.length: total number of items
Laudatory answered 9/9, 2018 at 21:5 Comment(0)
C
1

Tipically nunjucks wait single iterator for array. When you use multi-iterator and pass array, nunjucks split each array element by iterator set.

{% set pages = [[10, 11], [12, 13]] %}
{% for a, b in pages %}
{{a}},{{b}}
{% endfor %}
---
10:11
12:13

You can use range, convert array to object (element order can be lost) or use loop.index0'/loop.index

var nunjucks  = require('nunjucks');
var env = nunjucks.configure();

// range
var res = nunjucks.renderString(`
    {% for i in range(0, items.length) %}
    {% set item = items[i] %}
    {{i}}: {{item}}
    {% endfor %}`, 
    {items: [10, 12]}
);

console.log(res);

// array to object
res = nunjucks.renderString(`
    {% for i, item in items %}
    {{i}}: {{item}}
    {% endfor %}`, 
    {items: Object.assign({}, [10, 12])}
);

console.log(res);

// loop.index0
res = nunjucks.renderString(`
    {% for item in items %}
    {{loop.index0}}: {{item}}
    {% endfor %}`, 
    {items: [10, 12]}
);

console.log(res);
Confirmand answered 24/8, 2017 at 9:15 Comment(1)
Thanks for response. I was really hoping it would be a more trivial fix in the template without the need for more tinkering with Nunjucks configuration.Lousy
A
0

For anyone coming here by ways of Google or whatever. I was able to use the method with range loop described above directly in my template, and even nesting loops.

Here's part of my code directly in a nunjucks template:

<ul class="index">
    {% for x in range(0, dbReport.sections.length) %}
        {% set section = dbReport.sections[x] %}
        <li>
            <strong>{{ x + 1 }}</strong> {{ section.sectionTitle }}
            <ul>
                <li>
                    <strong>{{ x + 1 }}.1</strong> Section components:
                    <ul>
                        {% for y in range(0, section.subSections.length) %}
                            {% set subSection = section.subSections[y] %}
                            <li>
                                <strong>{{ x + 1 }}.1.{{ y + 1 }}</strong> {{subSection.subSectionTitle}}
                            </li>
                        {% endfor %}
                    </ul>
                </li>
            </ul>
        </li>
    {% endfor %}
</ul>
Adjectival answered 8/3, 2021 at 15:22 Comment(0)
P
0

with array.entries()

{%- for pageIndex, page in collections.pages.entries() -%}
  <div class="page" id="page-{{ pageIndex + 1 }}">
    {{ page.templateContent | safe }}
  </div>
{%- endfor -%}

Paleo answered 12/3, 2021 at 14:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.