github.com/jxgolibs/go-oauth2-server@v1.0.1/web/render.go (about)

     1  package web
     2  
     3  import (
     4  	"fmt"
     5  	"html/template"
     6  	"net/http"
     7  	"path/filepath"
     8  
     9  	"github.com/oxtoacart/bpool"
    10  )
    11  
    12  var (
    13  	templates map[string]*template.Template
    14  	bufpool   *bpool.BufferPool
    15  	loaded    = false
    16  )
    17  
    18  // renderTemplate is a wrapper around template.ExecuteTemplate.
    19  // It writes into a bytes.Buffer before writing to the http.ResponseWriter to catch
    20  // any errors resulting from populating the template.
    21  func renderTemplate(w http.ResponseWriter, name string, data map[string]interface{}) error {
    22  	loadTemplates()
    23  
    24  	// Ensure the template exists in the map.
    25  	tmpl, ok := templates[name]
    26  	if !ok {
    27  		return fmt.Errorf("The template %s does not exist", name)
    28  	}
    29  
    30  	// Create a buffer to temporarily write to and check if any errors were encountered.
    31  	buf := bufpool.Get()
    32  	defer bufpool.Put(buf)
    33  
    34  	err := tmpl.ExecuteTemplate(buf, "base", data)
    35  	if err != nil {
    36  		return err
    37  	}
    38  
    39  	// The X-Frame-Options HTTP response header can be used to indicate whether
    40  	// or not a browser should be allowed to render a page in a <frame>,
    41  	// <iframe> or <object> . Sites can use this to avoid clickjacking attacks,
    42  	// by ensuring that their content is not embedded into other sites.
    43  	w.Header().Set("X-Frame-Options", "deny")
    44  	// Set the header and write the buffer to the http.ResponseWriter
    45  	w.Header().Set("Content-Type", "text/html; charset=utf-8")
    46  	buf.WriteTo(w)
    47  	return nil
    48  }
    49  
    50  func loadTemplates() {
    51  	if loaded {
    52  		return
    53  	}
    54  
    55  	templates = make(map[string]*template.Template)
    56  
    57  	bufpool = bpool.NewBufferPool(64)
    58  
    59  	layoutTemplates := map[string][]string{
    60  		"web/layouts/outside.html": {
    61  			"./web/includes/register.html",
    62  			"./web/includes/login.html",
    63  		},
    64  		"web/layouts/inside.html": {
    65  			"./web/includes/authorize.html",
    66  		},
    67  	}
    68  
    69  	for layout, includes := range layoutTemplates {
    70  		for _, include := range includes {
    71  			files := []string{include, layout}
    72  			templates[filepath.Base(include)] = template.Must(template.ParseFiles(files...))
    73  		}
    74  	}
    75  
    76  	loaded = true
    77  }