Files
davideisinger.com/static/archive/sylvaindurand-org-jylksq.txt
2025-03-04 01:32:25 -05:00

171 lines
4.6 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
[1]sylvain durand
Gemini and Hugo
2020-12-04
For a few years, I have been using Hugo, a static site generator, to produce
these pages. At the same time very fast and corresponding perfectly to my
needs, it is above all very modular.
I was therefore not surprised to see that it was quite easy to convert, with
little effort, my site for the Gemini protocol. This was not done without some
tricks. Lets see how!
Declaring Gemini as an output format
Hugo can output content in multiple formats: most of them are already
predefined, but it is also possible to create your own. This is what we are
going to do for Gemini.
First, in the configuration file config.yml we will declare a new type text/
gemini with the file suffix .gmi:
mediaTypes:
text/gemini:
suffixes:
- "gmi"
Once this is done, we declare a new output format, which uses this type, which
is given the name GEMINI.
outputFormats:
GEMINI:
name: GEMINI
isPlainText: true
isHTML: false
mediaType: text/gemini
protocol: "gemini://"
permalinkable: true
Finally, it only remains to ask Hugo to generate pages for the different
contents. For example, in my case:
outputs:
home: ["HTML", "RSS", "GEMINI"]
page: ["HTML", "GEMINI"]
To be able to generate the files, it is now necessary to create layouts to see
how to display them!
Index page
To start with the index, we can start with layout/index.gmi. For example, here
is a simple text, followed by a list of posts:
## List of posts
{{ range .RegularPages }}
=> {{ .RelPermalink }} {{ .Title }}
{{- end }}
Here, I sort the articles in descending chronological order, grouping them by
date. This gives the following code:
## Posts grouped by year
{{ range .RegularPages.GroupByDate "2006" }}
### {{ .Key }}
{{ range .Pages.ByDate.Reverse }}
=> {{ .RelPermalink }} {{ .Title }}
{{- end }}
{{ end }}
Posts
For posts, we can create a layout/_default/single.gmi. Basically, it would
suffice to display the title and content:
# {{ .Title }}
{{ .RawContent }}
Images
For images, I extract them with a simple regex and show them as a link:
{{- $content := .RawContent -}}
{{- $content = $content | replaceRE `\!\[(.+?)\]\((.+?)\)` "=> $2 Image: $1" }}
{{ $content }}
Links
For the links, I decided to simply not use inline links on the site, but only
put the links on a single paragraph. This allows me, as before, a very simple
regex:
{{- range findRE `\[.+?\]\(.+?\)` $content }}
{{- $content = $content | replaceRE `\[(.+?)\]\((.+?)\)(.+)` "$1$3\n\n=> $2 $1 " }}
{{- end }}
However, this is not a very satisfactory method when you have a site that has a
lot of links online. A solution, proposed by the site Brain Baking, allows you
to reference each link with a number ([1], [2]…) and then to put the links
underneath, automatically, thanks to a clever code from [2]Brainbaking.
Navigation to other pages
If you want to add links for previous and next articles with:
{{ if .Next }}=> {{ .Next.RelPermalink }} ← Newer: {{ .Next.Title }}{{ end }}
{{ if .Prev -}}=> {{ .Prev.RelPermalink }} → Older: {{ .Prev.Title }}{{- end }}
Feeds
To create RSS feeds, we can create a new output format, then define its layout.
RSS
We will do the same here! In config.yml, we define:
outputFormats:
GEMINI_RSS:
baseName: "feed"
mediaType: "application/rss+xml"
isPlainText: false
outputs:
home: ["HTML", "GEMINI", ..., "GEMINI_RSS"]
Then, we create layouts/index.gemini_rss.xml with the following content:
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>{{ .Site.Title }}</title>
<description>{{ i18n "description" }}</description>
<link>{{ (replace .Permalink "https://" "gemini://") | safeURL }}</link>
<atom:link href="{{ .Permalink | safeURL }}feed.xml" rel="self" type="application/rss+xml" />
{{- range .RegularPages }}
<item>
<title>{{ .Title }}</title>
<link>{{ (replace .Permalink "https://" "gemini://") | safeURL }}</link>
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
<guid>{{ (replace .Permalink "https://" "gemini://") | safeURL }}</guid>
</item>
{{ end }}
</channel>
</rss>
The RSS feed is now available on /feed.xml.
Export
I use rsync to easily export my files to the server:
hugo
rsync -avz --no-perms --no-owner --no-group \
--no-times --delete public/ vps:/var/gemini
rm -rf public
This last folder is then read by a gemini server, as explained in the previous
article “[3]Discovering the Gemini protocol”.
References:
[1] https://sylvaindurand.org/
[2] https://brainbaking.com/post/2021/04/using-hugo-to-launch-a-gemini-capsule/
[3] https://sylvaindurand.org/discovering-the-gemini-protocol/