mirror of
https://github.com/svemagie/blog-eleventy-indiekit.git
synced 2026-04-02 08:44:56 +02:00
feat: add weeklyDigests collection for digest feature
- Added weeklyDigests collection after recentPosts collection - Groups published posts (excluding replies) by ISO 8601 week - Supports both camelCase and underscore property names - Includes byType grouping (articles, notes, photos, etc.) - Calculates week start/end dates for display - Excludes interactive directory from builds via .eleventyignore
This commit is contained in:
2
.eleventyignore
Normal file
2
.eleventyignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
interactive
|
||||||
@@ -767,6 +767,92 @@ export default function (eleventyConfig) {
|
|||||||
.slice(0, 5);
|
.slice(0, 5);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Weekly digests — posts grouped by ISO week for digest pages and RSS feed
|
||||||
|
eleventyConfig.addCollection("weeklyDigests", function (collectionApi) {
|
||||||
|
const allPosts = collectionApi
|
||||||
|
.getFilteredByGlob("content/**/*.md")
|
||||||
|
.filter(isPublished)
|
||||||
|
.filter((item) => {
|
||||||
|
// Exclude replies
|
||||||
|
return !(item.data.inReplyTo || item.data.in_reply_to);
|
||||||
|
})
|
||||||
|
.sort((a, b) => b.date - a.date);
|
||||||
|
|
||||||
|
// ISO week helpers
|
||||||
|
const getISOWeek = (date) => {
|
||||||
|
const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
|
||||||
|
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
|
||||||
|
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
|
||||||
|
return Math.ceil(((d - yearStart) / 86400000 + 1) / 7);
|
||||||
|
};
|
||||||
|
const getISOYear = (date) => {
|
||||||
|
const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
|
||||||
|
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
|
||||||
|
return d.getUTCFullYear();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Group by ISO week
|
||||||
|
const weekMap = new Map();
|
||||||
|
|
||||||
|
for (const post of allPosts) {
|
||||||
|
const d = new Date(post.date);
|
||||||
|
const week = getISOWeek(d);
|
||||||
|
const year = getISOYear(d);
|
||||||
|
const key = `${year}-W${String(week).padStart(2, "0")}`;
|
||||||
|
|
||||||
|
if (!weekMap.has(key)) {
|
||||||
|
// Calculate Monday (start) and Sunday (end) of ISO week
|
||||||
|
const jan4 = new Date(Date.UTC(year, 0, 4));
|
||||||
|
const dayOfWeek = jan4.getUTCDay() || 7;
|
||||||
|
const monday = new Date(jan4);
|
||||||
|
monday.setUTCDate(jan4.getUTCDate() - dayOfWeek + 1 + (week - 1) * 7);
|
||||||
|
const sunday = new Date(monday);
|
||||||
|
sunday.setUTCDate(monday.getUTCDate() + 6);
|
||||||
|
|
||||||
|
weekMap.set(key, {
|
||||||
|
year,
|
||||||
|
week,
|
||||||
|
slug: `${year}/W${String(week).padStart(2, "0")}`,
|
||||||
|
label: `Week ${week}, ${year}`,
|
||||||
|
startDate: monday.toISOString().slice(0, 10),
|
||||||
|
endDate: sunday.toISOString().slice(0, 10),
|
||||||
|
posts: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
weekMap.get(key).posts.push(post);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post type detection (matches blog.njk logic)
|
||||||
|
const typeDetect = (post) => {
|
||||||
|
if (post.data.likeOf || post.data.like_of) return "likes";
|
||||||
|
if (post.data.bookmarkOf || post.data.bookmark_of) return "bookmarks";
|
||||||
|
if (post.data.repostOf || post.data.repost_of) return "reposts";
|
||||||
|
if (post.data.photo && post.data.photo.length) return "photos";
|
||||||
|
if (post.data.title) return "articles";
|
||||||
|
return "notes";
|
||||||
|
};
|
||||||
|
|
||||||
|
// Build byType for each week and convert to array
|
||||||
|
const digests = [...weekMap.values()].map((entry) => {
|
||||||
|
const byType = {};
|
||||||
|
for (const post of entry.posts) {
|
||||||
|
const type = typeDetect(post);
|
||||||
|
if (!byType[type]) byType[type] = [];
|
||||||
|
byType[type].push(post);
|
||||||
|
}
|
||||||
|
return { ...entry, byType };
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sort newest-week-first
|
||||||
|
digests.sort((a, b) => {
|
||||||
|
if (a.year !== b.year) return b.year - a.year;
|
||||||
|
return b.week - a.week;
|
||||||
|
});
|
||||||
|
|
||||||
|
return digests;
|
||||||
|
});
|
||||||
|
|
||||||
// Generate OpenGraph images for posts without photos
|
// Generate OpenGraph images for posts without photos
|
||||||
// Runs on every build (including watcher rebuilds) — manifest caching makes it fast
|
// Runs on every build (including watcher rebuilds) — manifest caching makes it fast
|
||||||
// for incremental: only new posts without an OG image get generated (~200ms each)
|
// for incremental: only new posts without an OG image get generated (~200ms each)
|
||||||
|
|||||||
Reference in New Issue
Block a user