Skip to main content

Podcaster

Hosting a podcast and creating its website with Eleventy.

Podcaster Blog

What’s new in version 2

Version 1.0.0 of Podcaster was released on 8 January 2025. Today, a year later, I’m happy to announce the release of Version 2.0.0.

New documentation

Perhaps the most important change in Version 2.0.0 is a new set of documentation. It’s simpler, I think, and more comprehensive. And there’s room to add new material when it’s needed.

And to support this new documentation, I’ve made some changes to how Podcaster works — changes that should make it easier to use, to understand, and to explain.

New features

Here are Podcaster’s most important new features:

  • The structure of a Podcaster project has been clarified. Your episode audio files go in the episode-files directory, and your episode post templates go in the episode-posts directory. The episode posts are available to your templates in collections.episodePost.
  • You don’t need to specify as much episode metadata in your episode posts’ front matter:
    • You can specify episode.seasonNumber, episode.episodeNumber and date in your episode post’s filename.
    • Podcaster can work out episode.size, episode.duration and episode.filename from the files in your episode-files directory or from the files in an S3-compatible bucket.
  • The options accepted by Podcaster when you add it to your Eleventy configuration have been simplified.

And here are some of the other changes:

  • .m4a episode files are explicitly supported.
  • The durations of episode files are calculated more quickly, using music-metadata instead of mp3-duration.
  • The three readable filters, readableDate, readableSize and readableDuration, have been given more sensible defaults and some useful options.
  • episode.duration can be supplied in h:mm:ss format instead of as a number of seconds.
  • Podcast chapters are supported.
  • Episode post permalinks can be customised.
  • Podcaster now respects quiet mode.

As always, if you have any questions or suggestions or if you encounter any problems, please contact me on Bluesky or on Mastodon, or on the Podcaster GitHub page.

Upgrading from Version 1 to Version 2

Version 2 breaks compatibility with Version 1. Here’s how to get your Version 1 project working on Version 2.

  1. Put your episode audio files in an episode-files directory in your project’s input directory. Don’t forget to add that directory to .gitignore.
  2. Put your episode post files in an episode-posts directory in your project’s input directory. If you have a directory data file for those posts, move that as well, and rename it to episode-posts plus the appropriate extension.
  3. Update the options passed to addPlugin in your configuration file. Here’s a description of the new options.

You might also want to rename references to collections.podcastEpisode to collections.episodePost, although the original name is still supported.

Storing episode metadata in filenames

Important

This blog post was written for Version 1 of Podcaster. The feature described here has been included in Version 2 — in fact it’s now the default. You can find out more about it here.

Each podcast episode in Podcaster is represented by a template with the tag podcastEpisode. On my podcast websites, I put all the podcast episode templates in a /src/posts directory, and I give each template the podcastEpisode tag by using a directory data file.

So my /src/posts directory looks like this:

# /src/posts

.
├── 2021-11-04-ep1-yesterdays-enterprise.md
├── 2021-11-12-ep2-the-house-of-quark.md
├── 2021-11-19-ep3-lineage.md
├── 2021-11-26-ep4-forget-me-not.md
├── 2021-12-03-ep5-the-corbomite-maneuver.md
└── posts.11tydata.js

And the directory data file looks like this:

// posts.11tydata.js

export default {
  'tags': ['podcastEpisode']
}

The value exported from the directory data file gets added to the data cascade for all the templates in that directory.

But are there any other properties that we can calculate in the directory data file?

Eleventy will already calculate a post’s date from the dates at the start of the filename. I include that date so that posts are listed in chronological order, but it also means that I don’t have to specify the post date in the template’s front matter.

I include the episode number in the filename as well. Can I use the directory data file to calculate the episode number from the filename too?

Turns out, I can. Here’s an updated directory data file.

// posts.11tydata.js

export default {
  tags: ['podcastEpisode'],
  eleventyComputed: {
    'episode.episodeNumber' (data) {
      if (data.episode?.episodeNumber) {
        return data.episode?.episodeNumber
      }
      const matchResult = data.page.fileSlug.match(/^ep(\d+)/)
      if (matchResult) {
        return parseInt(matchResult[1])
      }
    }
  }
}

eleventyComputed lets you calculate data values based on values that have been already calculated. Here we’re getting the page’s fileSlug, which is just the filename with the date at the beginning removed. We search for the letters ep at the start of the fileSlug, we get the number that appears after that, and then we return it as episode.episodeNumber, which is where Podcaster wants to find it.

What about podcasts with seasons? Here’s a file listing from the 500 Year Diary podcast website.

# /src/posts

.
├── 2024-04-14-s1e1-the-power-of-the-daleks.md
├── 2024-04-21-s1e2-spearhead-from-space.md
├── 2024-04-28-s1e3-terror-of-the-autons.md
├── 2024-05-05-s1e4-the-christmas-invasion.md
├── 2024-05-12-s1e5-torchwood-everything-changes.md
└── 2024-05-19-s1e6-sja-invasion-of-the-bane.md

And here’s the directory data file that calculates both episode.episodeNumber and episode.seasonNumber from the post’s filename.

export default {
  tags: ['podcastEpisode'],
  eleventyComputed: {
    'episode.episodeNumber' (data) {
      if (data.episode?.episodeNumber) {
        return data.episode?.episodeNumber
      }
      const matchResult = data.page.fileSlug.match(/^s(?:\d+)e(\d+)/)
      if (matchResult) {
        return parseInt(matchResult[1])
      }
    },
    'episode.seasonNumber' (data) {
      if (data.episode?.seasonNumber) {
        return data.episode?.seasonNumber
      }
      const matchResult = data.page.fileSlug.match(/^s(\d+)/)
      if (matchResult) {
        return parseInt(matchResult[1])
      }
    }
  }
}

The episode data documentation makes it seem like you need to provide a lot of information in the front matter of your podcast episode templates. But using the technique I just described, as well as Podcaster’s automatic calculation of episode size and duration and the defaults Podcaster provides, you can get the front matter data down to nearly nothing. Here’s an example from 500 Year Diary, with no Podcaster-specific front matter at all.

---
title: Where Kelsey Went
recordingDate: 2024-04-19
topic: "The Sarah Jane Adventures: Invasion of the Bane"
diaryDate: 2007-01-01
---

Presenting an episode on your site

In my first post a few weeks ago, I showed you a simple way to create a home page for your podcast — by creating a template which loops through the podcastEpisode collection and renders some HTML containing the information for each episode.

Today, I’m going to show you an include file which presents more extensive detail about an episode. This include file can be used by itself on the episode’s dedicated page, but it can also be used as part of a list of episodes — like an index page or a tag page, for example.

An include file like this is sometimes called a partial.

Continue reading…

Describing a podcast episode

Podcasts are an audio medium, of course, but your listeners’ podcast players describe each of your episodes using text — a title, a short description and a long description.

And so Podcaster lets you provide all three of those.

I’ve posted about titles already — so let’s talk about the short and long descriptions.

Continue reading…

Creating a home page

You can put whatever you want on your podcast site’s home page, but the most obvious and straightforward approach might be to present a list of episodes in reverse chronological order.

Here’s how to do that.

Continue reading…