Generate excerpt when no excerpt_separator present in content #4133
Replies: 5 comments
-
|
Here's a very rough LiquidJS based example for generating excerpts from the current page using a handful of probably Very Bad Ideas(tm): eleventyConfig.setFrontMatterParsingOptions({
excerpt: true,
excerpt_separator: "<!-- excerpt -->",
});
eleventyConfig.addFilter("excerptify", function (page, wordcount = 10) {
const {
liquid: { filters: f },
context: { environments: env },
} = this;
const formatExcerpt = (html = "") => f.strip_html(html).replace(/\s+/g, " ").trim();
let excerpt = page.excerpt;
if (excerpt) {
return formatExcerpt(excerpt);
}
const self = env.collections.all.find((p) => p.url === page.url);
const templateContent = self.template._dataCache.content || "";
excerpt = formatExcerpt(templateContent);
return f.truncatewords(excerpt, wordcount);
});USAGEsrc/_includes/layouts/base.liquid<meta description="{{ page | excerptify }}" />
...src/index.liquidHas an excerpt. Uses it, but strips the HTML (since I was imagining using it in meta description tags): ---
title: Page Index
layout: layouts/base.liquid
---
This is an excerpt. Huzzah!
<p>More of an excerpt, but its kinda neat</p>
<!-- excerpt -->
<h2>{{ title }}</h2>
THis is more content, but not part of an excerptOUTPUT<meta description="This is an excerpt. Huzzah! More of an excerpt, but its kinda neat" />src/one.liquidDoesn't have an excerpt ---
title: PAGE One
layout: layouts/base.liquid
---
# {{ title }}
Thjis is some content, but it's not very good.
but does it do the job? kinda.OUTPUT<meta description="PAGE One Thjis is some content, but it's not very..." />Using Eleventy v2. Didn't try in Nunjucks or older versions of Eleventy, so your mileage may vary. UPDATE: I got bored/curious, so here's an equally poor Nunjucks filter example. Main differences are just filter names and context juggling when using eleventyConfig.addFilter("excerptify_n", function (page, length = 20) {
const { env: { filters: f }, ctx } = this;
const formatExcerpt = (html = "") => f.striptags(html).replace(/\s+/g, " ").trim();
let excerpt = page.excerpt;
if (excerpt) {
return formatExcerpt(excerpt);
}
const self = ctx.collections.all.find((p) => p.url === page.url);
const templateContent = self.template._dataCache.content || "";
excerpt = formatExcerpt(templateContent);
return f.truncate(excerpt, length);
}); |
Beta Was this translation helpful? Give feedback.
-
Another unpopular idea would possibly be to use something like https://cheerio.js.org/ to scrape the PROS: You can control what level of HTML you want to generate an excerpt for. |
Beta Was this translation helpful? Give feedback.
-
|
I had this article in a draft state for too long, so here it is: How I built my own excerpt for Markdown content in Eleventy. Not really what you're looking for, but it might be interesting anyway. |
Beta Was this translation helpful? Give feedback.
-
|
I forgot that gray-matter's excerpt can take a function: const sanitizeHtml = require("sanitize-html");
eleventyConfig.setFrontMatterParsingOptions({
excerpt_separator: "<!-- excerpt -->",
excerpt_char_limit: 180,
excerpt(file, options) {
if (file.content.includes(options.excerpt_separator)) {
// Return the raw excerpt. This might include HTML. 🤷
file.excerpt = file.content
.slice(0, file.content.indexOf(options.excerpt_separator))
.trim();
return;
}
// No excerpt marker found, extract the first n characters after removing HTML tags.
file.excerpt = sanitizeHtml(file.content, { allowedTags:[] })
.replace(/\s+/g, " ")
.slice(0, options.excerpt_char_limit)
.trim();
},
});Although the big caveat with this is that gray-matter is one of the first things to run in the pipeline (so it can extract front-matter from page contents). So your excerpt might have unparsed Nunjucks/Liquid templating. May or may not be a concern depending on your use case. |
Beta Was this translation helpful? Give feedback.
-
Indeed, that's a limitation I've accepted in my own usage. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Is your feature request related to a problem? Please describe.
I'm trying to use excerpts to generate my site's meta description tags, but the current implementation only generates an excerpt when the separator is present in my markdown. It's null/undefined otherwise.
Some of my posts use the
<!-- excerpt -->separator, but most do not, and I expect I will forget to add it many times in the future.Describe the solution you'd like
I'd love for a way to generate excerpts for all pages, even when the separator isn't present. This could be done via character limit, word limit, or paragraph count — any of these would be better than the current behavior, IMO.
I'd like to be able to do something like this to configure it:
It might make sense to leave the current behavior as is, unless this new option is specified.
Describe alternatives you've considered
There's clearly a need here, as I found several blog posts — however most of these solutions were tailored towards collections, not individual pages, and it's taking some work for me to adapt their approaches:
I'm currently using
{{ content | striptags() | truncate(160) }}in myinclude'd template partial, but this uses the final rendered HTML, so it has extra content such as the post date and title that I render before the main body of my page. I'd like to keep that stuff out of my summary.Additional context
No response
Beta Was this translation helpful? Give feedback.
All reactions