Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Eleventy By Example

You're reading from   Eleventy By Example Create powerful, performant websites with a static-first strategy

Arrow left icon
Product type Paperback
Published in May 2023
Publisher Packt
ISBN-13 9781804610497
Length 198 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Bryan Robinson Bryan Robinson
Author Profile Icon Bryan Robinson
Bryan Robinson
Arrow right icon
View More author details
Toc

Table of Contents (13) Chapters Close

Preface 1. Chapter 1: Setting Up Your Website 2. Chapter 2: Adding Data to Your 11ty Website FREE CHAPTER 3. Chapter 3: Deploying to a Static Site Host 4. Chapter 4: Building a Blog with Collections 5. Chapter 5: Creating Custom Shortcodes to Add Mixed Media to Markdown 6. Chapter 6: Building a Photography Site with the 11ty Image Plugin 7. Chapter 7: Building a Podcast Website with 11ty Plugins and Custom Outputs 8. Chapter 8: Creating a Static-Site Search with 11ty Serverless and Algolia 9. Chapter 9: Integrating 11ty with a Headless CMS 10. Chapter 10: Creating Custom 11ty Plugins 11. Index 12. Other Books You May Enjoy

Using the RSS plugin

To start customizing our project, we need to install and use the RSS plugin. The information we’ll need from this plugin is the same as that we’d need to have a traditional RSS feed for a blog as well. To get started, we need to install and configure the plugin.

Installing the plugin

The RSS plugin is an official 11ty plugin and full documentation can be found on the 11ty documentation site. To install the plugin, we need to run an npm install command for the npm package:

npm install @11ty/eleventy-plugin-rss

This will save the plugin to our project and update our package.json file. Next, we need to add this to our 11ty configuration file. Just as in the previous projects, the configuration is in the .eleventy.js file at the root of the project.

To configure the plugin, we set a new variable at the top of the configuration file and then use the addPlugin method inside the exported function of the file:

const pluginRss = require("@11ty/eleventy-plugin-rss");
module.exports = function(eleventyConfig) {
    eleventyConfig.addPlugin(pluginRss);
    // Copy `assets/` to `_site/assets/`
    eleventyConfig.addPassthroughCopy("assets");
    // Set the source for 11ty to the /src directory
    // Otherwise, this defaults to the project root
    // This provides a cleaner project structure
    return {
        dir: {
            input: "src",
            output: "_site",
// This is the default, but it's included here for clarity.
            includes: "_templates"
        }
    }
}

Now that the plugin is installed, we can start using the filters to begin to solve the needs of our podcast feed.

Setting up a feed page

In our src directory, we need to create a new page dedicated to the RSS feed. The RSS plugin is created for use in the Nunjucks template engine. Even though the rest of our site is being rendered by Liquid, this specific template can be rendered with Nunjucks by giving it the proper file extension: feed.njk.

Let’s start by adding the very basics of an RSS feed to this file. This code starts by defining that this is an XML document and is using XML version 1.0 and RSS version 2.0 – the correct versions for acceptance in iTunes:

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <title>{{ site.name }}</title>
  <link href="{{ site.url }}{{ permalink }}" rel="self" />
  <link href="{{ site.url }}/" />
</rss>

After saving this, a new directory will appear in our _site directory and a new route will be available in the localhost. The problem with this is that instead of creating an XML file and route, 11ty has built a file whose content is XML but whose file extension is HTML. This will create issues with most podcast apps, and even Google Chrome displays it as a blank HTML page instead of as data from XML.

This is because 11ty treats everything by default as HTML. We can override this by changing the permalink setting by changing the property in the file’s frontmatter. This will change the file placement and extension to an XML document instead of HTML. After saving this file, you can open up localhost:8080/feed.xml and Chrome will now recognize this as a feed:

---
permalink: '/feed.xml'
---
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <title>{{ site.name }}</title>
  <link href="{{ site.url }}{{ permalink }}" rel="self" />
  <link href="{{ site.url }}/" />
</rss>

