code: func NewTemplate(i *NewTemplateInput) (*Template, error) {
  	if i == nil {
  		i = &NewTemplateInput{}
  	}
  
  	// Validate that we are either given the path or the explicit contents
  	if i.Source != "" && i.Contents != "" {
  		return nil, ErrTemplateContentsAndSource
  	} else if i.Source == "" && i.Contents == "" {
  		return nil, ErrTemplateMissingContentsAndSource
  	}
  
  	var t Template
  	t.source = i.Source
  	t.contents = i.Contents
  	t.leftDelim = i.LeftDelim
  	t.rightDelim = i.RightDelim
  	t.errMissingKey = i.ErrMissingKey
  
  	if i.Source != "" {
  		contents, err := ioutil.ReadFile(i.Source)
  		if err != nil {
  			return nil, errors.Wrap(err, "failed to read template")
  		}
  		t.contents = string(contents)
  	}
  
  	// Compute the MD5, encode as hex
  	hash := md5.Sum([]byte(t.contents))
  	t.hexMD5 = hex.EncodeToString(hash[:])
  
  	return &t, nil
  }
docs: // NewTemplate creates and parses a new Consul Template template at the given
  // path. If the template does not exist, an error is returned. During
  // initialization, the template is read and is parsed for dependencies. Any
  // errors that occur are returned.