Description
Gemini et Gopher sont deux autres Internet, tout à fait légaux, dont le but est de la publication “légère” d’informations, principalement du texte. En fait, historiquement Gopher est né en 1991, en parallèle du Grand Net sur protocole HTTP ; tandis que Gemini est un protocole de communication récent, né courant juin 2019.
Tout comme le Grand Net sur HTTP(S), Gopher et Gemini ont leur propre protocole de communication, portant leur propre nom :
- Gemini :
gemini://
- Gopher :
gopher://
À savoir que le protocole gemini est basé sur TLS directement… De plus, bien que ces protocoles soient cloisonnés entre eux, en effet les protocoles Gemini, Gopher et HTTP(S) sont des réseaux différents, par des services différents, sur des ports différents, il existe des passerelles du côté de Gemini et Gopher, vers HTTP(S).
Ne cherchez pas toutes les fioritures que permet le protocole HTTP(S), exit les scripts CSS, JS, voire les images, avec Gemini et Gopher, on se concentre principalement sur la ressource importante : le texte. cf : cherchez Low Web ;-)
Comment modifier Hugo pour lui faire générer des fichiers à publier sur les protocoles Gemini, et Gopher ?
Dans les faits, vous prendrez plus de temps à lire cet article, qu’à faire vos modifications basiques, qui sont possibles d’être faites en moins de 5 minutes !!!
Il y a(ura) certainements de petites modifications à apporter… mais l’esprit de l’article est là, et fonctionnel. ;-)
ATTENTION : les modifications ci-dessous actuellement sont fonctionnelles dans le contexte d’une configuration basique de Hugo.
Dans le cas d’un site multi-langue, ou que vous avez paramétré la variable
permalinks.posts
, le résultat attendu n’aura pas lieu.
Dans les faits, le repertoire géré par la variable path
est lié au répertoire
de sortie. Ainsi dans le contexte multilangue, vous retrouverez dans chaque
répertoire de langue un répertoire nommé selon le protocole cible !
Ainsi, vous aurez dans le répertoire public/
, d’abord les répertoires de
langue, puis le répertoire gemini
ou gopher
.
Alors que dans une configuration basique, le répertoire gemini
ou gopher
sera directement déposé à la racine du répertoire public/
.
Gemini
Concernant les modifications pour Gemini, voici le propos :
Configuration pour Gemini
Modifions très simplement le fichier de configuration de Hugo config.toml
:
Configuration Gemini : ajout du mimetype
# Gemini
[mediaTypes."text/gemini"]
suffixes = ["gmi"]
Configuration Gemini : ajout du format de sortie
# Gemini
[outputFormats.Gemini]
isPlainText = true
isHTML = false
mediaType = "text/gemini"
name = "gemini"
path = "gemini/"
permalinkable = true
protocol = "gemini://"
Remarquons que la publication des fichiers gmi auront lieu dans un répertoire
distinct, nommé gemini, dans le répertoire public/
.
Ce seront de purs fichiers texte, ayant l’extension .gmi
.
Puis dans la configuration de la sortie, par exemple :
[outputs]
home = ["HTML", "gemini", …]
page = ["HTML", "gemini", …]
Bien sûr, ne pas utiliser les ‘…’ dans votre configuration ; ici, ils expriment les autres options de génération possible, sans les nommer !
Gemini est capable de lire des fichiers au format RSS, ce qui nous permet de générer un flux RSS ; ajoutons un nouveau format de sortie spécifique :
[outputFormats.GeminiRSS]
isHTML = false
mediaType = "application/rss+xml"
name = "GeminiRSS"
protocol = "gemini://"
path = "gemini/"
et modifions la génération de sortie, tel que par exemple :
[outputs]
home = ["HTML", "gemini", "GeminiRSS", …]
Layouts pour Gemini
index.gmi
Ajoutons un fichier index.gmi
dans le repertoire layouts/
, qui pour
l’exemple aura le code hugo basique suivant :
{{ range .Paginator.Pages }}
{{- if .OutputFormats.Get "gemini" }}
⇒ {{ replace .Permalink "/gemini" "" 1 }} {{ .Date.Format "January 2, 2006" }}: {{ .Title | safeHTML }}{{ end }}{{ end }}
Libre à vous de modifier, améliorer la pertinence du code Hugo pour obtenir le contenu que vous désirez publier…
index.geminirss.xml
Si vous désirez gérez un flux RSS pour Gemini, selon la configuration ci-dessus,
ajoutons un fichier index.geminirss.xml
, ayant le contenu de génération
tel que :
{{- $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>{{ .Site.Title | safeHTML }}</title>
<link>{{ replace .Permalink "https" "gemini" 1 }}</link>
<description>{{ .Site.Params.siteDescription | safeHTML }}</description>
<generator>Hugo {{ hugo.Version }} 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}}{{ 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 }}
{{- if .OutputFormats.Get "gemini" -}}
<item>
<title>{{ .Title | safeHTML }}</title>
{{ with .OutputFormats.Get "gemini" }}
<link>{{replace .Permalink "/gemini" "" 1}}</link>
{{ end }}
<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}}
{{ with .OutputFormats.Get "gemini" }}
<guid>{{replace .Permalink "/gemini" "" 1}}</guid>
{{ end }}
</item>
{{- end -}}
{{ end }}
</channel>
</rss>
single.gmi
Dans le répertoire enfant _default
du sous répertoire layouts/
, ajoutons
un simple fichier single.gmi
qui s’occupera principalement de la génération
des pages :
# {{ $.Title | safeHTML }}
{{ .RawContent }}
C’est basique ; ca fait le boulot, simplement. Là encore libre à vous de modifier, ajouter votre code Hugo, pour générer plus proprement afin de débarrasser du code Markdown, par exemple :
{{ $scratch := newScratch }}
{{ $content := .RawContent -}}
{{ $content := $content | replaceRE `#### ` "### " -}}
{{ $content := $content | replaceRE `\n- (.+?)` "\n* $1" -}}
{{ $content := $content | replaceRE `\n(\d+). (.+?)` "\n* $2" -}}
{{ $content := $content | replaceRE `\[\^(.+?)\]:?` "" -}}
{{ $content := $content | replaceRE `<br/??>` "\n" -}}
{{ $content := $content | replaceRE `<a .*href="(.+?)".*>(.+?)</a>` "[$2]($1)" -}}
{{ $content := $content | replaceRE `\sgemini://(\S*)` " [gemini://$1](gemini://$1)" -}}
{{ $content := $content | replaceRE "([^`])<.*?>([^`])" "$1$2" -}}
{{ $content := $content | replaceRE `\n\n!\[.*\]\((.+?) \"(.+?)\"\)` "\n\n=> $1 Image: $2" -}}
{{ $content := $content | replaceRE `\n\n!\[.*]\((.+?)\)` "\n\n=> $1 Embedded Image: $1" -}}
{{ $links := findRE `\n=> ` $content }}{{ $scratch.Set "ref" (add (len $links) 1) }}
{{ $refs := findRE `\[.+?\]\(.+?\)` $content }}
{{ $scratch.Set "content" $content }}{{ range $refs }}{{ $ref := $scratch.Get "ref" }}{{ $contentInLoop := $scratch.Get "content" }}{{ $url := (printf "%s #%d" . $ref) }}{{ $contentInLoop := replace $contentInLoop . $url -}}{{ $scratch.Set "content" $contentInLoop }}{{ $scratch.Set "ref" (add $ref 1) }}{{ end }}{{ $content := $scratch.Get "content" | replaceRE `\[(.+?)\]\((.+?)\) #(\d+)` "$1 [$3]" -}}
{{ $content | safeHTML }}
Explications :
Ce code - qui fait très bien son travail - est un copié-collé du code créé par un certain Wouter Groeneveld ; les explications sont fournies en anglais. N’ayant pas l’utilité de gérer des fichiers audio, vidéo, localement ou sur d’autres plateformes, j’ai simplement supprimé les lignes correspondantes.
Voilà (pour la partie Gemini) !
Il ne reste plus qu’à publier…
Gopher
Attaquons les modifications de configurations et de calques pour générer
les fichiers textes pour Gopher. Là encore, nous générons les fichiers
dans un répertoire dédié, nommé gopher dans le répertoire public/
afin de faciliter la synchronisation vers le serveur gopher…
Configuration pour Gopher
Modifions donc le fichier de configuration de Hugo, pour ajouter les formats de génération. En effet :
- le premier va nous être utile pour la génération des pages, qui porteront le nom index, dans leur propre répertoire
- le second pour générer les fichiers d’indexation gophermap
Tous auront l’extension de fichier .txt
et seront publiés dans un sous-répertoire
nommé gopher du répertoire public/
.
[outputFormats.Gopher]
baseName = "index"
isPlainText = true
isHTML = false
mediaType = "text/plain"
noUgly = false
path = "gopher/"
protocol = "gopher://"
[outputFormats.GopherMap]
baseName = "gophermap"
isPlainText = true
isHTML = false
mediaType = "text/plain"
noUgly = false
path = "gopher/"
protocol = "gopher://"
Puis modifions la génération des sorties, tel que :
[outputs]
home = ["HTML", "gemini", "GeminiRSS", "gophermap", …]
page = ["HTML", "gemini", "gopher"]
Layouts pour Gopher
Attaquons la partie des fichiers à créer dans le sous-répertoire layouts/
.
index.gophermap.txt
Restons simple :
{{ .Site.Title | safeHTML }}
⇒ Menu :
{{ range .Site.Menus.main }}
{{- if (or (eq .Identifier "search") (eq .Identifier "lang-switcher") (eq .Identifier "theme-switcher") ) }}
{{- else }}
1{{ .Name }} {{ .URL | safeURL }} 70
{{- end -}}
{{ end }}
⇒ Articles les plus récents :
{{ $nb := 7 }}
{{ range first $nb .Paginator.Pages }}
0{{ .Title }} {{ with .OutputFormats.Get "gopher" }} {{ replaceRE "/gopher" "" .RelPermalink }} 70 {{ end }}
{{- end }}
Ce fichier gophermap nous permet de publier simplement l’équivalent
du menu principal de Hugo, ainsi que promouvoir les x
derniers
articles. - ici, les 7 derniers -
Pour ceux qui n’auraient pas compris : les fichiers gophermap sont des fichiers d’indexation de contenu…
list.gophermap.txt
Ajoutons dans le répertoire enfant _default/
du sous-répertoire layout/
,
un fichier de génération de liste, qui peut avoir le contenu basique suivant :
!{{ .Title | safeHTML }}
{{ .RawContent }}
{{ range .Paginator.Pages }}
0{{ .Title }} {{ with .OutputFormats.Get "gopher" -}}{{ .RelPermalink }} {{ $.Site.Params.hostname}} 70 {{ end }}
{{ end }}
single.gopher.txt
Pour la génération des pages, ajoutons dans le même sous-répertoire _default/
,
un fichier nommé single.gopher.txt
qui peut avoir le contenu basique suivant :
!{{ .Title | safeHTML }}
{{ .Date.Format (.Site.Params.dateform | default "01 January 2006") }} · {{ .ReadingTime }} minute(s) de lecture.
{{ if .Params.tags }}
Tags : {{ range .Params.tags }}{{ . }} {{ end }}
{{ end }}
---
{{ .RawContent }}
---
Publié le : {{.Date.Format "2 January 2006"}}.
0⇒ Revenir à la page d'accueil : / 70
h⇒ Lire l'article “{{ $.Title | safeHTML }}” sur le protocole HTTP(S) : {{ .Permalink | safeURL }} 443
Le contenu de ce site est diffusé sous Licence {{ $.Site.Copyright | safeHTML }}.
Encore une fois, à vous de modifier à votre convenance et autres imaginations nécessaires pour votre promotion…
Voilà (pour la partie Gopher) !
Il ne reste plus qu’à publier…
Documentations
- le projet Gemini : https://gemini.circumlunar.space/
Wikipedia
Remerciements
- Drew Devault : un des premiers à modifier Hugo pour générer du contenu pour Gemini - voici son dépôt Git pour exemple !
- Sylvain Durant : un parisien qui fait simple et dont je me suis inspiré pour la communauté “OpenBSD Pour Tous” : https://sylvaindurand.org/gemini-and-hugo/
- le dépôt Git de la communauté “OpenBSD Pour Tous”, où vous retrouverez les modifications de génération pour gopher et gemini : https://tildegit.org/obsd4a/www