Add base64Decode and base64Encode template functions

Fixes #1416
This commit is contained in:
digitalcraftsman 2015-09-12 21:45:12 +02:00 committed by Bjørn Erik Pedersen
parent a1e32439fb
commit 79f8bb625d
3 changed files with 145 additions and 53 deletions

View file

@ -650,3 +650,33 @@ In this version, we are now sorting the tags, converting them to links with "pos
{{ end }}
`apply` does not work when receiving the sequence as an argument through a pipeline.
***
### base64Encode and base64Decode
`base64Encode` and `base64Decode` let you easily decode content with a base64 enconding and vice versa through pipes. Let's take a look at an example:
{{ "Hello world" | base64Encode }}
<!-- will output "SGVsbG8gd29ybGQ=" and -->
{{ "SGVsbG8gd29ybGQ=" | base64Decode }}
<!-- becomes "Hello world" again. -->
You can also pass other datatypes as argument to the template function which tries
to convert them. Now we use an integer instead of a string:
{{ 42 | base64Encode | base64Decode }}
<!-- will output "42". Both functions always return a string. -->
**Tip:** Using base64 to decode and encode becomes really powerful if we have to handle
responses of APIs.
{{ $resp := getJSON "https://api.github.com/repos/spf13/hugo/readme" }}
{{ $resp.content | base64Decode | markdownify }}
The response of the Github API contains the base64-encoded version of the [README.md](https://github.com/spf13/hugo/blob/master/README.md) in the Hugo repository.
Now we can decode it and parse the Markdown. The final output will look similar to the
rendered version in Github.

View file

@ -16,6 +16,7 @@ package tpl
import (
"bitbucket.org/pkg/inflect"
"bytes"
"encoding/base64"
"errors"
"fmt"
"html"
@ -1318,6 +1319,32 @@ func ModBool(a, b interface{}) (bool, error) {
return res == int64(0), nil
}
func Base64Decode(content interface{}) (string, error) {
conv, err := cast.ToStringE(content)
if err != nil {
return "", err
}
dec, err := base64.StdEncoding.DecodeString(conv)
if err != nil {
return "", err
}
return string(dec), nil
}
func Base64Encode(content interface{}) (string, error) {
conv, err := cast.ToStringE(content)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString([]byte(conv)), nil
}
func init() {
funcMap = template.FuncMap{
"urlize": helpers.URLize,
@ -1372,6 +1399,8 @@ func init() {
"readDir": ReadDir,
"seq": helpers.Seq,
"getenv": func(varName string) string { return os.Getenv(varName) },
"base64Decode": Base64Decode,
"base64Encode": Base64Encode,
"pluralize": func(in interface{}) (string, error) {
word, err := cast.ToStringE(in)
if err != nil {
@ -1387,5 +1416,4 @@ func init() {
return inflect.Singularize(word), nil
},
}
}

View file

@ -2,6 +2,7 @@ package tpl
import (
"bytes"
"encoding/base64"
"errors"
"fmt"
"html/template"
@ -1581,3 +1582,36 @@ func TestSafeURL(t *testing.T) {
}
}
}
func TestBase64Decode(t *testing.T) {
testStr := "abc123!?$*&()'-=@~"
enc := base64.StdEncoding.EncodeToString([]byte(testStr))
result, err := Base64Decode(enc)
if err != nil {
t.Error("Base64Decode:", err)
}
if result != testStr {
t.Errorf("Base64Decode: got '%s', expected '%s'", result, testStr)
}
}
func TestBase64Encode(t *testing.T) {
testStr := "YWJjMTIzIT8kKiYoKSctPUB+"
dec, err := base64.StdEncoding.DecodeString(testStr)
if err != nil {
t.Error("Base64Encode: the DecodeString function of the base64 package returned an error.", err)
}
result, err := Base64Encode(string(dec))
if err != nil {
t.Errorf("Base64Encode: Can't cast arg '%s' into a string.", testStr)
}
if result != testStr {
t.Errorf("Base64Encode: got '%s', expected '%s'", result, testStr)
}
}