Search code examples
eleventy

Eleventy - define start and end point for excerpt


I'm trying to find a way to selectively pick an excerpt somewhere within the content, i.e. able to define start and end of point of excerpt.

I have tried the Eleventy's docs method to parse excerpts from content. But this parses everything above the delimiter <!-- excerpt -->.

Select using {{ post.data.page.excerpt }}

---
pageTitle: blog
tags: posts
---
Everything here is parsed as the excerpt
<!-- excerpt -->
Lorem ipsum, dolor sit amet consectetur adipisicing elit.
...

An alternative approach I tried is to use a key in the front matter to specify separately an intro/excerpt, but this method doesn't let me use existing content.

{{ post.data.intro }}

---
pageTitle: blog
tags: posts
intro: This is an excerpt stored in a key
---
Lorem ipsum, dolor sit amet consectetur adipisicing elit.
...

Is there currently a way to specify a start and end separator for the excerpt to be taken from the content? For example:

---
pageTitle: blog
tags: posts
---
#Heading of the blog

Lorem ipsum, dolor sit amet consectetur adipisicing elit...

<!-- excerptStart -->
This part should be the excerpt of the post
<!-- excerptEnd -->
...

Any help would be appreciated!


Solution

  • After going through more research, I came across this blog that provided a workable solution.

    https://keepinguptodate.com/pages/2019/06/creating-blog-with-eleventy/ (Thanks to the original writer)

    In short, you can take full control of excerpt handling using "shortcode". Simply add this function in your eleventy.js file.

    module.exports = function (eleventyConfig) {
      eleventyConfig.addShortcode("excerpt", article => extractExcerpt(article));
    };
    
    function extractExcerpt(article) {
      if (!article.hasOwnProperty("templateContent")) {
        console.warn(
          'Failed to extract excerpt: Document has no property "templateContent".'
        );
        return null;
      }
    
      let excerpt = null;
      const content = article.templateContent;
    
      // The start and end separators to try and match to extract the excerpt
      const separatorsList = [
        { start: "<!-- Excerpt Start -->", end: "<!-- Excerpt End -->" },
        { start: "<p>", end: "</p>" },
      ];
    
      separatorsList.some(separators => {
        const startPosition = content.indexOf(separators.start);
        const endPosition = content.indexOf(separators.end);
    
        if (startPosition !== -1 && endPosition !== -1) {
          excerpt = content
            .substring(startPosition + separators.start.length, endPosition)
            .trim();
          return true; // Exit out of array loop on first match
        }
      });
    
      return excerpt;
    }
    

    Then you can add the <!-- Excerpt Start --> and <!-- Excerpt End --> in your markdown file/s to specify which part of the content you want to use as the excerpt.

    To use the excerpt shortcode, just add {% excerpt post %} to the homepage template.

    You can refer to the original blog linked above for detailed breakdown.

    I also tested a simple version of it without the bells and whistles. If you are interested to take a look, you can find it via: https://github.com/enrichdev-en/eleventy-excerpt-example.