Fixes debug HTML rendering:
- Stateless algorithm
This commit is contained in:
		
							
								
								
									
										8
									
								
								gin.go
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								gin.go
									
									
									
									
									
								
							@ -76,8 +76,8 @@ func (engine *Engine) allocateContext() (c *Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (engine *Engine) LoadHTMLGlob(pattern string) {
 | 
					func (engine *Engine) LoadHTMLGlob(pattern string) {
 | 
				
			||||||
	if IsDebugging() {
 | 
						if IsDebugging() {
 | 
				
			||||||
		render.HTMLDebug.AddGlob(pattern)
 | 
							r := &render.HTMLDebugRender{Glob: pattern}
 | 
				
			||||||
		engine.HTMLRender = render.HTMLDebug
 | 
							engine.HTMLRender = r
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		templ := template.Must(template.ParseGlob(pattern))
 | 
							templ := template.Must(template.ParseGlob(pattern))
 | 
				
			||||||
		engine.SetHTMLTemplate(templ)
 | 
							engine.SetHTMLTemplate(templ)
 | 
				
			||||||
@ -86,8 +86,8 @@ func (engine *Engine) LoadHTMLGlob(pattern string) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (engine *Engine) LoadHTMLFiles(files ...string) {
 | 
					func (engine *Engine) LoadHTMLFiles(files ...string) {
 | 
				
			||||||
	if IsDebugging() {
 | 
						if IsDebugging() {
 | 
				
			||||||
		render.HTMLDebug.AddFiles(files...)
 | 
							r := &render.HTMLDebugRender{Files: files}
 | 
				
			||||||
		engine.HTMLRender = render.HTMLDebug
 | 
							engine.HTMLRender = r
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		templ := template.Must(template.ParseFiles(files...))
 | 
							templ := template.Must(template.ParseFiles(files...))
 | 
				
			||||||
		engine.SetHTMLTemplate(templ)
 | 
							engine.SetHTMLTemplate(templ)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										50
									
								
								render/html_debug.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								render/html_debug.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					// Copyright 2014 Manu Martinez-Almeida.  All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a MIT style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package render
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"html/template"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type HTMLDebugRender struct {
 | 
				
			||||||
 | 
						files []string
 | 
				
			||||||
 | 
						globs []string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *HTMLDebugRender) AddGlob(pattern string) {
 | 
				
			||||||
 | 
						r.globs = append(r.globs, pattern)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *HTMLDebugRender) AddFiles(files ...string) {
 | 
				
			||||||
 | 
						r.files = append(r.files, files...)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *HTMLDebugRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
 | 
				
			||||||
 | 
						WriteHeader(w, code, "text/html")
 | 
				
			||||||
 | 
						file := data[0].(string)
 | 
				
			||||||
 | 
						obj := data[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if t, err := r.newTemplate(); err == nil {
 | 
				
			||||||
 | 
							return t.ExecuteTemplate(w, file, obj)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *HTMLDebugRender) newTemplate() (*template.Template, error) {
 | 
				
			||||||
 | 
						t := template.New("")
 | 
				
			||||||
 | 
						if len(r.files) > 0 {
 | 
				
			||||||
 | 
							if _, err := t.ParseFiles(r.files...); err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, glob := range r.globs {
 | 
				
			||||||
 | 
							if _, err := t.ParseGlob(glob); err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return t, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -27,11 +27,6 @@ type (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	redirectRender struct{}
 | 
						redirectRender struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	htmlDebugRender struct {
 | 
					 | 
				
			||||||
		files []string
 | 
					 | 
				
			||||||
		globs []string
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	HTMLRender struct {
 | 
						HTMLRender struct {
 | 
				
			||||||
		Template *template.Template
 | 
							Template *template.Template
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -43,34 +38,26 @@ var (
 | 
				
			|||||||
	HTMLPlain = htmlPlainRender{}
 | 
						HTMLPlain = htmlPlainRender{}
 | 
				
			||||||
	Plain     = plainTextRender{}
 | 
						Plain     = plainTextRender{}
 | 
				
			||||||
	Redirect  = redirectRender{}
 | 
						Redirect  = redirectRender{}
 | 
				
			||||||
	HTMLDebug = &htmlDebugRender{}
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func writeHeader(w http.ResponseWriter, code int, contentType string) {
 | 
					 | 
				
			||||||
	w.Header().Set("Content-Type", contentType+"; charset=utf-8")
 | 
					 | 
				
			||||||
	w.WriteHeader(code)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (_ jsonRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
 | 
					 | 
				
			||||||
	writeHeader(w, code, "application/json")
 | 
					 | 
				
			||||||
	encoder := json.NewEncoder(w)
 | 
					 | 
				
			||||||
	return encoder.Encode(data[0])
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (_ redirectRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
 | 
					func (_ redirectRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
 | 
				
			||||||
	w.Header().Set("Location", data[0].(string))
 | 
						w.Header().Set("Location", data[0].(string))
 | 
				
			||||||
	w.WriteHeader(code)
 | 
						w.WriteHeader(code)
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_ jsonRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
 | 
				
			||||||
 | 
						WriteHeader(w, code, "application/json")
 | 
				
			||||||
 | 
						return json.NewEncoder(w).Encode(data[0])
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (_ xmlRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
 | 
					func (_ xmlRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
 | 
				
			||||||
	writeHeader(w, code, "application/xml")
 | 
						WriteHeader(w, code, "application/xml")
 | 
				
			||||||
	encoder := xml.NewEncoder(w)
 | 
						return xml.NewEncoder(w).Encode(data[0])
 | 
				
			||||||
	return encoder.Encode(data[0])
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (_ plainTextRender) Render(w http.ResponseWriter, code int, data ...interface{}) (err error) {
 | 
					func (_ plainTextRender) Render(w http.ResponseWriter, code int, data ...interface{}) (err error) {
 | 
				
			||||||
	writeHeader(w, code, "text/plain")
 | 
						WriteHeader(w, code, "text/plain")
 | 
				
			||||||
	format := data[0].(string)
 | 
						format := data[0].(string)
 | 
				
			||||||
	args := data[1].([]interface{})
 | 
						args := data[1].([]interface{})
 | 
				
			||||||
	if len(args) > 0 {
 | 
						if len(args) > 0 {
 | 
				
			||||||
@ -81,52 +68,47 @@ func (_ plainTextRender) Render(w http.ResponseWriter, code int, data ...interfa
 | 
				
			|||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (_ htmlPlainRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
 | 
					func (_ htmlPlainRender) Render(w http.ResponseWriter, code int, data ...interface{}) (err error) {
 | 
				
			||||||
	writeHeader(w, code, "text/html")
 | 
						WriteHeader(w, code, "text/html")
 | 
				
			||||||
	format := data[0].(string)
 | 
						format := data[0].(string)
 | 
				
			||||||
	args := data[1].([]interface{})
 | 
						args := data[1].([]interface{})
 | 
				
			||||||
	var err error
 | 
					 | 
				
			||||||
	if len(args) > 0 {
 | 
						if len(args) > 0 {
 | 
				
			||||||
		_, err = w.Write([]byte(fmt.Sprintf(format, args...)))
 | 
							_, err = w.Write([]byte(fmt.Sprintf(format, args...)))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		_, err = w.Write([]byte(format))
 | 
							_, err = w.Write([]byte(format))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return err
 | 
						return
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *htmlDebugRender) AddGlob(pattern string) {
 | 
					 | 
				
			||||||
	r.globs = append(r.globs, pattern)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *htmlDebugRender) AddFiles(files ...string) {
 | 
					 | 
				
			||||||
	r.files = append(r.files, files...)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *htmlDebugRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
 | 
					 | 
				
			||||||
	writeHeader(w, code, "text/html")
 | 
					 | 
				
			||||||
	file := data[0].(string)
 | 
					 | 
				
			||||||
	obj := data[1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t := template.New("")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if len(r.files) > 0 {
 | 
					 | 
				
			||||||
		if _, err := t.ParseFiles(r.files...); err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, glob := range r.globs {
 | 
					 | 
				
			||||||
		if _, err := t.ParseGlob(glob); err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return t.ExecuteTemplate(w, file, obj)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (html HTMLRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
 | 
					func (html HTMLRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
 | 
				
			||||||
	writeHeader(w, code, "text/html")
 | 
						WriteHeader(w, code, "text/html")
 | 
				
			||||||
	file := data[0].(string)
 | 
						file := data[0].(string)
 | 
				
			||||||
	obj := data[1]
 | 
						args := data[1]
 | 
				
			||||||
	return html.Template.ExecuteTemplate(w, file, obj)
 | 
						return html.Template.ExecuteTemplate(w, file, args)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func WriteHeader(w http.ResponseWriter, code int, contentType string) {
 | 
				
			||||||
 | 
						contentType = joinStrings(contentType, "; charset=utf-8")
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", contentType)
 | 
				
			||||||
 | 
						w.WriteHeader(code)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func joinStrings(a ...string) string {
 | 
				
			||||||
 | 
						if len(a) == 0 {
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(a) == 1 {
 | 
				
			||||||
 | 
							return a[0]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						n := 0
 | 
				
			||||||
 | 
						for i := 0; i < len(a); i++ {
 | 
				
			||||||
 | 
							n += len(a[i])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b := make([]byte, n)
 | 
				
			||||||
 | 
						n = 0
 | 
				
			||||||
 | 
						for _, s := range a {
 | 
				
			||||||
 | 
							n += copy(b[n:], s)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return string(b)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user