Maybe I am missing something in the docs but I have an array of data from contentful that needs to get turned into pages using the same template. I'd love to hear how you'd approach this currently, but I think it would be amazing to be able to do something like this:
// projects is an array of objects that each look like
// { ... title: 'whatever', description: 'whatever' ...}
projects.forEach(project => {
createPage({
data: project,
template: 'project.njk',
dir: /projects
})
}
We don鈥檛 support a programmatic API yet but this is the ground that the pagination module covers!
https://github.com/11ty/eleventy/blob/master/docs/pagination.md
Moving this to be a feature request. This will require upvotes to get traction.
This repository is now using lodash style issue management for enhancements. This means enhancement issues will now be closed instead of leaving them open.
The enhancement backlog can be found here: https://github.com/11ty/eleventy/issues?utf8=%E2%9C%93&q=label%3Aneeds-votes+sort%3Areactions-%2B1-desc+
I was all set to vote for this until I discovered how pagination can do this for me. SO slick.
layout: layouts/base.njk
pagination:
data: eventslist.events
size: 1
alias: event
permalink: events/{{ event.date }}/index.html
---
<h1>{{ event.title }}</h1>
<p>{{ event.date }}</p>
...
鉂わ笍
i am using this approach to convert a big json file into a bunch of pages. there are a couple of pain points with this though
posts, each item isnt properly added to collections.poststitle = (renderData && renderData.title ? renderData.title : title) in the main layout, instead of just being able to use titletheres a few other things that make using the pagination size:1 approach for converting a data file into a bunch of pages not quite ideal. its close enough to get it going but it would be nice if either this pagination approach was fine-tuned to allow for generated 'pages' to be treated like unique items if size == 1, or perhaps if there was another way to turn a data file into a bunch of pages
A _big_ use case for me when it comes to programmatically generating pages is the following:
I have a posts array that includes posts in multiple languages. If I want to create multiple paginated and localized post list pages, what do I do? One way is to create multiple collections with a key of post-${lang} and then creating multiple .11ty.js files (my templating language of choice) that paginate over each collection. Here's an example:
const lang = 'en'
class BlogTemplateEN {
data() {
return {
pagination: {
data: `posts-${lang}`,
size: 1
},
permalink: props => {
return `/${lang}/blog${
props.pagination.pageNumber === 0
? ""
: `/${props.pagination.pageNumber + 1}`
}/index.html`;
}
};
}
render(props) {
// final template...
}
}
Problem is: I then have to copy and paste the same file, solely changing the lang to something else. I can't even abstract the BlogTemplate class into its own file and spin an instance of it with a different lang, as Eleventy won't be able to pass down its props to it... And say I have to include a new language: instead of simply changing a configuration, I now have to create a whole new file 馃様
I'm super open to ways of solving this specific problem, but overall I miss an imperative API for creating pages as it'd be much easier to leverage JS without having to get into data strings, sizes and other Eleventy-specific ways of doing pagination (which I don't think is super intuitive, honestly!).
@hcavalieri can't you do something like this:
BlogTemplate.js
class BlogTemplate {
language;
data() {
return {
pagination: {
data: `posts-${this.language}`,
size: 1
},
permalink: props => {
return `/${this.language}/blog${
props.pagination.pageNumber === 0
? ''
: `/${props.pagination.pageNumber + 1}`
}/index.html`;
}
};
}
render(props) {
// final template...
}
}
export default BlogTemplate;
BlogTemplateEn.11ty.js
import BlogTemplate from './BlogTemplate';
class BlogTemplateEn extends BlogTemplate {
language = 'EN';
}
That way you don't need to duplicate code.
That makes perfect sense, @therealshark ! I was trying to implement something similar but failed miserably, not much into classes haha
The thing is, though, this approach has limitations: you have to create on file for each language, for each template. Say I'm fetching an array of languages from an API and their respective content: how would I go about setting this up? One way is to manually create files, or to pre-fetch the languages and use fs to create these template files before running Eleventy... Regardless of how, it's not the nicest workflow, right?
Honestly, I'm a bit of a control freak and really want to get into the nitty gritty of how and when pages will be created, and that's why I'm putting Eleventy on hold for a while in favor of other options such as Metalsmith. Love the project, would love to use it, but it needs to work better on Windows (less bugs) and allow for controlling page creation. And be sure that I'll contribute if I find the time in the near future 馃槃
Thanks for the input, though, definitely helped o/
Related #620
I was all set to vote for this until I discovered how pagination can do this for me. SO slick.
layout: layouts/base.njk pagination: data: eventslist.events size: 1 alias: event permalink: events/{{ event.date }}/index.html --- <h1>{{ event.title }}</h1> <p>{{ event.date }}</p> ...鉂わ笍
But does it work for the large collection? I have 24k pages to generate. If I fetch whole data in a single call (in _data folder) then the response will be huge. it may fail.
I am looking for one by one web page generation. wondering how to do that in 11ty
Going to defer this one to #620鈥攁lthough this one was created earlier. #620 has a bit better discussion and example code 馃憤馃徎
Most helpful comment
I was all set to vote for this until I discovered how pagination can do this for me. SO slick.
鉂わ笍