aboutsummaryrefslogtreecommitdiffstats
path: root/modules/templates
diff options
context:
space:
mode:
Diffstat (limited to 'modules/templates')
-rw-r--r--modules/templates/helper.go31
-rw-r--r--modules/templates/helper_test.go15
2 files changed, 44 insertions, 2 deletions
diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index 94464fe628..8779de69ca 100644
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -9,6 +9,7 @@ import (
"html"
"html/template"
"net/url"
+ "reflect"
"slices"
"strings"
"time"
@@ -237,8 +238,8 @@ func DotEscape(raw string) string {
// Iif is an "inline-if", similar util.Iif[T] but templates need the non-generic version,
// and it could be simply used as "{{Iif expr trueVal}}" (omit the falseVal).
-func Iif(condition bool, vals ...any) any {
- if condition {
+func Iif(condition any, vals ...any) any {
+ if IsTruthy(condition) {
return vals[0]
} else if len(vals) > 1 {
return vals[1]
@@ -246,6 +247,32 @@ func Iif(condition bool, vals ...any) any {
return nil
}
+func IsTruthy(v any) bool {
+ if v == nil {
+ return false
+ }
+
+ rv := reflect.ValueOf(v)
+ switch rv.Kind() {
+ case reflect.Bool:
+ return rv.Bool()
+ case reflect.String:
+ return rv.String() != ""
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return rv.Int() != 0
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return rv.Uint() != 0
+ case reflect.Float32, reflect.Float64:
+ return rv.Float() != 0
+ case reflect.Slice, reflect.Array, reflect.Map:
+ return rv.Len() > 0
+ case reflect.Ptr:
+ return !rv.IsNil() && IsTruthy(reflect.Indirect(rv).Interface())
+ default:
+ return rv.Kind() == reflect.Struct && !rv.IsNil()
+ }
+}
+
// Eval the expression and return the result, see the comment of eval.Expr for details.
// To use this helper function in templates, pass each token as a separate parameter.
//
diff --git a/modules/templates/helper_test.go b/modules/templates/helper_test.go
index 0cefb7a6b2..c6c70cc18e 100644
--- a/modules/templates/helper_test.go
+++ b/modules/templates/helper_test.go
@@ -65,3 +65,18 @@ func TestHTMLFormat(t *testing.T) {
func TestSanitizeHTML(t *testing.T) {
assert.Equal(t, template.HTML(`<a href="/" rel="nofollow">link</a> xss <div>inline</div>`), SanitizeHTML(`<a href="/">link</a> <a href="javascript:">xss</a> <div style="dangerous">inline</div>`))
}
+
+func TestIsTruthy(t *testing.T) {
+ var test any
+ assert.Equal(t, false, IsTruthy(test))
+ assert.Equal(t, false, IsTruthy(nil))
+ assert.Equal(t, false, IsTruthy(""))
+ assert.Equal(t, true, IsTruthy("non-empty"))
+ assert.Equal(t, true, IsTruthy(-1))
+ assert.Equal(t, false, IsTruthy(0))
+ assert.Equal(t, true, IsTruthy(42))
+ assert.Equal(t, false, IsTruthy(0.0))
+ assert.Equal(t, true, IsTruthy(3.14))
+ assert.Equal(t, false, IsTruthy([]int{}))
+ assert.Equal(t, true, IsTruthy([]int{1}))
+}