Home | History | Annotate | Download | only in template
      1 // Copyright 2015 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // This file contains the code to handle template options.
      6 
      7 package template
      8 
      9 import "strings"
     10 
     11 // missingKeyAction defines how to respond to indexing a map with a key that is not present.
     12 type missingKeyAction int
     13 
     14 const (
     15 	mapInvalid   missingKeyAction = iota // Return an invalid reflect.Value.
     16 	mapZeroValue                         // Return the zero value for the map element.
     17 	mapError                             // Error out
     18 )
     19 
     20 type option struct {
     21 	missingKey missingKeyAction
     22 }
     23 
     24 // Option sets options for the template. Options are described by
     25 // strings, either a simple string or "key=value". There can be at
     26 // most one equals sign in an option string. If the option string
     27 // is unrecognized or otherwise invalid, Option panics.
     28 //
     29 // Known options:
     30 //
     31 // missingkey: Control the behavior during execution if a map is
     32 // indexed with a key that is not present in the map.
     33 //	"missingkey=default" or "missingkey=invalid"
     34 //		The default behavior: Do nothing and continue execution.
     35 //		If printed, the result of the index operation is the string
     36 //		"<no value>".
     37 //	"missingkey=zero"
     38 //		The operation returns the zero value for the map type's element.
     39 //	"missingkey=error"
     40 //		Execution stops immediately with an error.
     41 //
     42 func (t *Template) Option(opt ...string) *Template {
     43 	t.init()
     44 	for _, s := range opt {
     45 		t.setOption(s)
     46 	}
     47 	return t
     48 }
     49 
     50 func (t *Template) setOption(opt string) {
     51 	if opt == "" {
     52 		panic("empty option string")
     53 	}
     54 	elems := strings.Split(opt, "=")
     55 	switch len(elems) {
     56 	case 2:
     57 		// key=value
     58 		switch elems[0] {
     59 		case "missingkey":
     60 			switch elems[1] {
     61 			case "invalid", "default":
     62 				t.option.missingKey = mapInvalid
     63 				return
     64 			case "zero":
     65 				t.option.missingKey = mapZeroValue
     66 				return
     67 			case "error":
     68 				t.option.missingKey = mapError
     69 				return
     70 			}
     71 		}
     72 	}
     73 	panic("unrecognized option: " + opt)
     74 }
     75