A first attempt at supporting podcasts. iTunes RSS feed, layouts, parameters etc. included.
This commit is contained in:
parent
73cc5ad40b
commit
9d40eac2d6
12 changed files with 252 additions and 33 deletions
76
README.md
76
README.md
|
|
@ -25,6 +25,7 @@ This is originally a port of the [Zen](https://www.drupal.org/project/zen) theme
|
|||
* Meta tags and JSON-LD
|
||||
* Multilingual (i18n)
|
||||
* Normalize CSS
|
||||
* Podcast
|
||||
* Responsive design
|
||||
* RSS and JSON feeds with full content
|
||||
* Search with DuckDuckGo
|
||||
|
|
@ -129,14 +130,36 @@ params:
|
|||
microUsername: "" # Your micro.blog username.
|
||||
mobileMenu: true # Turn on a mobile menu on small screens.
|
||||
piwikSiteId: # Matamo site id
|
||||
piwikTrackerUrl: "" # Matamo url, schemaless and no slash on end (example.com/matamo).
|
||||
piwikTrackerUrl: "" # Matamo url, schemaless and no slash on end (example.org/matamo).
|
||||
poweredby: true # Show powered by hugo in footer
|
||||
search: true # Site search with DuckDuckGo.
|
||||
searchSize: 20 # Search field size, default 20.
|
||||
sidebar: true # Show a sidebar to the right
|
||||
submitted: true # Show author and date information for a post.
|
||||
|
||||
podcast:
|
||||
title: # * Feed title, defaults to site title (iTunes).
|
||||
description: # * Feed description/summary, defaults to site description (iTunes).
|
||||
image: # * Feed image, place inside assets directory (iTunes).
|
||||
category:
|
||||
name: # * Feed category (iTunes).
|
||||
subcategories: [] # Feed sub category (iTunes).
|
||||
explicit: false/true # Feed explicit settting, default to false (iTunes).
|
||||
author: # Feed author (iTunes).
|
||||
owner:
|
||||
name: # Feed owner name (iTunes).
|
||||
email: # Feed owner e-mail (iTunes).
|
||||
lang: # Feed language, defaults to site language (iTunes).
|
||||
block: no/yes # Block the feed from iTunes, default to no (iTunes).
|
||||
complete: no/yes # Set the feed as complete, defaults to no (iTunes).
|
||||
type: episodic/serial # Podcast type, defaults to episodic (iTunes).
|
||||
newfeed: # Are you moving? Set the new feed url here (iTunes).
|
||||
cdn: # CDN url, no slash on end (https://cdn.example.org).
|
||||
preload: none/metadata/auto # Set on the HTML5 audio tag, defaults to "metadata".
|
||||
```
|
||||
|
||||
The site will work without setting any of the podcast parameters but your podcast feed will not be accepted by iTunes. At a minimum you need to set the first four, title, description, image and category name. Read more in the podcast section below.
|
||||
|
||||
|
||||
## Multilingual
|
||||
|
||||
|
|
@ -183,6 +206,37 @@ If "lastmod" is set in the frontmatter on a post that value will be used in the
|
|||
With "lastmod" set a date section will also appear at the bottom of post telling the reader the created and modification dates.
|
||||
|
||||
|
||||
## Podcast
|
||||
|
||||
The Zen theme supports podcasting.
|
||||
|
||||
* RSS feed with all the needed iTunes tags.
|
||||
* Single and full layouts with HTML 5 audio player.
|
||||
* Archetype with required parameters.
|
||||
|
||||
|
||||
Here follow all the possible podcast frontmatter parameters. Only the first two is mandatory and are in the podcast archetype.
|
||||
|
||||
```
|
||||
podcast:
|
||||
mp3: # * The path to the mp3 file,
|
||||
duration: # * Episode duration, e.g 1:04:02 (iTunes).
|
||||
image:
|
||||
src: # Episode image src, place inside the assets directory (iTunes).
|
||||
alt: # Alt text for the image, explain what is on the image.
|
||||
width: # Image width in the article, defaults to 250px.
|
||||
class: # Image wrapper class.
|
||||
explicit: true/false # Episode explicit setting, default to false (iTunes).
|
||||
episode: # Episode number (iTunes).
|
||||
episodeType: full/trailer/bonus # Episode type, defaults to full (iTunes).
|
||||
season: # Episode season (iTunes).
|
||||
block: # Block the episode from iTunes, default to no (iTunes).
|
||||
```
|
||||
|
||||
* [Apple Podcasts categories](https://help.apple.com/itc/podcasts_connect/#/itc9267a2f12)
|
||||
* [Apple - A podcaster’s guide to RSS](https://help.apple.com/itc/podcasts_connect/#/itcb54353390)
|
||||
|
||||
|
||||
## Shortcodes
|
||||
|
||||
### Contact
|
||||
|
|
@ -201,6 +255,7 @@ Zen comes with a improved version of the built in "figure" shortcut.
|
|||
* If width and height is not set the real dimensions of the image will be used.
|
||||
* If only width or height is set the other value will be proportionally calculated.
|
||||
|
||||
|
||||
### Clear
|
||||
|
||||
Break float.
|
||||
|
|
@ -215,6 +270,25 @@ blablabla # Displayed left of the image.
|
|||
blablabla # Displayed below of the image.
|
||||
```
|
||||
|
||||
|
||||
### Audio and Video
|
||||
|
||||
```
|
||||
{{< audio src="/audio/audio.mp3" class="something" >}}
|
||||
|
||||
{{< video src="/video/video.mp4" class="something" >}}
|
||||
```
|
||||
|
||||
Possible parameters are:
|
||||
|
||||
* src
|
||||
* class
|
||||
* preload (none/metadata/auto, default metadata)
|
||||
* width (only video)
|
||||
|
||||
The audio and video tags will be wrapped with a figure tag.
|
||||
|
||||
|
||||
### Wrapper
|
||||
|
||||
A simple, but useful, shortcode to wrap content in a div with a class. The content will be run through "markdownify".
|
||||
|
|
|
|||
5
archetypes/micro.md
Normal file
5
archetypes/micro.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: "{{ replace .TranslationBaseName "-" " " | humanize }}"
|
||||
date: {{ .Date }}
|
||||
|
||||
---
|
||||
8
archetypes/podcast.md
Normal file
8
archetypes/podcast.md
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
title: "{{ replace .TranslationBaseName "-" " " | humanize }}"
|
||||
date: {{ .Date }}
|
||||
podcast:
|
||||
mp3:
|
||||
duration:
|
||||
|
||||
---
|
||||
|
|
@ -161,46 +161,56 @@ article {
|
|||
}
|
||||
|
||||
figure {
|
||||
@include respond-to(s) {
|
||||
display: table;
|
||||
margin: 0;
|
||||
|
||||
img {
|
||||
display: block;
|
||||
&.image {
|
||||
figcaption {
|
||||
@include respond-to(s) {
|
||||
display: table-caption;
|
||||
caption-side: bottom;
|
||||
}
|
||||
|
||||
h4,
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.left {
|
||||
@include padding(0 .5 .5 0);
|
||||
margin: 0;
|
||||
float: left;
|
||||
clear: both;
|
||||
@include respond-to(s) {
|
||||
display: table;
|
||||
|
||||
figcaption {
|
||||
img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&.left {
|
||||
@include padding(0 .5 .5 0);
|
||||
margin: 0;
|
||||
float: left;
|
||||
clear: both;
|
||||
|
||||
figcaption {
|
||||
@include padding(0 .5 .5 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.right {
|
||||
@include padding(0 0 .5 .5);
|
||||
margin: 0;
|
||||
float: right;
|
||||
clear: both;
|
||||
|
||||
figcaption {
|
||||
&.right {
|
||||
@include padding(0 0 .5 .5);
|
||||
margin: 0;
|
||||
float: right;
|
||||
clear: both;
|
||||
|
||||
figcaption {
|
||||
@include padding(0 0 .5 .5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
figcaption {
|
||||
@include respond-to(s) {
|
||||
display: table-caption;
|
||||
caption-side: bottom;
|
||||
}
|
||||
|
||||
h4,
|
||||
p {
|
||||
margin: 0;
|
||||
&.podcast {
|
||||
audio {
|
||||
width: 95%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
12
layouts/partials/podcast.html
Normal file
12
layouts/partials/podcast.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{{ $src := (.Params.podcast.mp3 | absURL) -}}
|
||||
{{ if .Site.Params.Podcast.cdn -}}
|
||||
{{ $src = add $.Site.Params.Podcast.cdn (.Params.podcast.mp3 | relURL) -}}
|
||||
{{ end -}}
|
||||
<figure class="podcast">
|
||||
<audio controls preload="{{ .Site.Params.Podcast.preload | default "metadata" }}"><source src="{{ $src }}" type="audio/mpeg"></audio>
|
||||
<figcaption><a href="{{ $src }}">{{ .Title }}</a></figcaption>
|
||||
</figure>
|
||||
{{ with .Params.podcast.image }}
|
||||
{{ $resource := resources.Get .src }}{{ $size := "250x" }}{{ with .width }}{{ $size = (add (string .) "x") }}{{ end }}{{ $image := $resource.Resize $size -}}
|
||||
<figure class="image {{ .class | default "right" }}"><img src="{{ $image.RelPermalink }}" width="{{ .width | default "250" }}" alt="{{ .alt }}"></figure>
|
||||
{{ end -}}
|
||||
10
layouts/podcast/full.html
Normal file
10
layouts/podcast/full.html
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<article class="{{ with .Section }}section-{{ . | urlize }} {{ end }}full-view">
|
||||
<header>
|
||||
<h1 class="title {{ if $.Param "submitted" | default false }}title-submitted{{ end }}"><a href="{{ .RelPermalink }}">{{ .Title }}</a></h1>
|
||||
{{ if $.Param "submitted" | default false }}{{ partial "submitted.html" . }}{{ end -}}
|
||||
</header>
|
||||
{{ partial "podcast.html" . -}}
|
||||
<div class="content">
|
||||
{{ .Content }}
|
||||
</div>
|
||||
</article>
|
||||
64
layouts/podcast/rss.xml
Normal file
64
layouts/podcast/rss.xml
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
|
||||
<channel>
|
||||
<title>{{ .Site.Params.Podcast.Title | default .Site.Title }}</title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
<description>{{ .Site.Params.Podcast.Description | default .Site.Params.Description }}</description>
|
||||
<generator>Hugo -- gohugo.io</generator>
|
||||
<language>{{ .Site.Params.Podcast.Lang | default .Site.LanguageCode }}</language>
|
||||
{{ with .Site.Author.email -}}
|
||||
<managingEditor>{{ . }}{{ with $.Site.Author.name }} ({{ . }}){{end}}</managingEditor>
|
||||
{{ end -}}
|
||||
{{ with .Site.Author.email -}}
|
||||
<webMaster>{{ . }}{{ with $.Site.Author.name }} ({{ . }}){{end}}</webMaster>
|
||||
{{ end -}}
|
||||
{{ with .Site.Copyright -}}
|
||||
<copyright>{{ . }}</copyright>
|
||||
{{ end -}}
|
||||
{{ if not .Date.IsZero -}}
|
||||
<lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>
|
||||
{{ end -}}
|
||||
{{ with .OutputFormats.Get "RSS" -}}
|
||||
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
|
||||
{{ end -}}
|
||||
{{ with .Site.Params.Podcast.Image }}{{ $image := resources.Get . }}<itunes:image href="{{ $image.Permalink }}" />{{ end }}
|
||||
{{ with .Site.Params.Podcast.Category -}}
|
||||
<itunes:category {{ if .name }}text="{{ .name }}"{{end}}>
|
||||
{{ range .subcategories }}<itunes:category text="{{ . }}" />{{ end }}
|
||||
</itunes:category>
|
||||
{{ end -}}
|
||||
{{ with .Site.Params.Podcast.Owner -}}
|
||||
<itunes:owner>
|
||||
{{ with .name }}<itunes:name>{{ . }}</itunes:name>{{ end }}
|
||||
{{ with .email }}<itunes:email>{{ . }}</itunes:email>{{ end }}
|
||||
</itunes:owner>
|
||||
{{ end -}}
|
||||
{{ with .Site.Params.Podcast.Description }}<itunes:summary>{{ . }}</itunes:summary>{{ end }}
|
||||
{{ with .Site.Params.Podcast.Author }}<itunes:author>{{ . }}</itunes:author>{{ end }}
|
||||
{{ with .Site.Params.Podcast.Type }}<itunes:type>{{ . }}</itunes:type>{{ end }}
|
||||
{{ with .Site.Params.Podcast.Block }}<itunes:block>{{ . }}</itunes:block>{{ end }}
|
||||
{{ with .Site.Params.Podcast.Complete }}<itunes:complete>{{ . }}</itunes:complete>{{ end }}
|
||||
{{ with .Site.Params.Podcast.NewFeed }}<itunes:new-feed-url>{{ . }}</itunes:new-feed-url>{{ end }}
|
||||
<itunes:explicit>{{ if .Site.Params.Podcast.Explicit }}true{{ else }}false{{ end }}</itunes:explicit>
|
||||
{{ range .Data.Pages }}
|
||||
<item>
|
||||
<title>{{ .Title }}</title>
|
||||
<itunes:title>{{ .Title }}</itunes:title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
<guid>{{ .Permalink }}</guid>
|
||||
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
|
||||
{{ with .Site.Author.email -}}
|
||||
<author>{{ . }}{{ with $.Site.Author.name }} ({{ . }}){{ end }}</author>
|
||||
{{ end -}}
|
||||
<description>{{ .Content | html }}</description>
|
||||
{{ with .Params.podcast.mp3 }}{{ $file_stat := os.Stat (add "/static" (. | relURL)) }}<enclosure url="{{ if $.Site.Params.Podcast.cdn }}{{ add $.Site.Params.Podcast.cdn (. | relURL) }}{{ else }}{{ . | absURL }}{{ end }}" length="{{ $file_stat.Size }}" type="audio/mpeg" />{{ end }}
|
||||
{{ with .Params.podcast.duration }}<itunes:duration>{{ . }}</itunes:duration>{{ end }}
|
||||
{{ with .Params.podcast.image.src }}{{ $image := resources.Get . }}<itunes:image href="{{ $image.Permalink }}" />{{ end }}
|
||||
{{ with .Params.podcast.episode }}<itunes:episode>{{ . }}</itunes:episode>{{ end }}
|
||||
{{ with .Params.podcast.episodeType }}<itunes:episodeType>{{ . }}</itunes:episodeType>{{ end }}
|
||||
{{ with .Params.podcast.season }}<itunes:season>{{ . }}</itunes:season>{{ end }}
|
||||
{{ with .Params.podcast.block }}<itunes:block>{{ . }}</itunes:block>{{ end }}
|
||||
<itunes:explicit>{{ if .Params.podcast.explicit }}true{{ else }}false{{ end }}</itunes:explicit>
|
||||
</item>
|
||||
{{ end }}
|
||||
</channel>
|
||||
</rss>
|
||||
24
layouts/podcast/single.html
Normal file
24
layouts/podcast/single.html
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{{ define "meta" }}
|
||||
{{- partial "single_meta.html" . -}}
|
||||
{{- partial "opengraph_meta.html" . -}}
|
||||
{{ end }}
|
||||
|
||||
{{ define "header" }}
|
||||
{{- partial "single_json_ld.html" . -}}
|
||||
{{ end }}
|
||||
|
||||
{{ define "main" -}}
|
||||
<main class="main layout__main">
|
||||
<article class="{{ with .Section }}section-{{ . | urlize }} {{ end }}single-view">
|
||||
<header>
|
||||
<h1 class="title {{ if $.Param "submitted" | default false }}title-submitted{{ end }}">{{ .Title }}</h1>
|
||||
{{ if $.Param "submitted" | default false }}{{ partial "submitted.html" . }}{{ end -}}
|
||||
{{ if .Params.tags }}{{ partial "tags.html" . }}{{ end -}}
|
||||
</header>
|
||||
{{ partial "podcast.html" . -}}
|
||||
<div class="content">
|
||||
{{ .Content }}
|
||||
</div>
|
||||
</article>
|
||||
</main>
|
||||
{{ end }}
|
||||
6
layouts/shortcodes/audio.html
Normal file
6
layouts/shortcodes/audio.html
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<figure {{ with .Get "class" }}class="{{ . }}"{{ end }}>
|
||||
<audio controls preload="{{ .Get "preload" | default "metadata" }}">
|
||||
{{ with .Get "src" }}<source src="{{ . | relURL }}" type="audio/mpeg">{{ end }}
|
||||
{{ with .Get "caption" }}<figcaption>{{ . }}</figcaption>{{ end }}
|
||||
</audio>
|
||||
</figure>
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
{{ $height := (mul ($.Scratch.Get "realheight") (div (add ($.Scratch.Get "width") 0.0) ($.Scratch.Get "realwidth"))) -}}
|
||||
{{ $.Scratch.Set "height" (math.Round $height) -}}
|
||||
{{ end -}}
|
||||
<figure {{ with .Get "class" }}class="{{ . }}"{{ end }}>
|
||||
<figure class="image {{ .Get "class" | default "" }}">
|
||||
{{ with .Get "link" }}<a href="{{ . }}">{{ end -}}
|
||||
<img src="{{ $.Get "src" | relURL }}" {{ if or (.Get "alt") (.Get "caption") }}alt="{{ with .Get "alt" }}{{ . }}{{ else }}{{ .Get "caption" }}{{ end }}"{{ end }}{{ with $.Scratch.Get "width" }} width="{{ . }}"{{ end }}{{ with $.Scratch.Get "height" }} height="{{ . }}"{{ end }}>
|
||||
<img src="{{ .Get "src" | relURL }}" {{ if or (.Get "alt") (.Get "caption") }}alt="{{ with .Get "alt" }}{{ . }}{{ else }}{{ .Get "caption" }}{{ end }}"{{ end }}{{ with $.Scratch.Get "width" }} width="{{ . }}"{{ end }}{{ with $.Scratch.Get "height" }} height="{{ . }}"{{ end }}>
|
||||
{{- if .Get "link" }}</a>{{ end }}
|
||||
{{ if or (or (.Get "title") (.Get "caption")) (.Get "attr") -}}
|
||||
<figcaption>{{ if isset .Params "title" }}
|
||||
|
|
|
|||
6
layouts/shortcodes/video.html
Normal file
6
layouts/shortcodes/video.html
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<figure {{ with .Get "class" }}class="{{ . }}"{{ end }}>
|
||||
<video controls preload="{{ .Get "preload" | default "metadata" }}" {{ with .Get "width" }}width="{{ . }}"{{ end }}>
|
||||
{{ with .Get "src" }}<source src="{{ . | relURL }}" type="video/mp4">{{ end }}
|
||||
</video>
|
||||
{{ with .Get "caption" }}<figcaption>{{ . }}</figcaption>{{ end }}
|
||||
</figure>
|
||||
|
|
@ -3,8 +3,8 @@ description = "A solid base for your custom Hugo theme with libsass and gulp sup
|
|||
homepage = "https://github.com/frjo/hugo-theme-zen"
|
||||
license = "GPLv2"
|
||||
licenselink = "http://www.gnu.org/licenses/old-licenses/gpl-2.0.html"
|
||||
tags = ["multilingual", "responsive", "blog", "search", "micro"]
|
||||
features = ["multilingual", "responsive", "grid", "sass", "gulp", "search", "matamo", "jsonfeed", "subtheme"]
|
||||
tags = ["multilingual", "responsive", "blog", "search", "micro", "podcast"]
|
||||
features = ["multilingual", "responsive", "grid", "sass", "search", "matamo", "jsonfeed", "subtheme", "podcast"]
|
||||
min_version = 0.47
|
||||
|
||||
[author]
|
||||
|
|
|
|||
Loading…
Reference in a new issue