Using html/template
to create JSON output. Code snippet is as follows (playground):
package main
import (
"bytes"
"encoding/json"
"fmt"
"html/template"
)
const tpl = `
{
"key": "{{- .Value -}}" // Replace with js .Value to get another error
}
`
func main() {
t, err := template.New("").Parse(tpl)
if err != nil {
panic(err)
}
var buf bytes.Buffer
err = t.Execute(&buf, struct{
Value string
}{"Test\\ > \\ Value"})
if err != nil {
panic(err)
}
data := make(map[string]string)
err = json.Unmarshal(buf.Bytes(), &data)
if err != nil {
panic(err)
}
fmt.Printf("%v
", data)
}
If I try to insert .Value
as is - then I get the following error:
panic: invalid character ' ' in string escape code
This is because \\
becomes \
and \ + space
is incorrect escaping in JSON. I can fix this by adding js
function to template:
const tpl = `
{
"key": "{{- js .Value -}}"
}
`
In that case it fails with another error:
panic: invalid character 'x' in string escape code
This is because js
function converts >
sign to \x3c
and \x
is incorrect escaping in JSON.
Any ideas how to get a universal function that correctly escapes strings for JSON? Is there an alternative way (e.g. an external library) to create JSON templates considering all these difficulties?
https://play.golang.org/p/4DMTAfEapbM
As @Adrian
suggested, using text/template
, so we do need just one unescape
and the end.
https://play.golang.org/p/oPC1E6s-EwB
Enscape before excute template, then unenscape twice when you want the string value.
https://play.golang.org/p/zD-cTO07GZq
Replace "\\
" with "\\\\
".
}{"Test\\ > \\ Value"})
to
}{"Test\\\\ > \\\\ Value"})
"// " comment is not supported in json
.