src/pkg/text/template/helper.go - The Go Programming Language

Golang

Source file src/pkg/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	func (t *Template) ParseFiles(filenames ...string) (*Template, error) {
    40		return parseFiles(t, filenames...)
    41	}
    42	
    43	// parseFiles is the helper for the method and function. If the argument
    44	// template is nil, it is created from the first file.
    45	func parseFiles(t *Template, filenames ...string) (*Template, error) {
    46		if len(filenames) == 0 {
    47			// Not really a problem, but be consistent.
    48			return nil, fmt.Errorf("template: no files named in call to ParseFiles")
    49		}
    50		for _, filename := range filenames {
    51			b, err := ioutil.ReadFile(filename)
    52			if err != nil {
    53				return nil, err
    54			}
    55			s := string(b)
    56			name := filepath.Base(filename)
    57			// First template becomes return value if not already defined,
    58			// and we use that one for subsequent New calls to associate
    59			// all the templates together. Also, if this file has the same name
    60			// as t, this file becomes the contents of t, so
    61			//  t, err := New(name).Funcs(xxx).ParseFiles(name)
    62			// works. Otherwise we create a new template associated with t.
    63			var tmpl *Template
    64			if t == nil {
    65				t = New(name)
    66			}
    67			if name == t.Name() {
    68				tmpl = t
    69			} else {
    70				tmpl = t.New(name)
    71			}
    72			_, err = tmpl.Parse(s)
    73			if err != nil {
    74				return nil, err
    75			}
    76		}
    77		return t, nil
    78	}
    79	
    80	// ParseGlob creates a new Template and parses the template definitions from the
    81	// files identified by the pattern, which must match at least one file. The
    82	// returned template will have the (base) name and (parsed) contents of the
    83	// first file matched by the pattern. ParseGlob is equivalent to calling
    84	// ParseFiles with the list of files matched by the pattern.
    85	func ParseGlob(pattern string) (*Template, error) {
    86		return parseGlob(nil, pattern)
    87	}
    88	
    89	// ParseGlob parses the template definitions in the files identified by the
    90	// pattern and associates the resulting templates with t. The pattern is
    91	// processed by filepath.Glob and must match at least one file. ParseGlob is
    92	// equivalent to calling t.ParseFiles with the list of files matched by the
    93	// pattern.
    94	func (t *Template) ParseGlob(pattern string) (*Template, error) {
    95		return parseGlob(t, pattern)
    96	}
    97	
    98	// parseGlob is the implementation of the function and method ParseGlob.
    99	func parseGlob(t *Template, pattern string) (*Template, error) {
   100		filenames, err := filepath.Glob(pattern)
   101		if err != nil {
   102			return nil, err
   103		}
   104		if len(filenames) == 0 {
   105			return nil, fmt.Errorf("template: pattern matches no files: %#q", pattern)
   106		}
   107		return parseFiles(t, filenames...)
   108	}