11ty / eleventy

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

Accessing global data in eleventyConfig.addCollection #775

Open tschofen opened 4 years ago

tschofen commented 4 years ago

I'm trying to create arbitrary pages from a complex global data file. I've been playing with 'addCollection' and am able to create pages. However, I can't figure out how to pass in the global data object into the addCollection method.

Here's what my util function looks like. As you can see the data to extract is currently hard-coded in the util.

  let results = []
  data.forEach((item) => {
    item.comments.forEach(comment => {
      results.push(comment)
    })
  });

  return results
}

exports.getNestedData = collection => {
  return getComments(collection, [
    {name: 'one', comments: ['one', 'two', 'three']},
    {name: 'eins', comments: ['eins', 'zwei', 'drei']}
  ]);
}

Relevant code in eleventy.js:

eleventyConfig.addCollection("getNestedData", require("./_utils/nested").getNestedData);

And finally pulling it into the page: Orders is the name of the global data file.

---
layout: layouts/main
title: Orders
permalink: /index-{{ pagination.pageNumber }}.html
postAction: search-results.html
pagination:
  data: collections.getNestedData orders
  size: 1
  alias: order
---
Pagination: {{pagination}}

Any idea how I can pass in the global data, or if need be access the global data file from within the getNestedData function?

Thanks in advance.

KyleMit commented 4 years ago

There's a similar issues #846 on addCollection and Global Data.

My understanding of the .addCollection API the collection parameter provided to the function is your nexus point to all other things eleventy.

module.exports = function(eleventyConfig) {
  eleventyConfig.addCollection("myCollectionName", function(collectionApi) {
    // do stuff here
    return {} // ... return whatever you want
  });
};

So in the example above, you can use collectionApi to grab global data, although the path isn't quite straightforward. Essentially, the collection object has an .items property with all the available templates and the data that is passed to them. Since global data is on every template, you can lift straight from there:

eleventyConfig.addCollection("dogsCollection", function(collectionApi) {
    var a = collectionApi.items[0].data.dogs;
    return a;
});

So in your case, I'd modify getNestedData

 exports.getNestedData = collection => {
+  let globalDogsData = collection.items[0].data.dogs;
+  // use data however you want
   return getComments(collection, [
     {name: 'one', comments: ['one', 'two', 'three']},
     {name: 'eins', comments: ['eins', 'zwei', 'drei']}
   ]);
}

That at least provides a vehicle for getting global data during the addCollection call - maybe there could be a collectionApi.getGlobalData() in TemplateCollection call down the road or some other vehicle I'm not aware of

rr923 commented 1 year ago

Hi, how is the status? Can we access global data within .addCollection? Right now seems we can only access templates data.