Once this new page is saved, we can navigate to http://localhost:8080/feed.xml and see the output directly:

Figure 7.1 – The very simple RSS output displayed in Chrome

Figure 7.1 – The very simple RSS output displayed in Chrome

Now that we have a properly formatted page, we can start adding all the information needed for the general information for the feed.

To start, we’ll add the general information found in the global site data with specific tags for both RSS and iTunes. We’ll add tags for the ID, language, author information, description, categories, and image. The main thing to note here is that the description needs to be inside a CDATA field to be valid XML:

---
permalink: '/feed.xml'
---
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <title>{{ site.name }}</title>
  <link href="{{ site.url }}{{ permalink }}" rel="self" />
  <link href="{{ site.url }}/" />
  <id>{{ site.url }}</id>
  <language>en-US</language>
  <itunes:author>{{ site.authorName }}</itunes:author>
  <description><![CDATA[{{ site.description }}]]>
    </description>
  <itunes:owner>
    <itunes:name>{{ site.authorName }}</itunes:name>
    <itunes:email>{{ site.authorEmail }}</itunes:email>
  </itunes:owner>
  <itunes:explicit>no</itunes:explicit>
  <itunes:type>episodic</itunes:type>
  {% for category in site.categories %}
    <itunes:category text="{{ category }}" />
  {% endfor %}
  {% if site.image %}
    <itunes:image href="{{ site.image }}" />
    <image>
      <title>{{ site.name }}</title>
      <link>{{ site.url }}</link>
      <url>{{ site.image }}</url>
    </image>
  {% endif %}
</rss>

The last piece of general information to provide the feed is the updated date. This is where two different filters from the RSS plugin are used.

We need to find the most recently added content item in our episodes collection. We can use the getNewestCollectionItemDate filter for that and then chain that filter with dateToRfc822 to format that date properly. Add the following line to the feed file:

  <updated>{{ collections.episodes |
    getNewestCollectionItemDate | dateToRfc822 }}</updated>

This will display the date in the updated element in the proper format:

<updated>Mon, 31 Dec 2018 19:00:00 +0000</updated>

Next, we need to loop through all the episodes in the collection and make a discrete RSS item for each. To do this, we need to get the absolute URL for each of the episodes from the relative path provided by 11ty. We do that with Nunjucks’ set tag, the post URL, and the RSS plugin’s absoluteUrl filter. We also have another instance of an updated date that will require the dateToRfc822 filter again:

  {% for post in collections.episodes %}
    {%- set absolutePostUrl = post.url | absoluteUrl
      (site.url) %}
    <item>
      <title>{{ post.data.title }}</title>
      <link href="{{ absolutePostUrl }}" />
      <updated>{{ post.date | dateToRfc822 }}</updated>
      <id>{{ absolutePostUrl }}</id>
    </item>
  {% endfor %}

We also need to provide the content from the Markdown file to the feed. This will allow for the transcription and description to be available in various podcast apps. To do this, we can use the templateContent variable on each post. If there are any URLs in that content, however, we also need to make those URLs absolute. The RSS plugin has that ready for us with the htmlToAbsoluteUrls filter to replace any relative URLs in our Markdown with their absolute versions. Nunjucks also needs to be told to render the Markdown as HTML and not as a string with escaped characters, so we pass that through the safe filter:

{% for post in collections.episodes %}
    {%- set absolutePostUrl = post.url | absoluteUrl
       (site.url) %}
    <item>
      <title>{{ post.data.title }}</title>
      <link href="{{ absolutePostUrl }}" />
      <updated>{{ post.date | dateToRfc822 }}</updated>
      <id>{{ absolutePostUrl }}</id>
      <content type="html">
        <![CDATA[
      {{ post.templateContent | htmlToAbsoluteUrls
        (absolutePostUrl) | safe  }}
    ]]>
      </content>
    </item>
  {% endfor %}

Finally, each item needs an enclosure element. The enclosure element provides the actual multimedia content information. This is where we need the Podcast Tools plugin to get the file size information for the feed.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image