Closed danurbanowicz closed 5 years ago
I'm doing essentially what you want using a custom collection. I'm doing it to group by months and by years. You could easily extend to group by day, etc.
My code below:
const moment = require("moment");
function generateDateSet(collection, format){
let dateSet = new Set();
collection.getAllSorted().forEach(function(item) {
if( "date" in item.data ) {
var tags = item.data.tags;
if( typeof tags === "string" ) {
tags = [tags];
}
if ( tags && ( tags.includes("_blog") || tags.includes("_photoblog") ) ){
let itemDate = item.data.date;
var date = moment(itemDate).format(format);
dateSet.add(date);
}
}
});
return Array.from(dateSet);
}
function getItemsByDate(collection, date, format){
var result = {};
result = collection.getAll().filter(function(item) {
var tags = item.data.tags;
if( typeof tags === "string" ) {
tags = [tags];
}
if ( tags && ( tags.includes("_blog") || tags.includes("_photoblog") ) ){
if( !item.data.date ){
return false;
}
var itemDate = item.data.date;
var itemShortDate = moment(itemDate).format(format);
return (itemShortDate == date);
};
return false;
});
result = result.sort(function(a, b) {
return b.date - a.date;
});
return result;
}
const contentByDateString = (collection, format) => {
var dateSet = {};
var newSet = new Set();
dateSet = generateDateSet(collection, format);
dateSet.forEach(function(date){
var result = getItemsByDate(collection, date, format)
newSet[date] = result;
});
return [{...newSet}];
}
exports.contentByMonth = collection => {
return contentByDateString(collection, "YYYY/MM");
}
exports.contentByYear = collection => {
return contentByDateString(collection, "YYYY");
}
Note, because of #277 I have to return the result wrapped in an array - so when you paginate on these collections you'll need to do something like:
pagination:
-data: collections.contentByMonth[0]
Thanks for this Ed, it's just given me an idea.
Is this okay to close? I do think you want a custom collection for this :+1:
@edwardhorsford I like your solution. How did you make your module exports available as a method on the collections
object?
@jvoros it's not quite method on the collections object.
I'm using eleventy's addCollection method like this:
eleventyConfig.addCollection("contentByMonth", require("./utils/collections/contentByDate").contentByMonth);
This creates a new collection using the function I posted above. I then use this collection to make pages / content.
See other solutions in #1284
I am happily using zero-maintenance tag pages but now I'm trying to additionally sort and paginate my posts (calendar events) based on an explicitly set date - and specifically by the month.
For example: I could just add
tags: april
to the post front matter, and it'd allow me to sort my posts by theapril
tag, but I was thinking it'd be better if Eleventy could just generate the tag from the post date filter I'm using. Something like:tags: {{ event.date | monthName }}
which would outputtags: april
..but alas, we can't use template syntax in front matter data for anything other than the permalink field.
So, how could I generate a tag or array of tags for a post based on post data, such as the date? Or is anyone using a different method to organise their collections by date? 🤔