Percent-encoding with the Hugo urlquery
Function
I recently tried to percent-encode (or URL-encode) strings in Hugo.
Percent-encoding is used to encode data in query strings of URLs because they
must only contain ASCII characters. There is a
Hugo built-in querify
function to transform key-value pairs to query strings.
But I required to URL-encode a single string value and not build a query string
from key-value pairs.
My goal is to allow users of the Hugo theme to add social media sharing buttons through the site configuration like this:
[params]
[[params.socialShare]]
formatString = "https://www.facebook.com/sharer.php?u={url}"
[[params.socialShare]]
formatString = "https://reddit.com/submit?url={url}&title={title}"
The formatString
contains {url}
and {title}
placeholders. The following is
a simplified sharing button implementation using the format strings where
placeholders are substituted with page-level variable values during Hugo
build-time:
{{ $href := .formatString }}
{{ $href := replace $href "{url}" .Permalink }}
{{ $href := replace $href "{title}" .Title }}
<a href="{{ $href | safeURL }}">Share Me!</a>
The issue here is that .Permalink
and .Title
must be percent-encoded. As
I’ve searched the web on how to do this with Hugo, I only found unsolved forum
posts:
- About htmlEscape: transform https into https%3A%2F%2F
- URL encoding (percent encoding) with Hugo?
- Is there a url encoder function in Hugo?
I couldn’t believe this was an unsolved mystery and assumed I was just too dumb
to read the docs. Hugo was written in Go, so I looked into how to do
percent-encoding in Go: with the url.QueryEscape()
function from the net/url
package.
Searching the Hugo code base for url.QueryEscape
leads to exactly one result.
It turns out
I discovered an undocumented, built-in Hugo function called urlquery
.
The following:
{{ urlquery "https://schnerring.net" }}
…returns the result: https%3A%2F%2Fschnerring.net
. Here is the fixed version
of the sharing button:
{{ $href := .formatString }}
{{ $href := replace $href "{url}" (urlquery .Permalink) }}
{{ $href := replace $href "{title}" (urlquery .Title) }}
<a href="{{ $href | safeURL }}">Share Me!</a>
The full social sharing button implementation is available on my GitHub.