Une blogoliste, c'est un peu un résultat de moteur de recherche généré non pas par un algo, mais par une personne. Si vous avez un lecteur RSS pour votre veille, voici comment utiliser votre liste de flux pour générer une page blogoliste avec Hugo.

Une liste de flux RSS au format .opml

Je me suis longtemps laissé porter par Twitter pour faire ma veille sur le web. Mais, Twitter n’existe plus. Il y a X, mais qui voudrait continuer à se faire polluer par un réseau de réactionnaires à tendance fascisante ? Heureusement, il perdure sur l’internet des mécanismes de partage non privatisés, ouverts, documentés et simples à mettre en place, comme les flux RSS.

En plus des flux RSS mis à disposition par les sites, blogs et autres podcasts, il est possible de suivre les releases de dépôts git ! Par exemple, sur Github, on peut suivre le flux RSS d’un projet sur une url de type https://github.com/USER/PROJECT/releases.atom, ou sur Codeberg avec une url de type https://codeberg.org/USER/PROJECT/releases.rss

C’est avec ces flux (et avec Mastodon) que j’effectue la majeure partie de ma veille. Pour cela, j’utilise un agrégateur de flux : Readwise Reader. Ce n’est peut-être pas l’agrégateur le plus libre de tous, en revanche c’est celui qui me rend le plus de services (en plus de sa fonction d’agrégateur).

Alors ce post ne porte pas sur le RSS ou les agrégateurs libres, mais bien sur les blogolistes. Mon point, c’est que la liste des sites suivis via RSS constitue un bon point de départ pour créer ce type de page. Et Readwise Reader, comme la plupart des agrégateurs, permet d’exporter la liste des flux suivis dans un format standard, le format opml. C’est particulièrement intéressant, car en plus de garantir une certaine interopérabilité entre ces différents agrégateurs, cela nous permettra de récupérer une liste de sites à afficher sur un site web.

Lire un fichier .opml avec Hugo

Si Hugo s’appuie avant tout sur le format markdown pour générer un site, il est aussi capable d’utiliser d’autres formats, comme le xml. Et cela tombe bien, parce un fichier opml, c’est justement du xml.

<?xml version="1.0" encoding="UTF-8"?>
<opml version="2.0">
  <head>
    <title>My feeds</title>
  </head>
  <body>
    <outline text="Feeds" title="Feeds">
      <outline title="W3C News" category="web" type="rss" xmlUrl="https://www.w3.org/blog/news/feed" />
    </outline>
  </body>
</opml>

Donc, une fois le fichier opml téléchargé depuis un aggrégateur, il suffit de le renommer en feeds.xml et de l’ajouter au répertoire /data/blogroll de Hugo. On peut alors y accéder depuis un template avec $.Site.Data.blogroll.feeds.body.outline

Afficher la blogoliste

La liste des sites est donc maintenue dans le fichier opml dans des balises <outline /> contenues dans une autre balise <outline text="Feeds" title="Feeds">...</outline>. Les données des sites sont portées pour des propriétés de ces balises. Readwise Reader retourne un title, une category, un type et une xmlUrl. Pour ma part, j’ai ajouté à la main au fichier d’autres informations : une description, un language, une htmlUrl et une mastodonUrl (cette dernière sortant de la norme opml 2).

<?xml version="1.0" encoding="UTF-8"?>
<opml version="2.0">
  <head>
    <title>alexisjanvier.net's blogroll</title>
  </head>
  <body>
    <outline text="Feeds" title="Feeds">
      <outline title="W3C News" category="Veille professionnelle" type="rss" 
        xmlUrl="https://www.w3.org/blog/news/feed"
        htmlUrl="https://www.w3.org/blog/" 
        mastodonUrl="https://w3c.social/@w3c" 
        description="Le W3C est en charge de promouvoir la compatibilité des technologies du web. Forcement, ce n'est pas idiot de les suivre." 
        language="en" />
    </outline>
  </body>
</opml>

On va donc itérer sur cette liste pour afficher les sites, la petite bizarrerie du système de template d’Hugo étant la manière de récupérer les propriétés de chaque balise <outline>, en l’occurrence :

<ul>
{{ range $.Site.Data.blogroll.feeds.body.outline.outline }}
    {{ $title := index . "-title" }}
    <li>{{ $title }}</li>
{{ end }}
</ul>

Au final, voila comment j’ai affiché ma page blogoliste, en ajoutant un filtrage par catégorie :

<!-- in layouts/blogroll/list.html -->
<div class="post-content">
    <h2>Veille professionnelle</h2>
    <p>Des sites me permettant d'être professionnellement à jour.</p>
    {{ partial "link-table.html" (dict "links" $.Site.Data.blogroll.feeds.body.outline.outline "filter" "Veille professionnelle") }}
</div>
<!-- in layouts/partials/link-table.html -->
<table>
    <tbody>
        {{ $filter := .filter }}
        {{ with .links }}
            {{ range . }}
            {{ $title := index . "-title" }}
            {{ $description := index . "-description" }}
            {{ $category := index . "-category" }}
            {{ $link := index . "-htmlUrl" }}
            {{ $rss := index . "-xmlUrl" }}
            {{ $mastodon := index . "-mastodonUrl" }}
            {{ $language := index . "-language" }}
            {{ if eq $category $filter }}
                <tr>
                    <th scope="row"><a href="{{ $link }}">{{ $title }}</a></th>
                    <td>{{ $description }}  ({{ $language }})</td>
                    <td><a href="{{ $rss }}">RSS</a></td>
                    <td>
                        {{ with $mastodon }}<a href="{{ . }}">Mastodon</a>{{ else }} - {{ end }}
                    </td>
                </tr>
            {{ end }}
            {{ end }}
        {{ end }}
    </tbody>
</table>

Conclusion

Bon, ce post ne va pas révolutionner la blogosphère. Mais il aborde plusieurs thématiques qui me tiennent à cœur :

  • La veille informationnelle, sa provenance (depuis des plateformes privées ou depuis des standards résiliant comme les flux RSS) et par extension son mode de consommation. Sur ce sujet, je vous renvoie sur un bon post de Ploum : “Comment j’ai fui le flux pour retrouver ma boîte”.
  • L’importance des formats ouverts (j’entends par là qu’on peut lire et éditer depuis n’importe quel éditeur de texte) pour persister de la donnée : ici, il s’agit de l’opml permettant de maintenir ses sources de veilles, mais c’est vrai aussi par exemple pour le markdown pour gérer ses contenus, pour le JSON Resume pour maintenir son CV, …
  • Les blogolistes, qui en créant à leur petite échelle un maillage humain du web, justifient à elles seules l’existence des blogs personnels. Parce que “Le web n’est pas qu’un supermarché !”.