Add `htmlEscape` and `htmlUnescape` template functions
authorCathal Garvey <cathalgarvey@cathalgarvey.me>
Mon, 18 Jul 2016 22:14:05 +0000 (23:14 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 18 Jul 2016 22:14:05 +0000 (00:14 +0200)
These functions allow trivial escaping and unescaping of HTML entities,
and make it far easier to compose other functions for the creation of
parameterised URLs.

docs/content/templates/functions.md
tpl/template_funcs.go
tpl/template_funcs_test.go

index 6ba0a8963345084ee5a7a4643e3f66f45c163aec..9f4499388f3368b4305b02585e3405899408eb54 100644 (file)
@@ -448,6 +448,27 @@ e.g. `{{ "I :heart: Hugo" | emojify }}`
 Takes a string of code and a language, uses Pygments to return the syntax highlighted code in HTML.
 Used in the [highlight shortcode](/extras/highlighting/).
 
+### htmlEscape
+HtmlEscape returns the given string with the critical reserved HTML codes escaped,
+such that `&` becomes `&amp;` and so on. It escapes only: `<`, `>`, `&`, `'` and `"`.
+
+Bear in mind that, unless content is passed to `safeHTML`, output strings are escaped
+usually by the processor anyway.
+
+e.g.
+`{{ htmlEscape "Hugo & Caddy > Wordpress & Apache" }} → "Hugo &amp; Caddy &gt; Wordpress &amp; Apache"`
+
+### htmlUnescape
+HtmlUnescape returns the given string with html escape codes un-escaped. This
+un-escapes more codes than `htmlEscape` escapes, including `#` codes and pre-UTF8
+escapes for accented characters. It defers completely to the Go `html.UnescapeString`
+function, so functionality is consistent with that codebase.
+
+Remember to pass the output of this to `safeHTML` if fully unescaped characters
+are desired, or the output will be escaped again as normal.
+
+e.g.
+`{{ htmlUnescape "Hugo &amp; Caddy &gt; Wordpress &amp; Apache" }} → "Hugo & Caddy > Wordpress & Apache"`
 
 ### humanize
 Humanize returns the humanized version of an argument with the first letter capitalized.
index c12218468137e185520b223a3d9dc30ab85d0310..b04b3681012d219d1f3ce0a52c7dd624b044408b 100644 (file)
@@ -1775,6 +1775,22 @@ func querify(params ...interface{}) (string, error) {
        return qs.Encode(), nil
 }
 
+func htmlEscape(in interface{}) (string, error) {
+       conv, err := cast.ToStringE(in)
+       if err != nil {
+               return "", err
+       }
+       return html.EscapeString(conv), nil
+}
+
+func htmlUnescape(in interface{}) (string, error) {
+       conv, err := cast.ToStringE(in)
+       if err != nil {
+               return "", err
+       }
+       return html.UnescapeString(conv), nil
+}
+
 func init() {
        funcMap = template.FuncMap{
                "absURL":       func(a string) template.HTML { return template.HTML(helpers.AbsURL(a)) },
@@ -1803,6 +1819,8 @@ func init() {
                "gt":           gt,
                "hasPrefix":    func(a, b string) bool { return strings.HasPrefix(a, b) },
                "highlight":    highlight,
+               "htmlEscape":   htmlEscape,
+               "htmlUnescape": htmlUnescape,
                "humanize":     humanize,
                "in":           in,
                "index":        index,
index eeffd46bde0c4cc09ad2d38931ae938b07a6e821..2d8f753bd9884cebaa1aa7012e565897458816aa 100644 (file)
@@ -93,6 +93,13 @@ eq: {{ if eq .Section "blog" }}current{{ end }}
 findRE: {{ findRE "[G|g]o" "Hugo is a static side generator written in Go." 1 }}
 hasPrefix 1: {{ hasPrefix "Hugo" "Hu" }}
 hasPrefix 2: {{ hasPrefix "Hugo" "Fu" }}
+htmlEscape 1: {{ htmlEscape "Cathal Garvey & The Sunshine Band <cathal@foo.bar>" | safeHTML}}
+htmlEscape 2: {{ htmlEscape "Cathal Garvey & The Sunshine Band <cathal@foo.bar>"}}
+htmlUnescape 1: {{htmlUnescape "Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;" | safeHTML}}
+htmlUnescape 2: {{"Cathal Garvey &amp;amp; The Sunshine Band &amp;lt;cathal@foo.bar&amp;gt;" | htmlUnescape | htmlUnescape | safeHTML}}
+htmlUnescape 3: {{"Cathal Garvey &amp;amp; The Sunshine Band &amp;lt;cathal@foo.bar&amp;gt;" | htmlUnescape | htmlUnescape }}
+htmlUnescape 4: {{ htmlEscape "Cathal Garvey & The Sunshine Band <cathal@foo.bar>" | htmlUnescape | safeHTML }}
+htmlUnescape 5: {{ htmlUnescape "Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;" | htmlEscape | safeHTML }}
 humanize 1: {{ humanize "my-first-post" }}
 humanize 2: {{ humanize "myCamelPost" }}
 humanize 3: {{ humanize "52" }}
@@ -149,6 +156,13 @@ eq: current
 findRE: [go]
 hasPrefix 1: true
 hasPrefix 2: false
+htmlEscape 1: Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;
+htmlEscape 2: Cathal Garvey &amp;amp; The Sunshine Band &amp;lt;cathal@foo.bar&amp;gt;
+htmlUnescape 1: Cathal Garvey & The Sunshine Band <cathal@foo.bar>
+htmlUnescape 2: Cathal Garvey & The Sunshine Band <cathal@foo.bar>
+htmlUnescape 3: Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;
+htmlUnescape 4: Cathal Garvey & The Sunshine Band <cathal@foo.bar>
+htmlUnescape 5: Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;
 humanize 1: My first post
 humanize 2: My camel post
 humanize 3: 52nd