The .Files

Hugo and Gopher

I’ve rediscovered gopher thanks to the tildeverse and figured I would give it a shot, once I was done setting up the web side of things. Well, the time has come and here I am, all ready to go.

However, I’m not too crazy about the idea of having to maintain two (or more) separate sets of content depending on the protocol. I’m pretty spread out as it is already.
So I started looking around for a way to generate gopher content from my preexisting Hugo markdown files. I didn’t have to search long, fortunately.

JFM’s blog1 details a very simple way of getting it all together, and after some tweaking, I came up with a perfectly working solution.

The first part

Edit Hugo’s config.toml file and add the following lines:

[outputs]
  section = ["HTML", "gopher"]
  page = ["HTML", "gopher"]

[outputFormats.gopher]
  mediaType = "text/plain"
  path = "/~me/phlog"
  baseName = "gophermap"
  protocol = "gopher://"
  isPlainText = true

[outputFormats.HTML]
  noUgly = true

The content of your [outputs] section might vary depending on your needs, naturally, but this is the bare minimum required to get your posts converted.

The meat of the issue is the [outputFormats.gopher] section. As per the Hugo docs2 we specify the required options to have the files be plaintext.
Generally path isn’t needed, but I wanted to have my blog (phlog, actually) be in a subdirectory. This will come into play during the deployment later.

I placed these additions at the bottom of my config file, then added uglyuRLs = true near the top. This option together with the [outputFormats.HTML] section provides clean permalinks for plaintext files while preserving the nice folder-like structure for web output.

The second part

Create the required layouts for the gophermap and phlog posts under layouts/_default.

layouts/_default/list.gopher.txt

1Go back	/me

{{ range .Pages.ByPublishDate.Reverse }}
0{{ .Date.Format "2006-01-02" }} {{ .Title }}	{{ with .OutputFormats.Get "gopher" -}} {{ .RelPermalink }}{{ end }}
{{ end }}

layouts/_default/single.gopher.txt

{{ .Title }}
{{ .Date.Format "2006-01-02" }}

{{ .RawContent }}

However, if you use manual summaries, replace {{ .RawContent }} with the following:

{{ $content := .RawContent -}}
{{ $content := $content | replaceRE "(?s:< !--more-- >)" "" -}}
{{ $content }}

This will remove the summary tag. Note that I had to include spaces in there to prevent Hugo from actually picking up the --more-- tag, so please make sure there’s no space in between the angle brackets and the rest of the tag.
I feel like this is a bug I should report…

The third part

Bring it all together in Drone’s pipeline. I added the following to the .drone.yml from my previous post:

...
steps:
  - name: deploy
    commands:
      (previous commands here)
      - cp -ruf /home/me/public_html/posts/~me/phlog.txt /home/me/public_gopher/phlog/gophermap
      - cp -ruf /home/me/public_html/~me/phlog/posts/*.txt /home/dgy/public_gopher/phlog/posts

The directory paths are a bit unwieldy and took some trial and error to get right, but I now have a “main” gophermap in public_gopher with a number of links and info about myself and the phlog in its own subdirectory.


  1. https://jfm.carcosa.net/blog/computing/hugo-gopher/ ↩︎

  2. https://gohugo.io/templates/output-formats#configure-output-formats ↩︎