Skip to content

Commit 74bc574

Browse files
committed
feat: enhance next_chapter shortcode to resolve current post from collections and improve error handling
1 parent 5674db3 commit 74bc574

1 file changed

Lines changed: 28 additions & 19 deletions

File tree

eleventy.config.js

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -88,26 +88,35 @@ export default function(eleventyConfig) {
8888
});
8989

9090
eleventyConfig.addShortcode("next_chapter", function() {
91-
// Determine current post slug
92-
const currentSlug = this.page.fileSlug;
93-
const currentIndex = flatSlugs.indexOf(currentSlug);
94-
if (currentIndex !== -1 && currentIndex < flatSlugs.length - 1) {
95-
const nextSlug = flatSlugs[currentIndex + 1];
96-
// We can't access `collections.posts` easily in a shortcode without passing arguments,
97-
// but we know the title if we look it up, OR we can just use the shortcode to generate a markdown string.
98-
// However, to get the actual post title, shortcodes do not have access to collections natively unless bound.
99-
// Wait, a Nunjucks specific shortcode might have context, but an easier way is a Nunjucks global or filter.
100-
// Wait, we can pass `collections.posts` to the shortcode, but that means doing `{% next_chapter collections.posts %}`.
101-
// It's cleaner to provide the title. Let's read the markdown file for the nextSlug.
102-
const nextPath = path.join(process.cwd(), "src", "posts", `${nextSlug}.md`);
103-
if (fs.existsSync(nextPath)) {
104-
const content = fs.readFileSync(nextPath, "utf-8");
105-
const titleMatch = content.match(/title:\s*"?([^"\n]+)"?/);
106-
const nextTitle = titleMatch ? titleMatch[1].trim() : nextSlug;
107-
return `Next we'll look at **[${nextTitle}](/posts/${nextSlug}/)**!`;
108-
}
91+
const posts = this?.ctx?.collections?.posts || [];
92+
const currentUrl = this?.page?.url;
93+
const currentSlug = this?.page?.fileSlug;
94+
const isDev = process.env.ELEVENTY_RUN_MODE === "serve" || process.env.NODE_ENV === "development";
95+
96+
const currentIndex = posts.findIndex((post) => {
97+
return post.url === currentUrl || post.fileSlug === currentSlug;
98+
});
99+
100+
if (currentIndex === -1) {
101+
if (isDev) {
102+
throw new Error(`[next_chapter shortcode] Could not resolve current post in collections.posts (url: '${currentUrl}', slug: '${currentSlug}')`);
103+
}
104+
return "";
105+
}
106+
107+
if (currentIndex >= posts.length - 1) {
108+
return "";
109109
}
110-
return "";
110+
111+
const nextPost = posts[currentIndex + 1];
112+
const nextTitle = (nextPost?.data?.title || nextPost?.fileSlug || "").trim();
113+
const nextUrl = nextPost?.url || "";
114+
115+
if (!nextTitle || !nextUrl) {
116+
return "";
117+
}
118+
119+
return `Next we'll look at **[${nextTitle}](${nextUrl})**!`;
111120
});
112121

113122
return {

0 commit comments

Comments
 (0)