shithub: hugo

Download patch

ref: 20555b1630765d68c4b6d6c90406483195935faf
parent: 7dd5cd675a4a62bfcd6b64b86b9514d7b9947b64
author: Cathal Garvey <[email protected]>
date: Mon Jul 18 19:14:05 EDT 2016

Add `htmlEscape` and `htmlUnescape` template functions

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.

--- a/docs/content/templates/functions.md
+++ b/docs/content/templates/functions.md
@@ -448,6 +448,27 @@
 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.
--- a/tpl/template_funcs.go
+++ b/tpl/template_funcs.go
@@ -1775,6 +1775,22 @@
 	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 @@
 		"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,
--- a/tpl/template_funcs_test.go
+++ b/tpl/template_funcs_test.go
@@ -93,6 +93,13 @@
 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 <[email protected]>" | safeHTML}}
+htmlEscape 2: {{ htmlEscape "Cathal Garvey & The Sunshine Band <[email protected]>"}}
+htmlUnescape 1: {{htmlUnescape "Cathal Garvey &amp; The Sunshine Band &lt;[email protected]&gt;" | safeHTML}}
+htmlUnescape 2: {{"Cathal Garvey &amp;amp; The Sunshine Band &amp;lt;[email protected]&amp;gt;" | htmlUnescape | htmlUnescape | safeHTML}}
+htmlUnescape 3: {{"Cathal Garvey &amp;amp; The Sunshine Band &amp;lt;[email protected]&amp;gt;" | htmlUnescape | htmlUnescape }}
+htmlUnescape 4: {{ htmlEscape "Cathal Garvey & The Sunshine Band <[email protected]>" | htmlUnescape | safeHTML }}
+htmlUnescape 5: {{ htmlUnescape "Cathal Garvey &amp; The Sunshine Band &lt;[email protected]&gt;" | htmlEscape | safeHTML }}
 humanize 1: {{ humanize "my-first-post" }}
 humanize 2: {{ humanize "myCamelPost" }}
 humanize 3: {{ humanize "52" }}
@@ -149,6 +156,13 @@
 findRE: [go]
 hasPrefix 1: true
 hasPrefix 2: false
+htmlEscape 1: Cathal Garvey &amp; The Sunshine Band &lt;[email protected]&gt;
+htmlEscape 2: Cathal Garvey &amp;amp; The Sunshine Band &amp;lt;[email protected]&amp;gt;
+htmlUnescape 1: Cathal Garvey & The Sunshine Band <[email protected]>
+htmlUnescape 2: Cathal Garvey & The Sunshine Band <[email protected]>
+htmlUnescape 3: Cathal Garvey &amp; The Sunshine Band &lt;[email protected]&gt;
+htmlUnescape 4: Cathal Garvey & The Sunshine Band <[email protected]>
+htmlUnescape 5: Cathal Garvey &amp; The Sunshine Band &lt;[email protected]&gt;
 humanize 1: My first post
 humanize 2: My camel post
 humanize 3: 52nd