How to unescape plus sign in URL? (Re Cloudflare Fonts)

The new Cloudflare Fonts service, now available but still in what appears to be an especially glitchy beta condition, “de-Googles” Google Fonts — i.e., serves Google Fonts without the privacy-violating code and shortens the delivery process from eight hops to one. The thing is, you have to supply HTML that looks like this if the font name is longer than one word (e.g., Noto Sans Display):

<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Display:ital,wght@0,100..900;1,100..900&amp;display=swap" rel="stylesheet">

… and, so far, I cannot successfully deliver that + in the URL if providing the URL programmatically in Hugo (an example of that appears below), as I am doing now for test purposes. Instead, each + ends up escaped to &43#;. I have tried running the URL through all the usual unescaping/safing filters mentioned in the Hugo docs, as well as some printf permutations, but so far none allows that plus sign to come through the process unescaped. What am I missing?

Programmatic example

This uses a content page’s front matter to distinguish a font’s “Google Fonts name” (requiring the plus sign if the name is multi-word) from its actual name.

---
title: "CFF001"
GF1name: "Noto+Sans+Display"
GF1font: "Noto Sans Display"
GF1wttop: 100
GF1wtbtm: 900
GF2name: "Noto+Serif"
GF2font: "Noto Serif"
GF2wttop: 100
GF2wtbtm: 900
---
{{- $URLGF1 := "" -}}
{{- $URLGF2 := "" -}}
{{- with $.Page.Params.GF1name -}}
	{{- $GF1name := $.Page.Params.GF1name -}}
	{{- $GF1wttop := $.Page.Params.GF1wttop -}}
	{{- $GF1wtbtm := $.Page.Params.GF1wtbtm -}}
	{{- $GF1italweight := ":ital,wght@" -}}
	{{- $optFirstGF1 := "0," -}}
	{{- $optSecondGF1 := "1," -}}
	{{- $URLGF1 = print $URLopen $GF1name $GF1italweight $optFirstGF1 $GF1wttop ".." $GF1wtbtm ";" $optSecondGF1 $GF1wttop ".." $GF1wtbtm "&display=swap" -}}
	<style type="text/css">
		.gf1 {
			font-family: "{{ $.Page.Params.GF1font }}", sans-serif;
		}
	</style>
{{- end }}
<!-- not showing similar code to get $URLGF2 -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
{{ if ne $URLGF1 "" -}}
	<link href="{{ $URLGF1 }}" rel="stylesheet">
{{- end }}

Try

Have tried that at multiple levels — i.e., with the original $GF1name by itself as well as the finished $URLGF1, and a few other things in between — but it still results in, e.g.:

<link href="https://fonts.googleapis.com/css2?family=Noto&#43;Sans&#43;Display:ital,wght@0,100..900;1,100..900&amp;display=swap" rel="stylesheet">

Hard to debug … remotely, but have you tried to add e.g. $foo | safeHTML; I suspect this is the case of the unescape being reversed, so to speak.

1 Like

Yep, tried that, too. For example, this still produces the same escaped result:

	{{- $GF1name := htmlUnescape $.Page.Params.GF1name -}}
...
	<link href="{{ $URLGF1 | safeHTML }}" rel="stylesheet">

. . . but I appreciate the help! I may just have to abandon the programmatic approach here as not worth the effort for a small test. I can feed the desired URL manually and it works fine, so it’s just a Go thing, I guess.

You want safeHTMLAttr, which you need to apply to the key/val pair, not just the val.

{{ $u := "https://example.org?a=b+c" }}
<a {{ printf "href=%s" $u | safeHTMLAttr }}>foo</a>
2 Likes

Thanks! In this particular case (link rather than a), it ended up as:

<link {{ printf "href=%s" $URLGF1 | safeHTMLAttr }} rel="stylesheet">

Why is the value of the href attribute unquoted (%s instead of %q)?

2 Likes

Ah, good catch (and one the solution to which I would’ve pondered after a while, maybe). Resolved:

<link {{ printf "href=%q" $URLGF1 | safeHTMLAttr }} rel="stylesheet">

…which produces, in the case of Noto Sans Display:

<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Display:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">

:+1:

2 Likes

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.