## General
 
+### default
+Checks whether a given value is set and returns a default value if it is not.
+"Set" in this context means true for booleans; non-zero for numeric types;
+non-zero length for strings, arrays, slices, and maps; any struct value; or
+non-nil for any other types.
+
+e.g.
+
+    {{ .Params.font | default "Roboto" }} → default is "Roboto"
+    {{ default "Roboto" .Params.font }} → default is "Roboto"
+
 ### delimit
 Loops through any array, slice or map and returns a string of all the values separated by the delimiter. There is an optional third parameter that lets you choose a different delimiter to go between the last two values.
 Maps will be sorted by the keys, and only a slice of the values will be returned, keeping a consistent output order.
 
        return t.Format(layout), nil
 }
 
+// dfault checks whether a given value is set and returns a default value if it
+// is not.  "Set" in this context means true for booleans; non-zero for numeric
+// types; non-zero length for strings, arrays, slices, and maps; any struct
+// value; or non-nil for any other types.
+func dfault(dflt, given interface{}) interface{} {
+       g := reflect.ValueOf(given)
+       if !g.IsValid() {
+               return dflt
+       }
+
+       set := false
+
+       switch g.Kind() {
+       case reflect.Bool:
+               set = g.Bool()
+       case reflect.String, reflect.Array, reflect.Slice, reflect.Map:
+               set = g.Len() != 0
+       case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+               set = g.Int() != 0
+       case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+               set = g.Uint() != 0
+       case reflect.Float32, reflect.Float64:
+               set = g.Float() != 0
+       case reflect.Complex64, reflect.Complex128:
+               set = g.Complex() != 0
+       case reflect.Struct:
+               set = true
+       default:
+               set = !g.IsNil()
+       }
+
+       if set {
+               return given
+       }
+
+       return dflt
+}
+
 // safeHTMLAttr returns a given string as html/template HTMLAttr content.
 //
 // safeHTMLAttr is currently disabled, pending further discussion
                "chomp":        chomp,
                "countrunes":   countRunes,
                "countwords":   countWords,
+               "default":      dfault,
                "dateFormat":   dateFormat,
                "delimit":      delimit,
                "dict":         dictionary,
 
        "encoding/base64"
        "errors"
        "fmt"
-       "github.com/spf13/cast"
-       "github.com/spf13/viper"
-       "github.com/stretchr/testify/assert"
        "html/template"
        "math/rand"
        "path"
        "strings"
        "testing"
        "time"
+
+       "github.com/spf13/cast"
+       "github.com/spf13/viper"
+       "github.com/stretchr/testify/assert"
 )
 
 type tstNoStringer struct {
        }
 }
 
+func TestDefault(t *testing.T) {
+       for i, this := range []struct {
+               dflt     interface{}
+               given    interface{}
+               expected interface{}
+       }{
+               {"5", 0, "5"},
+
+               {"test1", "set", "set"},
+               {"test2", "", "test2"},
+
+               {[2]int{10, 20}, [2]int{1, 2}, [2]int{1, 2}},
+               {[2]int{10, 20}, [0]int{}, [2]int{10, 20}},
+
+               {[]string{"one"}, []string{"uno"}, []string{"uno"}},
+               {[]string{"one"}, []string{}, []string{"one"}},
+
+               {map[string]int{"one": 1}, map[string]int{"uno": 1}, map[string]int{"uno": 1}},
+               {map[string]int{"one": 1}, map[string]int{}, map[string]int{"one": 1}},
+
+               {10, 1, 1},
+               {10, 0, 10},
+
+               {float32(10), float32(1), float32(1)},
+               {float32(10), 0, float32(10)},
+
+               {complex(2, -2), complex(1, -1), complex(1, -1)},
+               {complex(2, -2), complex(0, 0), complex(2, -2)},
+
+               {struct{ f string }{f: "one"}, struct{ f string }{}, struct{ f string }{}},
+       } {
+               res := dfault(this.dflt, this.given)
+               if !reflect.DeepEqual(this.expected, res) {
+                       t.Errorf("[%d] default returned %v, but expected %v", i, res, this.expected)
+               }
+       }
+}
+
 func TestSafeHTML(t *testing.T) {
        for i, this := range []struct {
                str                 string