/* * @Author: Bartuccio Antoine * @Date: 2018-07-14 11:32:11 * @Last Modified by: klmp200 * @Last Modified time: 2018-07-18 20:06:08 */ package gowebframework import ( "encoding/json" "fmt" "github.com/oxtoacart/bpool" "html/template" "io/ioutil" "log" "net/http" "path/filepath" "time" ) var templates map[string]*template.Template var buffer_pool *bpool.BufferPool type Config struct { TemplateIncludePath string TemplateLayoutPath string MainTemplate string StaticFolderPath string TemplateExtensionPattern string ServerPort string ServerListenAddress string SessionProvider string Domain string Debug bool } var ServerConfig Config // Load templates and configuration func Configure(config_file_name string, custom_config_file_name string) { loadConfiguration(config_file_name, custom_config_file_name) loadTemplates() // initialise sessions SessionProviderRegister(FileSessionProvider{}, "FileProvider") // Put a session of 1 day duration ses, err := newSessionManager(ServerConfig.SessionProvider, "GOSESSID", time.Hour*24) if err != nil { log.Fatal(err) } SESSION = ses go clearExpiredSessionsCron() } // Starts server func Start() { http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(ServerConfig.StaticFolderPath)))) log.Println("Server listening on http://" + ServerConfig.ServerListenAddress + ":" + ServerConfig.ServerPort) log.Fatal(http.ListenAndServe(ServerConfig.ServerListenAddress+":"+ServerConfig.ServerPort, nil)) } func loadDefaultConfiguration() { ServerConfig.StaticFolderPath = "statics/" ServerConfig.TemplateIncludePath = "templates/" ServerConfig.TemplateLayoutPath = "templates/layouts/" ServerConfig.TemplateExtensionPattern = "*.gohtml" ServerConfig.ServerPort = "8000" ServerConfig.ServerListenAddress = "0.0.0.0" ServerConfig.Domain = "localhost" ServerConfig.MainTemplate = `{{define "main" }} {{ template "base" . }} {{ end }}` ServerConfig.Debug = false ServerConfig.SessionProvider = "FileProvider" } func loadConfiguration(config_file_name string, custom_config_file_name string) { loadDefaultConfiguration() default_settings, err := ioutil.ReadFile(config_file_name) if err != nil { log.Println("No " + config_file_name + " found, using default conf instead") } else { log.Println("Importing settings") err = json.Unmarshal(default_settings, &ServerConfig) if err != nil { log.Fatal("Malformed " + config_file_name) } } custom_settings, err := ioutil.ReadFile(custom_config_file_name) if err != nil { log.Println("No settings_custom.json fonud, skipping") return } log.Println("Importing custom settings") err = json.Unmarshal(custom_settings, &ServerConfig) if err != nil { log.Fatal("Malformed " + custom_config_file_name) } } func loadTemplates() { if templates == nil { templates = make(map[string]*template.Template) } layoutFiles, err := filepath.Glob(ServerConfig.TemplateLayoutPath + ServerConfig.TemplateExtensionPattern) if err != nil { log.Fatal(err) } includeFiles, err := filepath.Glob(ServerConfig.TemplateIncludePath + ServerConfig.TemplateExtensionPattern) if err != nil { log.Fatal(err) } mainTemplate := template.New("main") mainTemplate, err = mainTemplate.Parse(ServerConfig.MainTemplate) for _, file := range includeFiles { fileName := filepath.Base(file) log.Println("Loading template", fileName) files := append(layoutFiles, file) templates[fileName], err = mainTemplate.Clone() if err != nil { log.Fatal(err) } templates[fileName] = template.Must(templates[fileName].ParseFiles(files...)) } log.Println("Templates loading successful") buffer_pool = bpool.NewBufferPool(64) log.Println("Buffer allocation sucessful") } // Renders a template loaded. It allows templat "inheritance" and pass data into it // Automatic reload if debug mode is enabled func RenderTemplate(w http.ResponseWriter, name string, data interface{}) { if ServerConfig.Debug { loadTemplates() } tmpl, is_ok := templates[name] if !is_ok { http.Error(w, fmt.Sprintf("The template %s does not exist.", name), http.StatusInternalServerError) } buf := buffer_pool.Get() defer buffer_pool.Put(buf) err := tmpl.Execute(buf, data) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } w.Header().Set("Content-Type", "text/html; charset=utf-8") buf.WriteTo(w) }