jekyll-octopod 0.23.0 → 0.24.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.
- checksums.yaml +4 -4
- data/assets/_config.yml.sample +14 -0
- data/lib/jekyll/octopod_filters.rb +28 -1
- data/lib/jekyll/paged_feed_page.rb +28 -1
- data/lib/jekyll/podlove_player_tag.rb +37 -2
- data/lib/octopod/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d953001b39397be865714d7b3ed448dc513ae4673d1c362bacead88d51897be9
|
|
4
|
+
data.tar.gz: 5c0f42e40cec30b2977f495df8169f5f92d5b2c02a38b9a8320c9613cc456e06
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8c5b98504862f358426070babb61db21df771c307070b2408631896dcb133a187aa6b5eb807dc981cff65cd0968d3b39626082e91fbdeffbc9cc00ef76e6d360
|
|
7
|
+
data.tar.gz: e8884a4dac88e26b5ebad5230451524b6cdd9cdc12a86eda7b9bd9af1e885d66c64f8d81c98ea5816335ed1c9e04ac6590ece78aa54d2d75dd2b320df6218023
|
data/assets/_config.yml.sample
CHANGED
|
@@ -26,6 +26,20 @@ rsync_delete: true
|
|
|
26
26
|
### Fediverse config, optional
|
|
27
27
|
fediverse_url: https://podcasts.social/@my_account # Fediverse links will not be shown unless this is set
|
|
28
28
|
|
|
29
|
+
### Feed permalinks, optional: by default the episode feeds live at /episodes.<format>.rss. When
|
|
30
|
+
### migrating a podcast from another platform, keep its old feed URL so subscribers don't have to
|
|
31
|
+
### resubscribe (a path ending in "/" is written as index.html, which every web server serves).
|
|
32
|
+
# episode_feed_permalinks:
|
|
33
|
+
# mp3: /feed/mp3/
|
|
34
|
+
|
|
35
|
+
### Transcript speakers, optional: map WebVTT voice tags (<v Thomas>) to names and avatars shown
|
|
36
|
+
### in the player's transcript. Without this, the voice tag itself is shown as the speaker's name.
|
|
37
|
+
# speakers:
|
|
38
|
+
# - id: thomas
|
|
39
|
+
# name: Thomas Kahle
|
|
40
|
+
# voice: Thomas # defaults to name
|
|
41
|
+
# avatar: /assets/img/speakers/thomas.jpg
|
|
42
|
+
|
|
29
43
|
language: en
|
|
30
44
|
explicit: "no" # "yes" | "no" | clean
|
|
31
45
|
|
|
@@ -283,7 +283,7 @@ module Jekyll
|
|
|
283
283
|
|
|
284
284
|
if site['episode_feed_formats']
|
|
285
285
|
site['episode_feed_formats'].map { |f|
|
|
286
|
-
feeds << ["#{f} Episode RSS-Feed",
|
|
286
|
+
feeds << ["#{f} Episode RSS-Feed", OctopodFilters.feed_url(site, f)] unless f == except
|
|
287
287
|
}
|
|
288
288
|
end
|
|
289
289
|
if site['additional_feeds']
|
|
@@ -295,6 +295,33 @@ module Jekyll
|
|
|
295
295
|
feeds
|
|
296
296
|
end
|
|
297
297
|
|
|
298
|
+
# Path of an episode feed page, relative to the site root. By default that's
|
|
299
|
+
# '/episodes.<format>.rss' (page 1) and '/episodes<n>.<format>.rss' (page n). The
|
|
300
|
+
# 'episode_feed_permalinks' setting in '_config.yml' moves page 1 of a format elsewhere, e.g. to
|
|
301
|
+
# keep the feed URL of a podcast migrated from another platform:
|
|
302
|
+
#
|
|
303
|
+
# episode_feed_permalinks:
|
|
304
|
+
# mp3: /feed/mp3/
|
|
305
|
+
def self.feed_path(site, format, page_number = 1)
|
|
306
|
+
permalink = (site['episode_feed_permalinks'] || {})[format.to_s]
|
|
307
|
+
if page_number == 1 && permalink && !permalink.to_s.strip.empty?
|
|
308
|
+
permalink.start_with?('/') ? permalink : "/#{permalink}"
|
|
309
|
+
else
|
|
310
|
+
"/episodes#{page_number == 1 ? '' : page_number}.#{format}.rss"
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def self.feed_url(site, format, page_number = 1)
|
|
315
|
+
"#{site['url']}#{feed_path(site, format, page_number)}"
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# Returns the full URL of an episode feed, honouring 'episode_feed_permalinks'.
|
|
319
|
+
#
|
|
320
|
+
# {{ site | episode_feed_url:'mp3' }} => https://example.com/episodes.mp3.rss
|
|
321
|
+
def episode_feed_url(site, format)
|
|
322
|
+
OctopodFilters.feed_url(site, format)
|
|
323
|
+
end
|
|
324
|
+
|
|
298
325
|
# Returns HTML links to all episode feeds named by the convetion
|
|
299
326
|
# 'episodes.<episode_file_format>.rss' within the root directory. Also it
|
|
300
327
|
# returns all additional feeds specified by 'additional_feeds' in the
|
|
@@ -18,6 +18,33 @@ module Jekyll
|
|
|
18
18
|
self.data['myself'] = page_number == 1 ? nil : page_number.to_s
|
|
19
19
|
self.data['format'] = format
|
|
20
20
|
self.data['page_number'] = page_number
|
|
21
|
+
|
|
22
|
+
# Full URLs for the feed's self/first/last/next/prev links, so the theme doesn't have to
|
|
23
|
+
# rebuild them from the naming convention (which an 'episode_feed_permalinks' entry changes).
|
|
24
|
+
config = site.config
|
|
25
|
+
self.data['self_url'] = OctopodFilters.feed_url(config, format, page_number)
|
|
26
|
+
self.data['first_url'] = OctopodFilters.feed_url(config, format, 1)
|
|
27
|
+
self.data['last_url'] = OctopodFilters.feed_url(config, format, [pages_total, 1].max)
|
|
28
|
+
self.data['next_url'] = OctopodFilters.feed_url(config, format, page_number + 1) if pages_total > page_number
|
|
29
|
+
self.data['prev_url'] = OctopodFilters.feed_url(config, format, page_number - 1) if page_number > 1
|
|
30
|
+
|
|
31
|
+
# Only the canonical first page moves; the generator's duplicate "episodes1.<format>.rss"
|
|
32
|
+
# stays where it is.
|
|
33
|
+
if name == "episodes.#{format}.rss"
|
|
34
|
+
path = OctopodFilters.feed_path(config, format, 1)
|
|
35
|
+
@feed_path = path unless path == "/#{name}"
|
|
36
|
+
self.data['permalink'] = @feed_path if @feed_path
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# A custom feed path ending in "/" (like Podlove's "/feed/mp3/") is written as index.html, the
|
|
41
|
+
# one directory index every web server serves without extra configuration. Jekyll's default
|
|
42
|
+
# would be index.rss, which no server picks up for a directory URL.
|
|
43
|
+
def destination(dest)
|
|
44
|
+
return super unless @feed_path
|
|
45
|
+
|
|
46
|
+
path = @feed_path.end_with?('/') ? "#{@feed_path}index.html" : @feed_path
|
|
47
|
+
site.in_dest_dir(dest, URL.unescape_path(path))
|
|
21
48
|
end
|
|
22
49
|
end
|
|
23
|
-
end
|
|
50
|
+
end
|
|
@@ -45,9 +45,44 @@ module Jekyll
|
|
|
45
45
|
duration: page["duration"],
|
|
46
46
|
audio: audio,
|
|
47
47
|
chapters: page["chapters"] ? page["chapters"].map { |chapter| split_chapter(chapter) }.compact : nil,
|
|
48
|
-
transcripts: transcripts_for(page),
|
|
49
48
|
share: { channels: SHARE_CHANNELS }
|
|
50
|
-
}.to_json
|
|
49
|
+
}.merge(transcripts_and_contributors(page, config).compact).to_json
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# The player shows a transcript cue's speaker by looking cue[:speaker] up by id in the
|
|
53
|
+
# top-level "contributors" list (and ignores cue[:voice] entirely), so the VTT voice tags only
|
|
54
|
+
# become visible names/avatars - and paragraph breaks at each speaker change - once both are
|
|
55
|
+
# filled in. Speakers can be declared per post or site-wide:
|
|
56
|
+
#
|
|
57
|
+
# speakers:
|
|
58
|
+
# - id: thomas
|
|
59
|
+
# name: Thomas Kahle
|
|
60
|
+
# voice: Thomas # matches <v Thomas>, defaults to name
|
|
61
|
+
# avatar: /assets/img/speakers/thomas.jpg
|
|
62
|
+
#
|
|
63
|
+
# Voices without a declared speaker still get a contributor named after the voice itself, so
|
|
64
|
+
# speaker names work out of the box without any configuration.
|
|
65
|
+
def transcripts_and_contributors(page, config)
|
|
66
|
+
speakers = page["speakers"] || config["speakers"] || []
|
|
67
|
+
contributors = speakers.map do |speaker|
|
|
68
|
+
avatar = speaker["avatar"]
|
|
69
|
+
avatar = config["url"] + avatar if avatar&.start_with?("/")
|
|
70
|
+
{ id: speaker["id"].to_s, name: speaker["name"], avatar: avatar, group: speaker["group"] }.compact
|
|
71
|
+
end
|
|
72
|
+
id_by_voice = speakers.to_h { |speaker| [speaker["voice"] || speaker["name"], speaker["id"].to_s] }
|
|
73
|
+
|
|
74
|
+
transcripts = transcripts_for(page)
|
|
75
|
+
transcripts&.each do |cue|
|
|
76
|
+
next unless cue[:voice]
|
|
77
|
+
|
|
78
|
+
unless id_by_voice.key?(cue[:voice])
|
|
79
|
+
id_by_voice[cue[:voice]] = cue[:voice]
|
|
80
|
+
contributors << { id: cue[:voice], name: cue[:voice] }
|
|
81
|
+
end
|
|
82
|
+
cue[:speaker] = id_by_voice[cue[:voice]]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
{ transcripts: transcripts, contributors: contributors.empty? ? nil : contributors }
|
|
51
86
|
end
|
|
52
87
|
|
|
53
88
|
# Finds a WebVTT transcript for this episode and parses it into the cue list Podlove Web
|
data/lib/octopod/version.rb
CHANGED