eleventy: Can't iterate over a global data subfolder

My global data are contained in subfolders of the main data folder. For instance: data/subdata. My Nunjucks for loop is:

{% for sub in subdata %}
.....
{% endfor %}

However I never get anything: no looping! But if I put: subdata.entry.property or subdata['entry'].property I get that property. I mean, if I know the name of the data subfolder, I can retrieve anything declared in that data file. Does it mean that I can’t iterate over the data subfolders?

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 1
  • Comments: 26 (8 by maintainers)

Most upvoted comments

Whoa, this thread kinda went off the rails and there is a lot of misinformation in here—sorry, everyone. Wish I would’ve stepped in sooner.

The original problem @octoxalis had was a simple misunderstanding of how Nunjucks loops work.

Consider the following project structure: image

Here’s what {{ subdata | dump }} looks like: image

It’s true that this outputs nothing:

{% for key in subdata %}
{{ key }}
{% endfor %}

However that’s only because you’re looping over an object literal, not an array. Absolutely you can iterate over subdata!

This is what you want:

{% for key, val in subdata %}
{{ key }}
{% endfor %}

Output: image

Does that help everyone?

Whoa, this thread kinda went off the rails and there is a lot of misinformation in here—sorry, everyone. Wish I would’ve stepped in sooner.

The original problem @octoxalis had was a simple misunderstanding of how Nunjucks loops work.

Consider the following project structure: image

Here’s what {{ subdata | dump }} looks like: image

It’s true that this outputs nothing:

{% for key in subdata %}
{{ key }}
{% endfor %}

However that’s only because you’re looping over an object literal, not an array. Absolutely you can iterate over subdata!

This is what you want:

{% for key, val in subdata %}
{{ key }}
{% endfor %}

Output: image

Does that help everyone?

The key, value piece is tripping me up. I have multiple files in _data/team with a name like bob.json and structured like so:

{
  "name": "Bob",
  "github": "bobsgithub",
  "twitter": "bobstwitter",
  "linkedin": "https://www.linkedin.com/in/bob/",
  "blog": "https://medium.com/@bob"
}

I can {{ team | dump }} and see all of the json output.

But I can’t figure out how to use the data in a template like so: {{ name }}, {{ blog }}, etc.

Any pointers?

@plainspace You could move the weights into the members.json file. I can’t see how you could create a custom collection from files in the _data/ directory.

[
  {"name": "bob", "weight": 20},
  {"name": "david", "weight": 10}
]

Then our nunjucks template can sort by weight:

<ul>
{%- for member in team.members | sort(false, false, "weight") %}
  <!-- {{ member | dump | safe }} -->
  {%- set weight = member.weight %}
  {%- set member = team[member.name] %}
  <li>{{ member.name }} &mdash; @{{ member.twitter }} &mdash; {{ weight }}</li>
{%- endfor %}
</ul>

OUTPUT:

<ul>
  <!-- {"name":"david","weight":10} -->
  <li>David &mdash; @davidstwitter &mdash; 10</li>
  <!-- {"name":"bob","weight":20} -->
  <li>Bob &mdash; @bobstwitter &mdash; 20</li>
</ul>

You could also move all the members into a single data file to make it easier to sort. But it really depends on how you’re using the data.

Thanks! Not sure if this is the right place to ask but let’s see:

I’d like to sort the data now. Some of the _data/team/{{ name }}.json files have a weight attribute in them.

I’m expecting that the following would move the members with a weight to the top of the list and order them ascending and then order those without a weight alphabetically. I’m assuming that isn’t working because the order in members.json is defining the order.

{%- for member_name in team.members|sort(attribute='weight') %}

No worries @jevets—just a simple mistake 👍 I appreciate the help you’ve been providing on the tracker!!

I think I’m missing something here but for example considering the json file to be already an array of object.

_data/2013_feedbacks.js

const fb = require('./2013/feedbacks.json');
module.exports = function(fb) {
  return fb;
};

then applying the following in an .md file

---
layout: layouts/base.njk
enableFasciaFeedback: true
feedbacks: {{ 2013_feedbacks }}
---

I expect feedback to be populated with the content of _data/2013/feedbacks.json but I don’t get any value.