mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05:00
tpl: Return all errors from casting
Most non-boolean template functions should return errors. Fixes #2354
This commit is contained in:
parent
d3627b1747
commit
5498a1bd56
2 changed files with 100 additions and 36 deletions
|
@ -447,7 +447,10 @@ func findRE(expr string, content interface{}, limit ...int) ([]string, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
conv := cast.ToString(content)
|
||||
conv, err := cast.ToStringE(content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(limit) > 0 {
|
||||
return re.FindAllString(conv, limit[0]), nil
|
||||
}
|
||||
|
@ -1204,12 +1207,15 @@ var markdownTrimPrefix = []byte("<p>")
|
|||
var markdownTrimSuffix = []byte("</p>\n")
|
||||
|
||||
// markdownify renders a given string from Markdown to HTML.
|
||||
func markdownify(in interface{}) template.HTML {
|
||||
text := cast.ToString(in)
|
||||
func markdownify(in interface{}) (template.HTML, error) {
|
||||
text, err := cast.ToStringE(in)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
m := helpers.RenderBytes(&helpers.RenderingContext{Content: []byte(text), PageFmt: "markdown"})
|
||||
m = bytes.TrimPrefix(m, markdownTrimPrefix)
|
||||
m = bytes.TrimSuffix(m, markdownTrimSuffix)
|
||||
return template.HTML(m)
|
||||
return template.HTML(m), nil
|
||||
}
|
||||
|
||||
// jsonify encodes a given object to JSON.
|
||||
|
@ -1219,7 +1225,6 @@ func jsonify(v interface{}) (template.HTML, error) {
|
|||
return "", err
|
||||
}
|
||||
return template.HTML(b), nil
|
||||
|
||||
}
|
||||
|
||||
// emojify "emojifies" the given string.
|
||||
|
@ -1568,14 +1573,20 @@ func readFile(fs *afero.BasePathFs, filename string) (string, error) {
|
|||
// It returns the contents as a string.
|
||||
// There is a upper size limit set at 1 megabytes.
|
||||
func readFileFromWorkingDir(i interface{}) (string, error) {
|
||||
return readFile(hugofs.WorkingDir(), cast.ToString(i))
|
||||
s, err := cast.ToStringE(i)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return readFile(hugofs.WorkingDir(), s)
|
||||
}
|
||||
|
||||
// readDirFromWorkingDir listst the directory content relative to the
|
||||
// configured WorkingDir.
|
||||
func readDirFromWorkingDir(i interface{}) ([]os.FileInfo, error) {
|
||||
|
||||
path := cast.ToString(i)
|
||||
path, err := cast.ToStringE(i)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list, err := afero.ReadDir(hugofs.WorkingDir(), path)
|
||||
|
||||
|
@ -1587,25 +1598,34 @@ func readDirFromWorkingDir(i interface{}) ([]os.FileInfo, error) {
|
|||
}
|
||||
|
||||
// safeHTMLAttr returns a given string as html/template HTMLAttr content.
|
||||
func safeHTMLAttr(a interface{}) template.HTMLAttr {
|
||||
return template.HTMLAttr(cast.ToString(a))
|
||||
func safeHTMLAttr(a interface{}) (template.HTMLAttr, error) {
|
||||
s, err := cast.ToStringE(a)
|
||||
return template.HTMLAttr(s), err
|
||||
}
|
||||
|
||||
// safeCSS returns a given string as html/template CSS content.
|
||||
func safeCSS(a interface{}) template.CSS {
|
||||
return template.CSS(cast.ToString(a))
|
||||
func safeCSS(a interface{}) (template.CSS, error) {
|
||||
s, err := cast.ToStringE(a)
|
||||
return template.CSS(s), err
|
||||
}
|
||||
|
||||
// safeURL returns a given string as html/template URL content.
|
||||
func safeURL(a interface{}) template.URL {
|
||||
return template.URL(cast.ToString(a))
|
||||
func safeURL(a interface{}) (template.URL, error) {
|
||||
s, err := cast.ToStringE(a)
|
||||
return template.URL(s), err
|
||||
}
|
||||
|
||||
// safeHTML returns a given string as html/template HTML content.
|
||||
func safeHTML(a interface{}) template.HTML { return template.HTML(cast.ToString(a)) }
|
||||
func safeHTML(a interface{}) (template.HTML, error) {
|
||||
s, err := cast.ToStringE(a)
|
||||
return template.HTML(s), err
|
||||
}
|
||||
|
||||
// safeJS returns the given string as a html/template JS content.
|
||||
func safeJS(a interface{}) template.JS { return template.JS(cast.ToString(a)) }
|
||||
func safeJS(a interface{}) (template.JS, error) {
|
||||
s, err := cast.ToStringE(a)
|
||||
return template.JS(s), err
|
||||
}
|
||||
|
||||
// mod returns a % b.
|
||||
func mod(a, b interface{}) (int64, error) {
|
||||
|
@ -1801,9 +1821,25 @@ func htmlUnescape(in interface{}) (string, error) {
|
|||
return html.UnescapeString(conv), nil
|
||||
}
|
||||
|
||||
func absURL(a interface{}) (template.HTML, error) {
|
||||
s, err := cast.ToStringE(a)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
return template.HTML(helpers.AbsURL(s)), nil
|
||||
}
|
||||
|
||||
func relURL(a interface{}) (template.HTML, error) {
|
||||
s, err := cast.ToStringE(a)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
return template.HTML(helpers.RelURL(s)), nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
funcMap = template.FuncMap{
|
||||
"absURL": func(a interface{}) template.HTML { return template.HTML(helpers.AbsURL(cast.ToString(a))) },
|
||||
"absURL": absURL,
|
||||
"add": func(a, b interface{}) (interface{}, error) { return helpers.DoArithmetic(a, b, '+') },
|
||||
"after": after,
|
||||
"apply": apply,
|
||||
|
@ -1834,7 +1870,7 @@ func init() {
|
|||
"humanize": humanize,
|
||||
"in": in,
|
||||
"index": index,
|
||||
"int": func(v interface{}) int { return cast.ToInt(v) },
|
||||
"int": func(v interface{}) (int, error) { return cast.ToIntE(v) },
|
||||
"intersect": intersect,
|
||||
"isSet": isSet,
|
||||
"isset": isSet,
|
||||
|
@ -1856,7 +1892,7 @@ func init() {
|
|||
"readDir": readDirFromWorkingDir,
|
||||
"readFile": readFileFromWorkingDir,
|
||||
"ref": ref,
|
||||
"relURL": func(a interface{}) template.HTML { return template.HTML(helpers.RelURL(cast.ToString(a))) },
|
||||
"relURL": relURL,
|
||||
"relref": relRef,
|
||||
"replace": replace,
|
||||
"replaceRE": replaceRE,
|
||||
|
@ -1875,7 +1911,7 @@ func init() {
|
|||
"slicestr": slicestr,
|
||||
"sort": sortSeq,
|
||||
"split": split,
|
||||
"string": func(v interface{}) string { return cast.ToString(v) },
|
||||
"string": func(v interface{}) (string, error) { return cast.ToStringE(v) },
|
||||
"sub": func(a, b interface{}) (interface{}, error) { return helpers.DoArithmetic(a, b, '-') },
|
||||
"substr": substr,
|
||||
"title": func(a string) string { return strings.Title(a) },
|
||||
|
|
|
@ -1740,7 +1740,10 @@ func TestMarkdownify(t *testing.T) {
|
|||
{"Hello **World!**", template.HTML("Hello <strong>World!</strong>")},
|
||||
{[]byte("Hello Bytes **World!**"), template.HTML("Hello Bytes <strong>World!</strong>")},
|
||||
} {
|
||||
result := markdownify(this.in)
|
||||
result, err := markdownify(this.in)
|
||||
if err != nil {
|
||||
t.Fatalf("[%d] unexpected error in markdownify", i, err)
|
||||
}
|
||||
if !reflect.DeepEqual(result, this.expect) {
|
||||
t.Errorf("[%d] markdownify got %v (type %v) but expected %v (type %v)", i, result, reflect.TypeOf(result), this.expect, reflect.TypeOf(this.expect))
|
||||
}
|
||||
|
@ -2127,12 +2130,17 @@ func TestSafeHTML(t *testing.T) {
|
|||
}
|
||||
|
||||
buf.Reset()
|
||||
err = tmpl.Execute(buf, safeHTML(this.str))
|
||||
v, err := safeHTML(this.str)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] execute template with an escaped string value by SafeHTML returns unexpected error: %s", i, err)
|
||||
t.Fatalf("[%d] unexpected error in safeHTML: %s", i, err)
|
||||
}
|
||||
|
||||
err = tmpl.Execute(buf, v)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] execute template with an escaped string value by safeHTML returns unexpected error: %s", i, err)
|
||||
}
|
||||
if buf.String() != this.expectWithEscape {
|
||||
t.Errorf("[%d] execute template with an escaped string value by SafeHTML, got %v but expected %v", i, buf.String(), this.expectWithEscape)
|
||||
t.Errorf("[%d] execute template with an escaped string value by safeHTML, got %v but expected %v", i, buf.String(), this.expectWithEscape)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2162,12 +2170,17 @@ func TestSafeHTMLAttr(t *testing.T) {
|
|||
}
|
||||
|
||||
buf.Reset()
|
||||
err = tmpl.Execute(buf, safeHTMLAttr(this.str))
|
||||
v, err := safeHTMLAttr(this.str)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] execute template with an escaped string value by SafeHTMLAttr returns unexpected error: %s", i, err)
|
||||
t.Fatalf("[%d] unexpected error in safeHTMLAttr: %s", i, err)
|
||||
}
|
||||
|
||||
err = tmpl.Execute(buf, v)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] execute template with an escaped string value by safeHTMLAttr returns unexpected error: %s", i, err)
|
||||
}
|
||||
if buf.String() != this.expectWithEscape {
|
||||
t.Errorf("[%d] execute template with an escaped string value by SafeHTMLAttr, got %v but expected %v", i, buf.String(), this.expectWithEscape)
|
||||
t.Errorf("[%d] execute template with an escaped string value by safeHTMLAttr, got %v but expected %v", i, buf.String(), this.expectWithEscape)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2197,12 +2210,17 @@ func TestSafeCSS(t *testing.T) {
|
|||
}
|
||||
|
||||
buf.Reset()
|
||||
err = tmpl.Execute(buf, safeCSS(this.str))
|
||||
v, err := safeCSS(this.str)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] execute template with an escaped string value by SafeCSS returns unexpected error: %s", i, err)
|
||||
t.Fatalf("[%d] unexpected error in safeCSS: %s", i, err)
|
||||
}
|
||||
|
||||
err = tmpl.Execute(buf, v)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] execute template with an escaped string value by safeCSS returns unexpected error: %s", i, err)
|
||||
}
|
||||
if buf.String() != this.expectWithEscape {
|
||||
t.Errorf("[%d] execute template with an escaped string value by SafeCSS, got %v but expected %v", i, buf.String(), this.expectWithEscape)
|
||||
t.Errorf("[%d] execute template with an escaped string value by safeCSS, got %v but expected %v", i, buf.String(), this.expectWithEscape)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2232,12 +2250,17 @@ func TestSafeJS(t *testing.T) {
|
|||
}
|
||||
|
||||
buf.Reset()
|
||||
err = tmpl.Execute(buf, safeJS(this.str))
|
||||
v, err := safeJS(this.str)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] execute template with an escaped string value by SafeJS returns unexpected error: %s", i, err)
|
||||
t.Fatalf("[%d] unexpected error in safeJS: %s", i, err)
|
||||
}
|
||||
|
||||
err = tmpl.Execute(buf, v)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] execute template with an escaped string value by safeJS returns unexpected error: %s", i, err)
|
||||
}
|
||||
if buf.String() != this.expectWithEscape {
|
||||
t.Errorf("[%d] execute template with an escaped string value by SafeJS, got %v but expected %v", i, buf.String(), this.expectWithEscape)
|
||||
t.Errorf("[%d] execute template with an escaped string value by safeJS, got %v but expected %v", i, buf.String(), this.expectWithEscape)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2267,12 +2290,17 @@ func TestSafeURL(t *testing.T) {
|
|||
}
|
||||
|
||||
buf.Reset()
|
||||
err = tmpl.Execute(buf, safeURL(this.str))
|
||||
v, err := safeURL(this.str)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] execute template with an escaped string value by SafeURL returns unexpected error: %s", i, err)
|
||||
t.Fatalf("[%d] unexpected error in safeURL: %s", i, err)
|
||||
}
|
||||
|
||||
err = tmpl.Execute(buf, v)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] execute template with an escaped string value by safeURL returns unexpected error: %s", i, err)
|
||||
}
|
||||
if buf.String() != this.expectWithEscape {
|
||||
t.Errorf("[%d] execute template with an escaped string value by SafeURL, got %v but expected %v", i, buf.String(), this.expectWithEscape)
|
||||
t.Errorf("[%d] execute template with an escaped string value by safeURL, got %v but expected %v", i, buf.String(), this.expectWithEscape)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue