If you've built sites using Eleventy before, you're probably familiar with collections. Collections are a great feature to show blog posts on your site. If your posts are written inside of markdown files, you can give each post the tags
key as front matter data to create a collection.
Front matter in 11ty is placed inside opening and closing document separators ---
and uses YAML syntax. Two markdown files post-one.md
and post-two.md
will be the blog posts contained in the posts
collection.
---
title: Blog post one
permalink: "/posts/{{ title | slug }}"
tags: posts
---
Some content in post one
---
title: Blog post two
permalink: "/posts/{{ title | slug }}"
tags: posts
---
Some content in post two
You might have noticed a permalink
key in the front matter data. Eleventy's permalink does some cool stuff to make sure that "Cool URIs don't change". You can use the permalink
key to remap a templates output to a path other than the default inputPath
. The output from setting a permalink
will leave off the file extension.
The two markdown files would be written to the _site
output as:
/posts/blog-post-one/
/posts/blog-post-two/
Using the slug
filter works nicely to slugify your posts title
key. The above permalink could also be written as permalink: "/posts/blog-post-two/"
if you wanted to manually write the equivalent of {{ title | slug }}
.
Accessing Collection Data
Now that both of the blog posts have been given the posts
tag. They can be easily accessed from the posts
collection in the following way using a Nunjucks for
loop.
{% for post in collections.posts %}
<a href="{{ page.url }}">{{ post.data.title }}</a>
{% endfor %}
This would iterate over the posts
collection and access the front matter data title
to create a link to each blog post.
<a href="/posts/blog-post-one/">Blog post one</a>
<a href="/posts/blog-post-two/">Blog post two</a>
If you wanted to show the markdown from blog posts in another template or layout file, you can use {{ content | safe }}
.
Handling multiple tags
One way to create a new collection is simply by giving a .md
file a new tag within the tags
key. This method has been demonstrated above to access the posts
collection.
When you have multiple tags on a blog post, such as html
, css
, js
. You will add each tag to the tags
key as a list of values.
---
tags:
- html
- css
- js
---
This is where creating a custom collection comes in handy. Instead of including the posts
tag in the tags
list for every blog post (which might be repetitive), just create a custom collection with the markdown files from /posts/
inside the .eleventy.js
file. This way you can omit posts
from the tags list within front matter data.
Create Custom Collections
All blog posts in this article are saved as .md
files in the /posts/
directory. To create a custom collection, navigate to .eleventy.js
. You will utilize the first argument of the config function eleventyConfig
to call the API and use addCollection
to create a new custom collection.
You can add the markdown files within /posts/
to the new collection using getFilteredByGlob(glob)
, which will match an arbitrary glob or array of globs against the input file's full path (inputPath
).
module.exports = function(eleventyConfig) {
// Creates custom collection "myPosts"
eleventyConfig.addCollection("myPosts", function(collection) {
return collection.getFilteredByGlob("/posts/*.md");
});
}
Now a custom collection called myPosts
has been created which contains all the markdown files in /posts/
. You can access this custom collection just like a regular collection.
{% for article in collections.myPosts %}
<h2>{{ article.data.title }}</h2>
{% endfor %}
Another useful method is getFilteredByTags(tags)
which will retrieve any content that includes all of the tags passed in.
eleventyConfig.addCollection("web", function(collection) {
return collection.getFilteredByTags("html", "css", "js");
});
Filter Recent Posts
If you wanted to dedicate a section of the page for some of your most recent blog posts. You could create a custom sorted collection and perform a slice
array operation to filter the number of recent posts.
eleventyConfig.addCollection("recentPosts", function(collection) {
return collection.getAllSorted().reverse().slice(0, 3);
});
Conclusion
Custom collections along with the ability to build powerful shortcodes and filters in .eleventy.js
using the configuration API is one of the main reasons why #eleventy rocks!