Flux RSS avec Hugo

Hugo génère automatiquement un flux RSS par langue dans les dossier /en et /fr si on met defaultContentLanguageInSubdir: true dans config.yml. Sinon par défaut le flux RSS de la langue principale (defaultContentLanguage: en) se situe dans /.

Ajouter un lien

On ajoute un lien dans le menu vers le RSS de chaque langue dans config.yml:

defaultContentLanguage: en
defaultContentLanguageInSubdir: true

languages:
  en:
        weight: 1
        menu:
          main:
            - identifier: RSS
              name: RSS
              url: /index.xml
              weight: 40
  fr:
        weight: 2
        menu:
          main:
            - identifier: RSS
              name: RSS
              url: /index.xml
              weight: 40

source: https://gohugo.io/content-management/multilingual/#configure-languages

Ajouter l’auteur dans le flux RSS

Créer un template layouts/_default/rss.xml et modifier le bloc pour inclure l’auteur:

    <item>
      <title>{{ .Title }}</title>
      <link>{{ .Permalink }}</link>
      <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
      {{ with .Site.Params.Author }}<author>{{.}}</author>{{end}}
      <guid>{{ .Permalink }}</guid>
      <description>{{ .Summary | html }}</description>
    </item>

L’auteur doit être défini dans config.yml:

params:
  author: Philippe

CDATA pour encapsuler les caractères spéciaux

L’utilisation de <![CDATA[ ]]> est essentiel pour envoyer des caractères spéciaux dans et content:encoded. Sinon les lecteurs de flux essaient d’interpréter les caractères d’accents ou & ;. Par exemple IFTTT refusaient de traiter mes articles en français à cause des accents.

      <description>{{ printf "<![CDATA[" | safeHTML }}{{ .Summary | html }}{{ printf "]]>" | safeHTML }}</description>

Ajouter une image dans le contenu RSS

Insérer ce bloc <content:encoded> après le bloc <description>. Si une image est définie dans l’en-tête YML de l’article elle sera insérée et utilisable par d’autres programmes comme rss2email.

      {{- if isset .Params "image" }}
      {{ printf "<content:encoded><![CDATA[<img src=\"https://bonsai.earth/img/" | safeHTML }}{{ .Params.image }}{{ printf "\" />" | safeHTML }}{{ .Summary  }}{{ printf "]]></content:encoded>" | safeHTML }}
      {{- end }}

Template rss complet

{{- $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" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <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 -- gohugo.io</generator>{{ with .Site.LanguageCode }}
    <language>{{.}}</language>{{end}}{{ 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}}
    <image>
        <url>https://bonsai.earth/img/picea-20210401-2-thumb.jpg</url>
        <title>{{ if eq  .Title  .Site.Title }}{{ .Site.Title }}{{ else }}{{
 with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title>
        <link>{{ .Permalink }}</link>
    </image>
    {{ 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 -}}
    {{ range $pages }}
    <item>
      <title>{{ .Title }}</title>
      <link>{{ .Permalink }}</link>
      <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
      <guid>{{ .Permalink }}</guid>
      <description>{{ printf "<![CDATA[" | safeHTML }}{{ .Summary | html }}{{ printf "]]>" | safeHTML }}</description>
      {{- if isset .Params "image" }}
      {{ printf "<content:encoded><![CDATA[<img src=\"https://bonsai.earth/img/" | safeHTML }}{{ .Params.image }}{{ printf "\" />" | safeHTML }}{{ .Summary  }}{{ printf "]]></content:encoded>" | safeHTML }}
      {{- end }}
    </item>
    {{ end }}
  </channel>
</rss>

Inclure uniquement les posts dans le flux RSS

Par défaut Hugo incorpore tous les fichiers contenus dans le dossier /content dans le flux RSS. Si on ne veut pas envoyer les pages comme “à propos” mais uniquement les articles du dossier posts, il faut remplacer ces lignes dans le template RSS:

{{- if or $.IsHome $.IsSection -}}
{{- $pages = $pctx.RegularPages  -}}
{{- else -}}
{{- $pages = $pctx.Pages  -}}
{{- end -}}

Par ces lignes:

{{- if or $.IsHome $.IsSection -}}
{{- $pages = (where (where $pctx.RegularPages ".Section" "posts") "Kind" "page")  -}}
{{- else -}}
{{- $pages = (where (where $pctx.Pages ".Section" "posts") "Kind" "page")  -}}
{{- end -}}