Hugo and Gopher
2020-12-16


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 blog[^1] 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:

```toml
[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
docs[^2] 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:

```yaml
...
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