...
Run Format

Source file src/text/template/helper.go

     1	// Copyright 2011 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	// Helper functions to make constructing templates easier.
     6	
     7	package template
     8	
     9	import (
    10		"fmt"
    11		"io/ioutil"
    12		"path/filepath"
    13	)
    14	
    15	// Functions and methods to parse templates.
    16	
    17	// Must is a helper that wraps a call to a function returning (*Template, error)
    18	// and panics if the error is non-nil. It is intended for use in variable
    19	// initializations such as
    20	//	var t = template.Must(template.New("name").Parse("text"))
    21	func Must(t *Template, err error) *Template {
    22		if err != nil {
    23			panic(err)
    24		}
    25		return t
    26	}
    27	
    28	// ParseFiles creates a new Template and parses the template definitions from
    29	// the named files. The returned template's name will have the base name and
    30	// parsed contents of the first file. There must be at least one file.
    31	// If an error occurs, parsing stops and the returned *Template is nil.
    32	func ParseFiles(filenames ...string) (*Template, error) {
    33		return parseFiles(nil, filenames...)
    34	}
    35	
    36	// ParseFiles parses the named files and associates the resulting templates with
    37	// t. If an error occurs, parsing stops and the returned template is nil;
    38	// otherwise it is t. There must be at least one file.
    39	// Since the templates created by ParseFiles are named by the base
    40	// names of the argument files, t should usually have the name of one
    41	// of the (base) names of the files. If it does not, depending on t's
    42	// contents before calling ParseFiles, t.Execute may fail. In that
    43	// case use t.ExecuteTemplate to execute a valid template.
    44	func (t *Template) ParseFiles(filenames ...string) (*Template, error) {
    45		t.init()
    46		return parseFiles(t, filenames...)
    47	}
    48	
    49	// parseFiles is the helper for the method and function. If the argument
    50	// template is nil, it is created from the first file.
    51	func parseFiles(t *Template, filenames ...string) (*Template, error) {
    52		if len(filenames) == 0 {
    53			// Not really a problem, but be consistent.
    54			return nil, fmt.Errorf("template: no files named in call to ParseFiles")
    55		}
    56		for _, filename := range filenames {
    57			b, err := ioutil.ReadFile(filename)
    58			if err != nil {
    59				return nil, err
    60			}
    61			s := string(b)
    62			name := filepath.Base(filename)
    63			// First template becomes return value if not already defined,
    64			// and we use that one for subsequent New calls to associate
    65			// all the templates together. Also, if this file has the same name
    66			// as t, this file becomes the contents of t, so
    67			//  t, err := New(name).Funcs(xxx).ParseFiles(name)
    68			// works. Otherwise we create a new template associated with t.
    69			var tmpl *Template
    70			if t == nil {
    71				t = New(name)
    72			}
    73			if name == t.Name() {
    74				tmpl = t
    75			} else {
    76				tmpl = t.New(name)
    77			}
    78			_, err = tmpl.Parse(s)
    79			if err != nil {
    80				return nil, err
    81			}
    82		}
    83		return t, nil
    84	}
    85	
    86	// ParseGlob creates a new Template and parses the template definitions from the
    87	// files identified by the pattern, which must match at least one file. The
    88	// returned template will have the (base) name and (parsed) contents of the
    89	// first file matched by the pattern. ParseGlob is equivalent to calling
    90	// ParseFiles with the list of files matched by the pattern.
    91	func ParseGlob(pattern string) (*Template, error) {
    92		return parseGlob(nil, pattern)
    93	}
    94	
    95	// ParseGlob parses the template definitions in the files identified by the
    96	// pattern and associates the resulting templates with t. The pattern is
    97	// processed by filepath.Glob and must match at least one file. ParseGlob is
    98	// equivalent to calling t.ParseFiles with the list of files matched by the
    99	// pattern.
   100	func (t *Template) ParseGlob(pattern string) (*Template, error) {
   101		t.init()
   102		return parseGlob(t, pattern)
   103	}
   104	
   105	// parseGlob is the implementation of the function and method ParseGlob.
   106	func parseGlob(t *Template, pattern string) (*Template, error) {
   107		filenames, err := filepath.Glob(pattern)
   108		if err != nil {
   109			return nil, err
   110		}
   111		if len(filenames) == 0 {
   112			return nil, fmt.Errorf("template: pattern matches no files: %#q", pattern)
   113		}
   114		return parseFiles(t, filenames...)
   115	}
   116	

View as plain text