11ty / eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.
https://www.11ty.dev/
MIT License
16.84k stars 487 forks source link

Loop json data within shortcode #1751

Open Brixy opened 3 years ago

Brixy commented 3 years ago

Hi guys!

I am trying to feed shortcodes with json data from /data/_calendar.json.

The calendar shortcodes will be used in numerous places throughout the website—so a simple nunjucks loop in a template file or including a file is not a real option.

Here are some usage examples:

{% calendarByYear "2020" %}
{% calendarByLocation "Location" %}
{% calendarBySpeaker "Name of speaker" %}

Is there any to loop through a json data file within a shortcode?

Sorry if this question has been asked already, yet I’m not quite sure whether #1154 is related.

Thank you very much.

pdehaan commented 3 years ago

OPTION 1

There are probably a few different says to do this, but you can require() your /_data/calendar.json file in your .eleventy.js config file and parse/filter the values there:

const calendar = require("./src/_data/calendar.json");

module.exports = eleventyConfig => {
  eleventyConfig.addShortcode("calendarByYear", (year) => {
    return calendar.filter(event => new Date(event.date).getFullYear() === parseInt(year, 10))
      .map(event => `<div><p>${event.name} at ${event.date}</p></div>`)
      .join("\n");
  });

  // {% calendarByYear "2020" %}
  // {% calendarByLocation "Location" %}
  // {% calendarBySpeaker "Name of speaker" %}

  return {
    dir: {
      input: "src",
      output: "www"
    }
  };
};

USAGE

{% calendarByYear 2020 | safe %}

OPTION 2

Another option is to pass the global calendar object to your shortcode.

module.exports = eleventyConfig => {
  eleventyConfig.addShortcode("calendarByYear2", (data=[], year="") => {
    return data.filter(event => new Date(event.date).getFullYear() === parseInt(year, 10))
      .map(event => `<div><p>${event.name} at ${event.date}</p></div>`)
      .join("\n");
  });

  return {
    dir: {
      input: "src",
      output: "www"
    }
  };
};

USAGE

{% calendarByYear2 calendar, "2021" | safe %}

Where my super awesome(tm) ./src/_data/calendar.json file looks like:

[
  {
    "name": "Dance Party",
    "date": "2021-04-19",
    "location": "Home"
  },
  {
    "name": "Eleventy Meetup",
    "date": "2020-12-24",
    "location": "Online"
  },
  {
    "name": "New Years Eve",
    "date": "2020-12-31",
    "location": "Boat"
  }
]
Brixy commented 3 years ago

Super awesome(tm)! Thank you very much for your explanation and your time. Problem solved.

A shortcode looping over a data file is a common task, I guess, but I did not find it documented on the Eleventy website. Shall I leave this issue open?