github.com/jasonish/buffalo@v0.8.2-0.20170413145823-bacbdd415f1b/render/template.go (about)

     1  package render
     2  
     3  import (
     4  	"html"
     5  	"html/template"
     6  	"io"
     7  	"path/filepath"
     8  	"strings"
     9  
    10  	"github.com/shurcooL/github_flavored_markdown"
    11  )
    12  
    13  type templateRenderer struct {
    14  	*Engine
    15  	contentType string
    16  	names       []string
    17  }
    18  
    19  func (s templateRenderer) ContentType() string {
    20  	return s.contentType
    21  }
    22  
    23  func (s templateRenderer) Render(w io.Writer, data Data) error {
    24  	var body template.HTML
    25  	var err error
    26  	for _, name := range s.names {
    27  
    28  		body, err = s.exec(name, data)
    29  		if err != nil {
    30  			return err
    31  		}
    32  		data["yield"] = body
    33  	}
    34  	w.Write([]byte(body))
    35  	return nil
    36  }
    37  
    38  func (s templateRenderer) partial(name string, dd Data) (template.HTML, error) {
    39  	d, f := filepath.Split(name)
    40  	name = filepath.Join(d, "_"+f)
    41  	return s.exec(name, dd)
    42  }
    43  
    44  func (s templateRenderer) exec(name string, data Data) (template.HTML, error) {
    45  	source, err := s.TemplatesBox.MustBytes(name)
    46  	if err != nil {
    47  		return "", err
    48  	}
    49  
    50  	helpers := map[string]interface{}{
    51  		"partial": s.partial,
    52  	}
    53  
    54  	for k, v := range s.Helpers {
    55  		helpers[k] = v
    56  	}
    57  
    58  	if strings.ToLower(filepath.Ext(name)) == ".md" {
    59  		source = github_flavored_markdown.Markdown(source)
    60  		source = []byte(html.UnescapeString(string(source)))
    61  	}
    62  
    63  	body, err := s.TemplateEngine(string(source), data, helpers)
    64  	if err != nil {
    65  		return "", err
    66  	}
    67  
    68  	return template.HTML(body), nil
    69  }
    70  
    71  // Template renders the named files using the specified
    72  // content type and the github.com/gobuffalo/plush
    73  // package for templating. If more than 1 file is provided
    74  // the second file will be considered a "layout" file
    75  // and the first file will be the "content" file which will
    76  // be placed into the "layout" using "{{yield}}".
    77  func Template(c string, names ...string) Renderer {
    78  	e := New(Options{})
    79  	return e.Template(c, names...)
    80  }
    81  
    82  // Template renders the named files using the specified
    83  // content type and the github.com/gobuffalo/plush
    84  // package for templating. If more than 1 file is provided
    85  // the second file will be considered a "layout" file
    86  // and the first file will be the "content" file which will
    87  // be placed into the "layout" using "{{yield}}".
    88  func (e *Engine) Template(c string, names ...string) Renderer {
    89  	return templateRenderer{
    90  		Engine:      e,
    91  		contentType: c,
    92  		names:       names,
    93  	}
    94  }