Skip to content

Instantly share code, notes, and snippets.

@lpar
Last active January 29, 2023 14:09
  • Star 16 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save lpar/7ded35d8f52fef7490a5be92e6cd6937 to your computer and use it in GitHub Desktop.
How to make Hugo (0.20+) generate an Atom feed instead of RSS

The Hugo static site generator sadly still uses the obsolete and badly standardized RSS format.

Here's how to set it up to generate an Atom feed instead. Pretty much all feed readers which understand RSS also understand Atom, except iTunes, and Atom is a better format.

  1. Define an appropriate media type and corresponding output format in config.toml:
    [mediaTypes]
    [mediaTypes."application/atom"]
    suffix = "xml"

    [outputFormats.Atom]
    mediaType = "application/atom"
    baseName = "index"
    isPlainText = false
  1. Tell Hugo to produce the home page in Atom and HTML formats, also in config.toml:
    [outputs]
    home = [ "HTML", "Atom" ]
  1. Put an index.atom.xml template file in your layouts directory. You can use the attached one as a starting point, don't forget to edit the author element appropriately or make it take the values from your config.
<feed xmlns="http://www.w3.org/2005/Atom">
<title>{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}</title>
<link rel="self" href="{{ .Permalink }}"/>
<updated>{{ .Date.Format "2006-01-02T15:04:05-0700" | safeHTML }}</updated>
<author>
<name>YOUR NAME HERE</name>
<email>YOUR EMAIL ADDRESS</email>
<uri>DEFINITIVE URI OF YOUR WEB SITE</uri>
</author>
<id>{{ .Permalink }}</id>
{{ range first 15 .Data.Pages }}
<entry>
<title>{{ .Title }}</title>
<link rel="alternate" href="{{ .Permalink }}"/>
<id>{{ .Permalink }}</id>
<published>{{ .Date.Format "2006-01-02T15:04:05-0700" | safeHTML }}</published>
<updated>{{ .Lastmod.Format "2006-01-02T15:04:05-0700" | safeHTML }}</updated>
<summary>{{ .Summary | html }}</summary>
</entry>
{{ end }}
</feed>
@adiabatic
Copy link

The media-type stuff helped. Thanks!

@marcisme
Copy link

marcisme commented Jul 2, 2017

Thanks for this. The configuration was helpful. I had to make some adjustments to the template to get it to validate.

<feed xmlns="http://www.w3.org/2005/Atom">
  <title>{{ if eq  .Title  .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title>
  <link href="{{ .Permalink }}index.xml" rel="self"/>
  <link href="{{ .Permalink }}"/>{{ if not .Date.IsZero }}
  <updated>{{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHTML }}</updated>{{ end }}
  <id>{{ .Permalink }}</id>{{ with .Site.Author.name }}
  <author>
    <name>{{.}}</name>{{ with $.Site.Author.email }}
    <email>{{.}}</email>{{end}}
  </author>{{end}}
  <generator>Hugo -- gohugo.io</generator>{{ range .Data.Pages }}
  <entry>
    {{ `<title type="html"><![CDATA[` | safeHTML }}{{ .Title }}]]></title>
    <link href="{{ .Permalink }}"/>
    <id>{{ .Permalink }}</id>{{ with .Site.Params.Author }}
    <author>
      <name>{{.}}</name>
    </author>{{end}}
    <published>{{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHTML }}</published>
    <updated>{{ .Lastmod.Format "2006-01-02T15:04:05-07:00" | safeHTML }}</updated>
    {{ `<content type="html"><![CDATA[` | safeHTML }}{{ .Content }}]]></content>
  </entry>{{ end }}
</feed>

Update: I removed the | html part from {{ .Content | html }} because escaping the content caused it to not render properly in my feed reader. The validators complain about the data-lang attributes that are there for syntax highlighting, but I think that's ok.

@dianoetic
Copy link

In case anyone else stumbles on this as I did, I added some updates of my own drawing from Hugo's current RSS template.

{{- $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 -}}
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>{{ if eq  .Title  .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title>
  <link href="{{ .Permalink }}index.xml" rel="self"/>
  <link href="{{ .Permalink }}"/>{{ if not .Date.IsZero }}
  <updated>{{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHTML }}</updated>{{ end }}
  <id>{{ .Permalink }}</id>{{ with .Site.Author.name }}
  <author>
    <name>{{.}}</name>{{ with $.Site.Author.email }}
    <email>{{.}}</email>{{end}}
  </author>{{end}}
  <generator>Hugo -- gohugo.io</generator>{{ range $pages }}
  <entry>
    {{ `<title type="html"><![CDATA[` | safeHTML }}{{ .Title }}]]></title>
    <link href="{{ .Permalink }}"/>
    <id>{{ .Permalink }}</id>{{ with $.Site.Author.name }} 
    <author>
      <name>{{.}}</name>
    </author>{{end}}
    <published>{{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHTML }}</published>
    <updated>{{ .Lastmod.Format "2006-01-02T15:04:05-07:00" | safeHTML }}</updated>
    {{ if .Content }}
    {{ `<content type="html"><![CDATA[` | safeHTML }}{{ .Content }}]]></content>
    {{ end }}
  </entry>{{ end }}
</feed>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment