package dethnote import ( "bytes" "errors" "fmt" "html/template" "io" "net/http" "os" "path/filepath" ) var functions template.FuncMap // URLBase returns the base URL of the current HTTP request. func URLBase(r *http.Request) string { return fmt.Sprintf("https://%s", r.Host, ) } // IncludeFunc implements the "Include" command for the templates. func (s *Server) IncludeFunc(name string, v ...interface{}) template.HTML { buf := bytes.NewBuffer([]byte{}) var err error if len(v) > 0 { err = s.Template(buf, name, v[0]) } else { err = s.Template(buf, name, nil) } if err != nil { return template.HTML("[include error: " + err.Error() + "]") } return template.HTML(buf.String()) } // Template renders an HTML template for the browser. func (s *Server) Template(w io.Writer, name string, v interface{}) error { // Initialize template functions? if functions == nil { functions = template.FuncMap{ "Include": s.IncludeFunc, } } basename := filepath.Base(name) // Find the template file locally. filename := "./templates/" + name if _, err := os.Stat(filename); os.IsNotExist(err) { return errors.New("template not found: " + name) } t := template.New(basename).Funcs(functions) t, err := t.ParseFiles(filename) if err != nil { return err } // Write the template into a buffer in case of errors, so we can still // control the outgoing HTTP status code. buf := bytes.NewBuffer([]byte{}) err = t.ExecuteTemplate(buf, basename, v) if err != nil { return err } // Send the HTML result. w.Write(buf.Bytes()) return nil } // WriteError sends an error to the user. func WriteError(w http.ResponseWriter, err error) { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) }