eleventy-plugin-podcaster 0.9.4 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,22 +15,22 @@ And then include the plugin in your Eleventy configuration file.
15
15
  ```js
16
16
  // eleventy.config.js
17
17
 
18
- import podcaster from 'eleventy-plugin-podcaster'
18
+ import Podcaster from 'eleventy-plugin-podcaster'
19
19
 
20
20
  export default function (eleventyConfig) {
21
21
  .
22
22
  .
23
- eleventyConfig.addPlugin(podcaster)
23
+ eleventyConfig.addPlugin(Podcaster)
24
24
  .
25
25
  .
26
26
  }
27
27
  ```
28
28
 
29
- ## ➡ [Documentation and usage][docs]
29
+ ## ➡ [Documentation and usage][Podcaster]
30
30
 
31
- On GitHub, you can find [detailed documentation][docs] about how to provide **Podcaster** with the information it needs to create your podcast feed and about how to use that information when creating the templates for your Eleventy site.
31
+ On [the `eleventy-plugin-podcaster` website][Podcaster], you can find detailed documentation about how to provide **Podcaster** with the information it needs to create your podcast feed and about how to use that information when creating the templates for your Eleventy site.
32
32
 
33
- [docs]: https://github.com/nathan-bottomley/eleventy-plugin-podcaster/tree/main/docs
33
+ [Podcaster]: https://eleventy-plugin-podcaster.com/docs
34
34
 
35
35
  As well as creating your feed and providing information to your templates, **Podcaster** can optionally calculate the size and duration of your podcast MP3 files, as well as offering functionality for drafts and excerpts.
36
36
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eleventy-plugin-podcaster",
3
- "version": "0.9.4",
3
+ "version": "0.10.0",
4
4
  "description": "An Eleventy plugin that allows you to create a podcast and its accompanying website",
5
5
  "main": "eleventy.config.js",
