Enable RSS Readers for Hugo Sites

A RSS reader, old but like rivets, still useful

Some readers of my blog prefer to recieve updates about content via their existing RSS reader. Many popular RSS readers exist, I did a bit of research to enable RSS readers to properly interact with the site.

RSS readers will periodically read a feed url. In my case I used the URL index.xml. We need to do a few things to enable RSS readers.

  1. Enable auto generation of a feed url. Be mindful to not have invalid characters in article titles, as xml will not pass lint.

The output below line 3 tells hugo to use the template index.xml for the home sections. You will notice I also create json, the json template enables search via lunr.js

1
2
[outputs]
    home = ['html', 'rss', 'json']

Enable the XML template.

Reading the fine documentation for hugo. You will find a section about Template Lookup Order. The template order is a powerful and easy way to make sure that modifications can be made to the site from multiple locations. Think 3rd party templates or local templates in testing/beta. The link tells us that we need to create a index.xml in our layouts directory. You will notice logic statement in the template file encased in “braces” {{- -}}. I like to use the - inside braces as it prevent additional whitespace on output. Although preventing whitespace is not important in all cases, it is a good style component for me so I dont forget it when whitespace should be limited.

  1. customize xml to include proper sections
{{- $pctx := . }}
{{- if .IsHome }}{{ $pctx = .Site }}{{ end }}
{{- $pages := slice }}
{{- if or $.IsHome $.IsSection }}
{{- $pages = $pctx.RegularPages }}
{{- else }}
{{- $pages = $pctx.Pages }}
{{- end }}
{{- $limit := .Site.Config.Services.RSS.Limit }}
{{- if ge $limit 1 }}
{{- $pages = $pages | first $limit }}
{{- end }}
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{ . }} on {{ end }}{{ .Site.Title }}{{ end }}</title>
    <link>{{ .Permalink }}</link>
    <description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{ . }} {{ end }}{{ end }}on {{ .Site.Title }}</description>
    <generator>Hugo</generator>
    <language>{{ site.Language.LanguageCode }}</language>{{ with $authorEmail }}
    <managingEditor>{{.}}{{ with $authorName }} ({{ . }}){{ end }}</managingEditor>{{ end }}{{ with $authorEmail }}
    <webMaster>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</webMaster>{{ end }}{{ with .Site.Copyright }}
    <copyright>{{ . }}</copyright>{{ end }}{{ if not .Date.IsZero }}
    <lastBuildDate>{{ (index $pages.ByLastmod.Reverse 0).Lastmod.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 }}
    {{ $pages := where site.RegularPages "Type" "in" site.Params.mainSections }}
    {{- range $pages }}
    <item>
      <title>{{ .Title }}</title>
      <link>{{ .Permalink }}</link>
      <pubDate>{{ .PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
      {{- with $authorEmail }}<author>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</author>{{ end }}
      <guid>{{ .Permalink }}</guid>
      {{- if .Page.Params.description -}}
      <description>{{ .Page.Params.description | transform.XMLEscape | safeHTML }}</description>
      {{ else }}
      <description>{{ .Summary | transform.XMLEscape | safeHTML }}</description>
      {{ end }}
    </item>
    {{- end }}
  </channel>
</rss>

Once the two steps above have been completed validate your xml with a linter.

Validating your content in a RSS reader is also a good idea.

tech

If you would like email or rss feed updates. Visit the Subscribe page