18

I've got following model:

items: {
    someId1: 
        {
            property1....
        },
    someId2: {...},
    someIdN: {...}
}

I would like to get a for-loop in my template (nunjucks) which goes through all the "someId's". Does anyone have any idea how? A normal for-loop does not work since it's not an array and since I use the "someId.." for a reference in another template I cannot put it to an array.

Any help would be awesome.

Tikkes
  • 4,599
  • 4
  • 36
  • 62

3 Answers3

44

This answer is actually right on the Nunjucks homepage:

<ul>
   {% for name, item in items %}
      <li>{{ name }}: {{ item }}</li>
   {% endfor %}
</ul>

In your case this would be:

<ul>
   {% for someId, item in items %}
      <li>{{ someId }}: {{ item.property1 }}</li>
   {% endfor %}
</ul>

As you can use the for loop for arrays and object/hashes.

Rich
  • 5,603
  • 9
  • 39
  • 61
Jasper Moelker
  • 1,390
  • 13
  • 10
  • 1
    I was just looking through a similar problem with a coworker. This does what we want, but one problem with the solution is that, because this is javascript, the order of the looping cannot be guaranteed. http://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order – Josh Brown Apr 14 '16 at 17:10
1

You can use nested loops like this:

<ul>
  {% for item in items %}
    {% for something in item.someId1 %}
      <li>
        {{ something.property1 }}
      </li>
    {% endfor %}
  {% endfor %}
</ul>

For this json object:

items: {
  someId1: {
    property1: "It makes you want to shout! Raise your hands up and..."
  },
  someId2: {...},
  someIdN: {...}
}
KyleMit
  • 30,350
  • 66
  • 462
  • 664
0

I think the answer you're looking for is to use something like this:

{% for tuple in items | dictsort %}
   <p>{{tuple[0]}}, {{tuple[1]}}</p>
{% endfor %}

Very simply the dictsort filter returns a list of tuples(key-value pair) from the object in a sorted manner, which can then be accessed as follows.

So, if the object is

items: {
    someId1: 
        {
            property1....
        },
    someId2: {...},
    someIdN: {...}
}

You would get,

[['someid1',{property1: ..}], ['someid2','...'], ['someid3','...']]

Now you can just use the loop as if you were looping through an array. Keep in mind that additional nested properties must be handled manually too.

The previous answers suggested manually extracting each property. What if I wanted the same page with data that has 5 properties as well as 10 properties. What if I wanted all keys by not specifying them? Which is something I came across and stumbled upon this question. As of 2022, we can use dictsort but previous answers may worked just as well.

Aryan3212
  • 121
  • 2
  • 9