6
6
  "exports": {
package/src/drafts.js CHANGED
@@ -4,9 +4,9 @@ export default (eleventyConfig, options = {}) => {
4
4
  let hasLoggedAboutDrafts = false
5
5
  eleventyConfig.addPreprocessor('drafts', 'md', (data, _content) => {
6
6
  let shouldIncludeDrafts = false
7
- if (process.env.BUILD_DRAFTS === 'true') {
7
+ if (process.env.INCLUDE_DRAFTS === 'true') {
8
8
  shouldIncludeDrafts = true
9
- } else if (process.env.BUILD_DRAFTS === 'false') {
9
+ } else if (process.env.INCLUDE_DRAFTS === 'false') {
10
10
  shouldIncludeDrafts = false
11
11
  } else {
12
12
  shouldIncludeDrafts = (process.env.ELEVENTY_RUN_MODE !== 'build')
@@ -1,5 +1,6 @@
1
1
  ---
2
- permalink: "{{ podcast.feedPath or '/feed/podcast.xml' }}"
2
+ eleventyComputed:
3
+ permalink: "{{ podcast.feedPath }}"
3
4
  eleventyAllowMissingExtension: true
4
5
  ---
5
6
  {%- set siteUrl %}{{ podcast.siteUrl or site.url }}{% endset -%}
@@ -8,20 +9,17 @@ eleventyAllowMissingExtension: true
8
9
  xmlns:atom="http://www.w3.org/2005/Atom"
9
10
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
10
11
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
11
- >
12
+ xmlns:podcast="https://podcastindex.org/namespace/1.0">
12
13
  <channel>
13
14
  <title>{{ podcast.title }}</title>
14
- <itunes:subtitle>{{ podcast.subtitle or podcast.description }}</itunes:subtitle>
15
- <description>{{ podcast.description }}</description>
16
15
  <link>{{ siteUrl }}</link>
17
- <atom:link href="{{ podcast.feedPath | htmlBaseUrl(siteUrl) }}" rel="self" type="application/rss+xml" />
18
- {%- if podcast.owner %}
19
- <itunes:owner>
20
- <itunes:name>{{ podcast.owner.name }}</itunes:name>
21
- <itunes:email>{{ podcast.owner.email }}</itunes:email>
22
- </itunes:owner>
23
- {%- endif %}
24
- <itunes:author>{{ podcast.author }}</itunes:author>
16
+ <atom:link href="{{ permalink | htmlBaseUrl(siteUrl) }}" rel="self" type="application/rss+xml" />
17
+ <description>{{ podcast.description }}</description>
18
+ <language>{{ podcast.language }}</language>
19
+ <copyright>{{ podcast.copyrightNotice }}</copyright>
20
+ <pubDate>{{ collections.podcastEpisode | getNewestCollectionItemDate | dateToRfc3339 }}</pubDate>
21
+ <lastBuildDate>{{ podcast.feedLastBuildDate }}</lastBuildDate>
22
+ <itunes:image href="{{ podcast.imagePath | htmlBaseUrl(siteUrl) }}"></itunes:image>
25
23
  {%- if podcast.subcategory %}
26
24
  <itunes:category text="{{ podcast.category }}">
27
25
  <itunes:category text="{{ podcast.subcategory }}" />
@@ -29,67 +27,75 @@ eleventyAllowMissingExtension: true
29
27
  {%- else %}
30
28
  <itunes:category text="{{ podcast.category }}" />
31
29
  {%- endif %}
32
- <itunes:image href="{{ podcast.imagePath | htmlBaseUrl(siteUrl) }}"></itunes:image>
33
- <itunes:summary>{{ podcast.summary or podcast.description }}</itunes:summary>
34
- {% if podcast.explicit !== undefined %}<itunes:explicit>{{ podcast.explicit or "false" }}</itunes:explicit>{% endif -%}
30
+ {% if podcast.explicit !== undefined %}
31
+ <itunes:explicit>{{ podcast.explicit }}</itunes:explicit>
32
+ {% endif -%}
33
+ <itunes:author>{{ podcast.author }}</itunes:author>
35
34
  {%- if podcast.type %}
36
35
  <itunes:type>{{ podcast.type }}</itunes:type>
37
36
  {%- endif %}
38
37
  {%- if podcast.complete %}
39
38
  <itunes:complete>yes</itunes:complete>
40
39
  {%- endif %}
41
- <language>{{ podcast.language }}</language>
42
- <copyright>{{ podcast.copyrightNotice }}</copyright>
43
- <pubDate>{{ collections.podcastEpisode | getNewestCollectionItemDate | dateToRfc3339 }}</pubDate>
44
- <lastBuildDate>{{ podcast.feedLastBuildDate }}</lastBuildDate>
45
- <generator>{{ eleventy.generator }}</generator>
40
+ {%- if podcast.block %}
41
+ <itunes:block>yes</itunes:block>
42
+ {%- endif %}
43
+ {%- if podcast.owner %}
44
+ <itunes:owner>
45
+ <itunes:name>{{ podcast.owner.name }}</itunes:name>
46
+ <itunes:email>{{ podcast.owner.email }}</itunes:email>
47
+ </itunes:owner>
48
+ {%- endif %}
49
+
46
50
  {% for post in collections.podcastEpisode | reverse %}
47
51
  <item>
48
- <title>{{ post.data.title }}</title>
52
+ <title>{{ post.data.episode.title or post.data.title }}</title>
49
53
  <link>{{ post.url | htmlBaseUrl(siteUrl) }}</link>
50
- <pubDate>{{ post.date | dateToRfc3339 }}</pubDate>
51
- {% if post.data.episode.seasonNumber -%}
52
- <itunes:season>{{ post.data.episode.seasonNumber }}</itunes:season>
53
- {%- endif %}
54
- <itunes:episode>{{ post.data.episode.episodeNumber }}</itunes:episode>
55
- {% if podcast.feedEpisodeSummaryTemplate %}
56
- {%- set episodeSummary -%}
57
- {% include podcast.feedEpisodeSummaryTemplate %}
58
- {%- endset -%}
54
+ {%- if post.data.guid != undefined %}
55
+ <guid isPermalink="false">{{ post.data.guid }}</guid>
59
56
  {% else %}
60
- {%- set episodeSummary = post.content | striptags(true) | truncate(500) -%}
61
- {%- endif %}
62
- <itunes:summary>{{ episodeSummary }}</itunes:summary>
63
- {% if podcast.feedEpisodeDescriptionTemplate %}
57
+ <guid isPermalink="true">{{ post.url | htmlBaseUrl(siteUrl) }}</guid>
58
+ {% endif -%}
59
+ <pubDate>{{ post.date | dateToRfc3339 }}</pubDate>
60
+ {% if podcast.episodeDescriptionTemplate %}
64
61
  {%- set episodeDescription -%}
65
- {% include podcast.feedEpisodeDescriptionTemplate %}
62
+ {% include podcast.episodeDescriptionTemplate %}
66
63
  {%- endset -%}
64
+ {% elif post.data.episode.description %}
65
+ {%- set episodeDescription = post.data.episode.description -%}
67
66
  {% else %}
68
67
  {%- set episodeDescription = post.content | striptags(true) | truncate(800) -%}
69
68
  {%- endif %}
70
- <description>{{ episodeDescription }}</description>
71
- {% if podcast.feedEpisodeContentTemplate %}
69
+ <description>{{ episodeDescription | trim }}</description>
70
+ <itunes:summary>{{ episodeDescription | trim }}</itunes:summary>
71
+ {% if podcast.episodeContentTemplate %}
72
72
  {%- set episodeContent -%}
73
- {% include podcast.feedEpisodeContentTemplate %}
73
+ {% include podcast.episodeContentTemplate %}
74
74
  {%- endset -%}
75
75
  {% else %}
76
76
  {%- set episodeContent = post.content -%}
77
77
  {% endif %}
78
- <content:encoded>
79
- <![CDATA[{{ episodeContent | renderTransforms(post.data.page, siteUrl) | safe | trim }}]]>
80
- </content:encoded>
78
+ <content:encoded><![CDATA[{{ episodeContent | renderTransforms(post.data.page, siteUrl) | safe | trim }}]]></content:encoded>
81
79
  <enclosure url="{{ post.data.episode.url }}" length="{{ post.data.episode.size }}" type="audio/mp3"></enclosure>
82
80
  <itunes:duration>{{ post.data.episode.duration | readableDuration }}</itunes:duration>
83
- {%- if post.data.guid != undefined %}
84
- <guid isPermalink="false">{{ post.data.guid }}</guid>
85
- {% else %}
86
- <guid isPermalink="true">{{ post.url | htmlBaseUrl(siteUrl) }}</guid>
81
+ <itunes:episode>{{ post.data.episode.episodeNumber }}</itunes:episode>
82
+ {% if post.data.episode.seasonNumber -%}
83
+ <itunes:season>{{ post.data.episode.seasonNumber }}</itunes:season>
84
+ {%- endif %}
85
+ {%- if post.data.episode.image %}
86
+ <itunes:image href="{{ post.data.episode.image | htmlBaseUrl(siteUrl) }}"></itunes:image>
87
+ {% endif -%}
88
+ {%- if post.data.episode.explicit != undefined %}
89
+ <itunes:explicit>{{ post.data.episode.explicit }}</itunes:explicit>
87
90
  {% endif -%}
88
- {%- if post.data.explicit != undefined %}
89
- <itunes:explicit>{{ post.data.explicit }}</itunes:explicit>
91
+ {%- if post.data.episode.type %}
92
+ <itunes:episodeType>{{ post.data.episode.type }}</itunes:episodeType>
90
93
  {% endif -%}
91
- {%- if post.data.type != undefined %}
92
- <itunes:episodeType>{{ post.data.episodeType }}</itunes:episodeType>
94
+ {%- if post.data.episode.transcript %}
95
+ <podcast:transcript url="{{ post.data.episode.transcript | htmlBaseUrl(siteUrl) }}"></podcast:transcript>
96
+ {%- endif %}
97
+ {%- if post.data.episode.block === true %}
98
+ <itunes:block>Yes</itunes:block>
93
99
  {% endif -%}
94
100
  </item>
95
101
  {% endfor -%}
package/docs/README.md DELETED
@@ -1,179 +0,0 @@
1
- # eleventy-plugin-podcaster 🕚⚡️🎈🐀🎤📲
2
-
3
- `eleventy-plugin-podcaster` — or **Podcaster**, as we will call it from now on — lets you use Eleventy to create a podcast and its accompanying website. **Podcaster** creates the podcast feed that you submit to Apple Podcasts, Spotify or any other podcast directory. And it provides information about your podcast to your Eleventy templates. This means that you can include information about the podcast and its episodes on your podcast's website, creating pages for individual episodes, guests, topics, seasons or anything else at all.
4
-
5
- Plenty of services exist that will host your podcast online — [Spotify][], [Acast][], [Podbean][], [Buzzsprout][], [Blubrry][]. But none of these will allow you to own your podcast's presence on the web, and none of them will give you the freedom to create a site that presents your podcast in a way that reflects its premise, tone and style.
6
-
7
- But **Podcaster** will.
8
-
9
- [Spotify]: https://podcasters.spotify.com
10
- [Acast]: https://www.acast.com
11
- [Podbean]: https://www.podbean.com
12
- [Buzzsprout]: https://www.buzzsprout.com
13
- [Blubrry]: https://blubrry.com
14
-
15
- ## Installation
16
-
17
- To install the npm package, type this at the command line:
18
-
19
- ```shell
20
- npm install eleventy-plugin-podcaster
21
- ```
22
-
23
- And then include the plugin in your Eleventy configuration file.
24
-
25
- ```js
26
- // eleventy.config.js
27
-
28
- import podcaster from 'eleventy-plugin-podcaster'
29
-
30
- export default function (eleventyConfig) {
31
- .
32
- .
33
- eleventyConfig.addPlugin(podcaster)
34
- .
35
- .
36
- }
37
- ```
38
-
39
- ## Podcast information
40
-
41
- Once you've installed **Podcaster** in your Eleventy project, the next step is to provide it with information about your podcast — the title, the owner, the category, the subcategory and so on. The easiest way to do this is to put all the information in your data directory in a `podcast.json` file.
42
-
43
- Here's an example.
44
-
45
- ```json
46
- {
47
- "title": "Flight Through Entirety: A Doctor Who Podcast",
48
- "description": "Flying through the entirety of Doctor Who. Originally with cake, but now with guests.",
49
- "siteUrl": "https://flightthroughentirety.com",
50
- "author": "Flight Through Entirety",
51
- "category": "TV & Film",
52
- "language": "en-AU",
53
- }
54
- ```
55
-
56
- [Read more about podcast information.](podcast-information.md)
57
-
58
- ## Episode information
59
-
60
- For each podcast episode you create, you will also create a Eleventy template containing the information about it — the title, the release date, the episode number, the filename and so on. This template will have the tag `podcastEpisode`; its front matter will contain all of the information about the episode — title, release date, episode number and so on — and its content will contain the episode's show notes.
61
-
62
- Here's an example.
63
-
64
- ```yaml
65
- ---
66
- title: Entering a new Phase
67
- date: 2024-04-14
68
- tags:
69
- - podcastEpisode
70
- episode:
71
- filename: 500YD S1E1, Entering a New Phase.mp3
72
- seasonNumber: 1
73
- episodeNumber: 1
74
- size: 61231442 # bytes
75
- duration: 3778.482 # seconds
76
- ---
77
- A big week for beginnings this week, with a new Doctor, a new origin story for the Daleks, and a whole new approach to defeating the bad guys. Oh, and a new podcast to discuss them all on. So let's welcome Patrick Troughton to the studio floor, as we discuss _The Power of the Daleks_.
78
-
79
- ```
80
-
81
- [Read more about episode information.](episode-information.md)
82
-
83
- ## The podcast feed
84
-
85
- To create your podcast feed, **Podcaster** needs both the information you've provided about your podcast and the information you've provided about your individual episodes.
86
-
87
- By default, your podcast feed will be located at `/feed/podcast.xml`, which means that the URL you submit to Apple Podcasts or Spotify (or wherever) will be `{{ podcast.siteUrl }}/feed/podcast.xml`
88
-
89
- ## Using podcast information and episode information in templates
90
-
91
- All the podcast and episode information you provide are made available to your templates through the data cascade, including `title` and `date`, as well as fields in the `podcast` and `episode` objects.
92
-
93
- Here's how you could use this information to describe a single podcast episode in a Liquid template.
94
-
95
- ```liquid
96
- <article>
97
- <h1>{{ title }}</h1>
98
- <p class="episode-number">Episode {{ episode.episodeNumber }}</p>
99
- <p class="release-date">{{ date | date: "%A %-e %B %Y" }}</p>
100
- <section class="content">
101
- {{ content }}
102
- </section>
103
- <audio controls src="{{ episode.url }}" preload="none">
104
- <p class="audio-details">
105
- Episode {{ episode.episodeNumber }}: {{ title }}
106
- | Recorded on {{ recordingDate | date: "%A %-e %B %Y" }}
107
- | {{ episode.size | readableSize }}
108
- | Duration {{ episode.duration | readableDuration }}
109
- | <a download href="{{ episode.url }}">Download</a>
110
- </p>
111
- </article>
112
- ```
113
-
114
- All podcast episode templates belong to the `collections.podcastEpisode` collection, which means you can list several episodes on a single page using [Eleventy's pagination feature][pagination]. In that case, each episode's information will be available in its [collection item data structure][item].
115
-
116
- [pagination]: https://www.11ty.dev/docs/pagination/
117
- [item]: https://www.11ty.dev/docs/collections/#collection-item-data-structure
118
-
119
- > [!TIP]
120
- > `episode.size` gives you the podcast's size in bytes and `episode.duration`
121
- > gives you the duration in seconds. To include size and duration
122
- > in your templates in a human-readable format, use **Podcaster**’s filters
123
- > `readableSize` and `readableDuration`.
124
-
125
- ## Hosting
126
-
127
- You can host your podcast site — along with its feed — [the same way you would host any Eleventy site][hosting], using [a Jamstack provider][] linked to your source control repository or using [a classic web host][] which will allow you to upload the contents of your output directory.
128
-
129
- [hosting]: https://www.11ty.dev/docs/deployment/
130
- [a Jamstack provider]: https://www.11ty.dev/docs/deployment/#jamstack-providers
131
- [a classic web host]: https://www.11ty.dev/docs/deployment/#classic-web-hosts
132
-
133
- However, your podcast episode files should probably be hosted somewhere else, preferably on a Content Delivery Network (CDN), which will let your listeners download your episodes promptly and quickly.
134
-
135
- There are many options available, including [Digital Ocean Spaces][], [Linode Object Storage][], [Backblaze B2 Cloud Storage][] and [Cloudflare R2][].
136
-
137
- [Digital Ocean Spaces]: https://www.digitalocean.com/products/spaces
138
- [Linode Object Storage]: https://www.linode.com/products/object-storage/
139
- [Backblaze B2 Cloud Storage]: https://www.backblaze.com/cloud-storage
140
- [Cloudflare R2]: https://developers.cloudflare.com/r2/
141
-
142
- To find out how to set this up and how to make this work with **Podcaster**, [read more about hosting your podcast episode files][episode-file-hosting].
143
-
144
- [episode-file-hosting]: hosting.md
145
-
146
- ## Optional features
147
-
148
- **Podcaster** also implements some optional features which are useful for creating podcast websites — **drafts** and **excerpts**.
149
-
150
- These are not fundamental features of a podcast website, which is why they are opt-in. You activate them by passing options to the `addPlugin` method in your configuration file.
151
-
152
- ```js
153
- eleventyConfig.addPlugin(podcaster, {
154
- handleDrafts: true,
155
- handleExcerpts: true
156
- })
157
- ```
158
-
159
- [Read more about optional features.](optional-features.md)
160
-
161
- ## Podcaster in action
162
-
163
- I started podcasting and creating podcasting websites in 2014. At first I used Squarespace, then WordPress, and then Jekyll, before finally settling on Eleventy late in 2022.
164
-
165
- I now have seven podcast websites powered by Eleventy, and **Podcaster** was derived from the code I used to create them.
166
-
167
- Here's a list:
168
-
169
- - [Flight Through Entirety](https://flightthroughentirety.com), a _Doctor Who_ podcast flying through the entirety of the show's 60-something-year history.
170
- - [Untitled Star Trek Project](https://untitledstartrekproject.com), a _Star Trek_ commentary podcast, where two friends watch _Star Trek_ episodes from across the franchise, chosen (nearly) at random using [a page on the podcast website](https://untitledstartrekproject.com/randomiser).
171
- - [500 Year Diary](https://500yeardiary), another _Doctor Who_ podcast, where we look at the show's themes and ideas and some of the people involved in its creation.
172
- - [The Second Great and Bountiful Human Empire](https://thesecondgreatandbountifulhumanempire.com), a _Doctor Who_ flashcast, where we give our initial reactions to each episode of the post-2023 era of the show.
173
- - [Startling Barbara Bain](https://startlingbarbarabain), a commentary podcast on _Space: 1999_, a lavish and generally ridiculous British scifi show from the 1970s.
174
- - [Maximum Power](https://maximumpowerpodcast.com), a podcast about _Blakes 7_, a less lavish but more ridiculous British scifi show from the 1970s.
175
- - [Bondfinger](https://bondfinger.com), a James Bond commentary podcast that soon ran out of James Bond films and ended up spending its time drinking and watching terrible TV shows from the 1960s.
176
-
177
- ## Licence
178
-
179
- This plugin is available as open source under the terms of the [ISC License](https://opensource.org/licenses/ISC).
@@ -1,55 +0,0 @@
1
- # Episode information
2
-
3
- Each episode of your podcast should have an associated Eleventy template, with a `podcastEpisode` tag. The front matter of this template will contain the necessary information about the episode, and the content of the template will be the show notes.
4
-
5
- ## Front matter
6
-
7
- The important information about each of your podcast episodes — the title, the date, the filename, the episode number, the size, the duration — should be made available in an `episode` object in the front matter of a post with an `podcastEpisode` tag, like this:
8
-
9
- ```yaml
10
- ---
11
- title: Entering a new Phase
12
- date: 2024-04-14
13
- tags:
14
- - podcastEpisode
15
- episode:
16
- filename: 500YD S1E1, Entering a New Phase.mp3
17
- seasonNumber: 1
18
- episodeNumber: 1
19
- size: 61231442
20
- duration: 3283
21
- explicit: no
22
- episodeType: full
23
- excerpt: >-
24
- A big week for beginnings this week, with a new Doctor,
25
- a new origin story for the Daleks, and a whole new approach
26
- to defeating the bad guys. Oh, and a new podcast to discuss
27
- them all on. So let’s welcome Patrick Troughton to the studio
28
- floor, as we discuss _The Power of the Daleks_.
29
- ---
30
- ```
31
-
32
- Here's a detailed description of the data you need to provide here.
33
-
34
- | field | value | required? |
35
- | ----- | ----- | ----- |
36
- | `title` | The title of the episode; this will also be the title of the post on the website. | yes |
37
- | `date` | The release date of the episode; this will also be the date of the post on the website | yes |
38
- | `tags` | Every episode post must have the tag `podcastEpisode` included in the `tags` array. Other tags are also permitted. | yes |
39
- | `guid` | A unique ID for the post. Normally this will be the post's URL, in which case there is no need to provide it here. It's should really only be necessary to provide it if you're importing the podcast from some other system that has assigned a guid to each post. | no |
40
- | `episode.filename` | The filename of the episode's audio file. | yes |
41
- | `episode.seasonNumber` | The season number. (Most podcasts don't group their episodes into seasons.) | no |
42
- | `episode.episodeNumber` | The episode number. Needn't be unique, but the combination of `seasonNumber` and `episodeNumber` must be unique. | yes |
43
- | `episode.size` | The size of the episode's audio file in bytes. | yes |
44
- | `episode.duration` | The duration of the episode as a number of seconds. You can convert this to `h:mm:ss` format using Podcaster's `readableDuration` filter. | yes |
45
- | `episode.explicit` | Warns listeners that this episode contains explicit language. Should be used for a single episode in a podcast that isn't itself marked as explicit. | no |
46
- | `episode.type` | The type of episode. Defaults to `full`, meaning a full episode of the podcast. Other valid types are `trailer` and `bonus`. | no |
47
- | `excerpt` | A shorter version of the content of the post, written in Markdown. For use in lists of episodes where the show notes are long. For other ways of providing excerpts to **Podcaster**, check out its [optional excerpts feature][excerpts]. | no |
48
-
49
- [excerpts]: /docs/optional-features.md#excerpts
50
-
51
- > [!TIP]
52
- > It's possible for **Podcaster** to calculate the size and duration for each episode if it has access to your episode audio files. [Read more to find out how](docs/size-and-duration.md).
53
-
54
- > [!TIP]
55
- > It's also possible for **Podcaster** to automatically create an `excerpt` for each episode. [Read more to find out how](/docs/optional-features.md#excerpts).
package/docs/hosting.md DELETED
@@ -1,20 +0,0 @@
1
- # Hosting your podcast episode files
2
-
3
- As it says in [README.md](README.md), you should probably host your podcast files separately from your website. I host my podcast episode files in [Digital Ocean Spaces][], which is inexpensive and not particularly difficult to set up. But there are many other options available, including [Linode Object Storage][], [Backblaze B2 Cloud Storage][] and [Cloudflare R2][].
4
-
5
- [Digital Ocean Spaces]: https://www.digitalocean.com/products/spaces
6
- [Linode Object Storage]: https://www.linode.com/products/object-storage/
7
- [Backblaze B2 Cloud Storage]: https://www.backblaze.com/cloud-storage
8
- [Cloudflare R2]: https://developers.cloudflare.com/r2/
9
-
10
- Your CDN host will assign URLs to each of your podcast episodes: you will tell **Podcaster** about these URLs by defining `podcast.episodeUrlBase` as the base URL for all of your podcast episodes, like this: `https://example-podcast.sfo3.digitaloceanspaces.com`. You will provide the filename for each episode as `episode.filename`.
11
-
12
- To deploy your episodes to your CDN host, you can write an NPM script using [`rclone`][rclone], `rsync` or `s3cmd`, depending on your setup.
13
-
14
- [rclone]: https://rclone.org
15
-
16
- Here's the script that I use to deploy the episodes for one of my sites to a DigitalOcean Space.
17
-
18
- ```sh
19
- rclone sync episodes/ digitalocean:startlingbarbarabain -P --exclude .DS_Store
20
- ```
@@ -1,43 +0,0 @@
1
- # Optional features
2
-
3
- **Podcaster** includes some optional features which you might find useful for your podcasting website. These features are turned off by default, in case you want to implement them some other way. You can enable one or both of them when you include the plugin in your eleventy configuration file, like this:
4
-
5
- ```js
6
- // eleventy.config.js
7
-
8
- import podcasterPlugin from 'eleventy-plugin-podcaster'
9
-
10
- export default function (eleventyConfig) {
11
- .
12
- .
13
- eleventyConfig.addPlugin(podcasterPlugin, {
14
- handleDrafts: true,
15
- handleExcerpts: true,
16
- readableDateLocale: 'en-GB'
17
- })
18
- .
19
- .
20
- }
21
- ```
22
-
23
- ## Drafts
24
-
25
- If `handleDrafts` is set to `true`, the plugin will allow you to designate posts as drafts by including `draft: true` in their front matter (or elsewhere in the data cascade). By default, drafts will be included in the build when Eleventy is running in `serve` or `watch` mode, but will be excluded in `build` mode. You can override this default behaviour by setting the `BUILD_DRAFTS` environment variable to `true` or `false`.
26
-
27
- ## Excerpts
28
-
29
- If `handleExcerpts` is set to `true`, the plugin will create excerpts for your podcast episode posts. Excerpts are shortened versions of your final content, which you can use on index pages or topic pages or guest pages instead of your complete post.
30
-
31
- Excerpts are available in a template as `{{ excerpt }}`, but you will probably access them from a collection item, where they are available as `{{ item.data.excerpt }}`. Excerpts are HTML fragments.
32
-
33
- **Podcaster** defines the excerpt in one of three ways, in order of priority.
34
-
35
- 1. As an `excerpt` field in the post's front matter. This should be written in Markdown.
36
- 2. The part of the post between the excerpt delimiters `<!---excerpt-->` and `<!---endexcerpt-->` .
37
- 3. The first paragraph in the post which is not nested inside another tag. (This is so that a blockquote at the beginning of a post isn't included in the excerpt.)
38
-
39
- ## `readableDate` filter
40
-
41
- **Podcaster** optionally provides a `readableDate` filter, to match `readableDuration` and `readableSize`. It transforms a date into a localised string, which usually includes weekday, day of month, month and year.
42
-
43
- To make **Podcaster** provide this filter, pass a locale string as one of the options when you're adding the plugin to your config file. In English, the two most common locale strings are `'en-GB'` and `'en-US'`.
@@ -1,95 +0,0 @@
1
- # Podcast information
2
-
3
- The important information about your podcast — the title, the owner, the category, the subcategory and so on — should be made available as fields in a `podcast` object in the data cascade. The easiest way to do this is to put all the required information in your data directory in a `podcast.json` file, like this:
4
-
5
- ```json
6
- {
7
- "title": "Flight Through Entirety: A Doctor Who Podcast",
8
- "description": "Flying through the entirety of Doctor Who. Originally with cake, but now with guests.",
9
- "siteUrl": "https://flightthroughentirety.com",
10
- "author": "Flight Through Entirety",
11
- "category": "TV & Film",
12
- "language": "en-AU",
13
- }
14
- ```
15
-
16
- ---
17
-
18
- However, `eleventy-plugin-podcast` is quite customisable. He's another `podcast.json` file, with all of the valid fields included.
19
-
20
- ```json
21
- {
22
- "feedPath": "/podcast.xml",
23
- "title": "Flight Through Entirety: A Doctor Who Podcast",
24
- "subtitle": "Flying through the entirety of Doctor Who",
25
- "summary": "Flying through the entirety of Doctor Who. Originally with cake,but now with guests.",
26
- "description": "Flying through the entirety of Doctor Who. Originally with cake, but now with guests.",
27
- "siteUrl": "https://flightthroughentirety.com",
28
- "owner": {
29
- "name": "Nathan Bottomley",
30
- "email": "nathan@example.com"
31
- },
32
- "author": "Flight Through Entirety",
33
- "category": "TV & Film",
34
- "subcategory": "TV Reviews",
35
- "imagePath": "/assets/images/podcast-logo.jpg",
36
- "explicit": false,
37
- "type": "episodic",
38
- "complete": "no",
39
- "language": "en-AU",
40
- "copyright": "Flight Through Entirety",
41
- "startingYear": 2014,
42
- "episodeUrlBase": "https://example.fte-cdn.com/",
43
- "feedEpisodeContentTemplate": "feed-episode-content.njk",
44
- "feedEpisodeDescriptionTemplate": "feed-episode-description.njk"
45
- "feedEpisodeSummaryTemplate": "feed-episode-summary.njk"
46
- }
47
- ```
48
-
49
- And here's a detailed description of all of this information.
50
-
51
- | field | value | required? |
52
- | ----- | ----- | --------- |
53
- | `feedPath` | The path where the podcast feed will be located. Defaults to `/feed/podcast.xml`. | no |
54
- | `title` | The title of your podcast. | yes |
55
- | `subtitle` | A short description of your podcast. If you omit this the `description` field will be used instead. | no |
56
- | `summary` | A description of your podcast. If you omit this the `description` field will be used instead. | no |
57
- | `description` | A short description of your podcast. The most popular podcast applications prominently display this information. | yes |
58
- | `siteUrl` | The URL of your podcast website. The most popular podcast applications use this to provide a link to your website. It's also used by this plugin to convert relative links to absolute links in your feed. (If `podcast.siteUrl` isn't provided, the feed template will use `site.url` instead.) | yes |
59
- | `owner` | An optional object in the form `{ name, email }` You might want to omit this: Apple Podcasts has deprecated it, and an email in a podcast feed will attract some spam. However, some podcast directories, like Castbox, will use the email address to identify you when you try to claim ownership of a podcast in their directory. | no |
60
- | `author` | The creator or creators of the podcast. The most popular podcast applications prominently display this information. | yes |
61
- | `category` | The category for the podcast. Describes he kind of show it is. Valid categories are listed in [this Apple support document][categories]. Used by podcast directories to help listeners find the podcast. | yes |
62
- | `subcategory` | The subcategory for the podcast. Valid subcategories are also listed in [the Apple support document][categories]. | no |
63
- | `imagePath` | The path to your podcast logo, which should be a JPEG or PNG file 3000 × 3000 pixels in size. (You can find more detailed specifications in [this Apple support document](https://podcasters.apple.com/support/896-artwork-requirements#shows)). Defaults to `/img/podcast-logo.jpg`. | yes |
64
- | `explicit` | Warns listeners that your podcast contains explicit language. In Apple Podcasts, if you include this with the value `true`, your podcast and its episodes will be badged with an 🄴 to indicate that they use explicit language. Some of the most popular podcast applications ignore this field. | no |
65
- | `type` | Two possible values: `episodic` and `serial`. Defaults to `episodic`, which means that the podcast can be listened to in no particular order. Narrative podcasts (like _Serial_) should be marked as `serial`. | no |
66
- | `complete` | Indicates that a podcast is complete and that no new episodes should be expected, in which case it should have the value `true`. Should be omitted otherwise. | no |
67
- | `language` | A code that specifies the language of the feed (rather than the podcast). You can find [a list of permissible codes][lang] at the RSS Advisory Board's website. | yes |
68
- | `copyright` | The copyright owner of the podcast. If omitted, the value supplied for `author` is used instead. | no |
69
- | `startingYear` | The year your podcast started. Used to express the copyright date as a range (_"© 2014–2024 Flight Through Entirety"_). If this is omitted, the copyright date will just be the current year. | no |
70
- | `episodeUrlBase` | If you store your podcast episodes on a CDN, or if you use a podcast analytics service, this is where you specify the base URL for them. If you don't specify this, it defaults to `https://{{ podcast.siteUrl }}/episodes/` | no |
71
-
72
- [categories]: https://podcasters.apple.com/support/1691-apple-podcasts-categories
73
- [lang]: https://www.rssboard.org/rss-language-codes
74
-
75
- ## Feed episode templates
76
-
77
- For each episode of the podcast, the feed can contain three textual descriptions — `content`, `description` and `summary`. `content` is HTML and will contain the show notes of an episode. `description` and `summary` are short plain text descriptions of the episode.
78
-
79
- By default, **Podcaster** will set the `content` of the feed to the `content` of an episode's post, and will set `summary` and `description` to an abbreviated version of the content (roughly the first 500 characters of the `content`). And this will be perfectly fine for most podcast feeds.
80
-
81
- However, if you want to, you can override any or all of these three textual descriptions by providing special templates in the includes directory and adding their names to the `podcast` object.
82
-
83
- | field | value | required? |
84
- | ----- | ----- | --------- |
85
- | `feedEpisodeContentTemplate` | The name of an include template that will be used to create the show notes of each episode, as displayed in your listeners' podcast players. The content of this template should be HTML. You only need to include this if you want the show notes in podcast players to be different from the show notes on the website. | no |
86
- | `feedEpisodeDescriptionTemplate` | The name of an include template that will be used to create the description of each episode. The content of this template should be plain text. If it's omitted, the description will just be an abbreviated text version of the `content` of the episode's post. | no |
87
- | `feedEpisodeSummaryTemplate` | The name of an include template that will be used to create the summary of each episode. The content of this template should be plain text. If it's omitted, the description will just be an abbreviated text version of the `content` of the episode's post. | no |
88
-
89
- These templates must be Nunjucks templates, and the post for the episode must be referred to by the variable `post`. Here's a sample content template from one of my podcast websites.
90
-
91
- ```njk
92
- <p class="diary-date">{{ post.data.diaryDate | readableDate }}</p>
93
- <p class="topic">{{ post.data.topic }}</p>
94
- {{ post.content | safe }}
95
- ```
@@ -1,58 +0,0 @@
1
- # Size and duration
2
-
3
- The simplest way of telling **Podcaster** the size and duration of your podcast episode files is by including that information in the front matter of each episode's post, like this:
4
-
5
- ```yaml
6
- episode:
7
- size: 61231442 # bytes
8
- duration: 3778.482 # seconds
9
- ```
10
-
11
- However, you can also get **Podcaster** to analyses your podcast's episode files and find that information for you.
12
-
13
- To do this, you need a directory which contains all of your podcast's episode files. **Podcaster** assumes that this is an `episodes` folder at the top level of your project. If it finds the folder, it will analyse all of its `.mp3` files, find their size and duration, and save that information in a JSON file called `episodesData.json` in your project's data directory.
14
-
15
- ```json
16
- {
17
- "500YD S1E1, Entering a New Phase (The Power of the Daleks).mp3": {
18
- "size": 61231442,
19
- "duration": 3778.482
20
- }
21
- }
22
- ```
23
-
24
- During the build, **Podcaster** will use this JSON file behind the scenes to retrieve `episode.size` and `episode.duration`, both in the podcast feed and in your templates, using the filename you have provided as `episode.filename`.
25
-
26
- You can specify another folder for **Podcaster** to use when you include **Podcaster** in your configuration file by specifying a relative or absolute path like this.
27
-
28
- ```js
29
- import podcasterPlugin from 'eleventy-plugin-podcaster'
30
-
31
- export default function (eleventyConfig) {
32
- .
33
- .
34
- eleventyConfig.addPlugin(podcasterPlugin, {
35
- episodesDir: '~/episodes'
36
- })
37
- .
38
- .
39
- }
40
- ```
41
-
42
- ## Why `episodesData.json`?
43
-
44
- When you're building your site locally, you can easily point **Podcaster** at a local directory full of your podcast's episode files and then run your build.
45
-
46
- But if you host your site on a Jamstack provider and it's building your site for you, it won't have access to a directory like that. (Your podcast files are too big to store in your repository.)
47
-
48
- So you can run your build locally first, and then commit the resulting `episodesData.json` file to your repository. If you do that, the build process on your host will use the information there to work our your episodes' size and duration.
49
-
50
- ## Skipping the process
51
-
52
- **Podcaster** will analyse your MP3 files only once during a `--serve` session. To get it to run the analysis again, you need to restart the web server.
53
-
54
- If you don't want to run the analysis process during a build, you can just set the environment variable `SKIP_EPISODE_CALCULATIONS` to `true`.
55
-
56
- ```sh
57
- SKIP_EPISODE_CALCULATIONS=true npx @11ty/eleventy --serve
58
- ```