1. Yann Malet
  2. gowebexp

Commits

Yann Malet  committed fd8279a

Do not parse the templates on every request

  • Participants
  • Parent commits 3069b38
  • Branches master

Comments (0)

Files changed (5)

File web/app.go

View file
  • Ignore whitespace
 	return true
 }
 
+func templatePath(templateDir, name string) string {
+	return filepath.Join(templateDir, name)
+}
+
+func parseTemplates(templateDir string, filenames ...string) (templates map[string]*template.Template) {
+	if len(filenames) == 0 {
+		log.Fatal("You must pass at least one file to parseTemplates")
+	}
+	templates = make(map[string]*template.Template)
+
+	for _, filename := range filenames {
+		templates[filename] = template.Must(template.ParseFiles(
+			templatePath(templateDir, filename),
+			templatePath(templateDir, "base.html")))
+	}
+	return templates
+}
+
 // Implement a sigleton Pattern
 type WebApp struct {
 	Router      *mux.Router
 	Storage     Storage
 	StaticDir   string
 	TemplateDir string
+	Templates   map[string]*template.Template
 	CookieStore *sessions.CookieStore
 }
 
 		Storage:     storage,
 		StaticDir:   StaticDir,
 		TemplateDir: TemplateDir,
+		Templates: parseTemplates(TemplateDir,
+			"index.html",
+			"page_list.html",
+			"page_detail.html"),
 		CookieStore: sessions.NewCookieStore([]byte("something-very-secret"))}
 	return app
 }
 
-func (app *WebApp) Template(name string) string {
-	return filepath.Join(app.TemplateDir, name)
-}
-
 func (app *WebApp) GenerateCsrfToken() string {
 	// Arbitrary length of 80
 	token := make([]byte, 80)
 	if err != nil {
 		panic(err)
 	}
-	tmpl := template.Must(template.ParseFiles(
-		App.Template("index.html"), App.Template("base.html")))
+	tmpl := App.Templates["index.html"]
 	ctx := make(map[string]interface{})
 	ctx["pages_url"] = pages_url
 	ctx["title"] = "Web experiment with GO"
 		}
 	}
 
-	// DISCUSS template inheritance it feels weird
-	t, err := template.ParseFiles(App.Template("pages.html"), App.Template("base.html"))
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
+	tmpl := App.Templates["page_list.html"]
 	ctx["storage"] = App.Storage
-	err = t.ExecuteTemplate(w, "base", ctx)
+	err := tmpl.ExecuteTemplate(w, "base", ctx)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 	}
 }
 
 func PageDetail(w http.ResponseWriter, r *http.Request) {
-	t, err := template.ParseFiles(
-		App.Template("detail_page.html"), App.Template("base.html"))
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
+	tmpl := App.Templates["page_detail.html"]
 	ctx := make(map[string]interface{})
-	ctx["page"], err = App.Storage.GetPageBySlug(mux.Vars(r)["slug"])
+	page, err := App.Storage.GetPageBySlug(mux.Vars(r)["slug"])
+	ctx["page"] = page
 	if err != nil {
 		http.NotFound(w, r)
 		return
 	}
-	err = t.ExecuteTemplate(w, "base", ctx)
+	err = tmpl.ExecuteTemplate(w, "base", ctx)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return

File web/templates/detail_page.html

  • Ignore whitespace
-{{ define "title" }}{{ .page.Name }}{{ end}}
-{{ define "header" }}<h2>{{ .page.Name }}</h2>{{ end}}
-{{ define "content" }}{{ .page.RenderedContent }}{{ end }}
-{{ define "sidebar" }}{{ end}}
-{{ define "footer" }}{{ end}}
-
-

File web/templates/page_detail.html

View file
  • Ignore whitespace
+{{ define "title" }}{{ .page.Name }}{{ end}}
+{{ define "header" }}<h2>{{ .page.Name }}</h2>{{ end}}
+{{ define "content" }}{{ .page.RenderedContent }}{{ end }}
+{{ define "sidebar" }}{{ end}}
+{{ define "footer" }}{{ end}}
+
+

File web/templates/page_list.html

View file
  • Ignore whitespace
+{{ define "title" }}Pages{{ end}}
+{{ define "header" }}<h2>Pages</h2>{{ end }}
+{{ define "content" }}
+<h1>Page List</h1>
+<ul>{{ range .storage.Pages }}
+    <li><a href="/pages/{{ .Slug}}/">{{ .Name }}</a></li>{{ end }}
+</ul>
+<a id="display_page_form" href="#" class="button">Add Page</a>
+{{ if .validationErrors }}
+<div id="pageFormError" class="text-error">The page does not validate fix the error below</div>
+{{ end }}
+<form id="pageForm" action="" method="post" accept-charset="utf-8" class="hide">
+    <fieldset>
+        <input type="hidden" name="csrf_token" value="{{ .csrf_token }}">
+        <div class="row">
+            <div class="twelve columns">
+                {{ if .validationErrors.Name }}<div class="text-error">{{ .validationErrors.Name }}</div>{{ end }}
+                <label>name</label>
+                <input type="text" name="name" value="" placeholder="name">
+            </div>
+        </div>
+        <div class="row">
+            <div class="twelve columns">
+                {{ if .validationErrors.Slug }}<div class="text-error">{{ .validationErrors.Slug }}</div>{{ end }}
+                <label>slug</label>
+                <input type="text" name="slug" value="" placeholder="name">
+            </div>
+        </div>
+        <div class="row">
+            <div class="twelve columns">
+               {{ if .validationErrors.Content }}<div class="text-error">{{ .validationErrors.Content }}</div>{{ end }}
+               <label>content</label>
+                <textarea name="content"></textarea>
+            </div>
+        </div>
+
+        <p><input type="submit" value="Add" class="button"></p>
+    </fieldset>
+</form>
+{{ end }}
+{{define "sidebar" }}{{ end }}
+{{define "footer" }}{{ end }}

File web/templates/pages.html

  • Ignore whitespace
-{{ define "title" }}Pages{{ end}}
-{{ define "header" }}<h2>Pages</h2>{{ end }}
-{{ define "content" }}
-<h1>Page List</h1>
-<ul>{{ range .storage.Pages }}
-    <li><a href="/pages/{{ .Slug}}/">{{ .Name }}</a></li>{{ end }}
-</ul>
-<a id="display_page_form" href="#" class="button">Add Page</a>
-{{ if .validationErrors }}
-<div id="pageFormError" class="text-error">The page does not validate fix the error below</div>
-{{ end }}
-<form id="pageForm" action="" method="post" accept-charset="utf-8" class="hide">
-    <fieldset>
-        <input type="hidden" name="csrf_token" value="{{ .csrf_token }}">
-        <div class="row">
-            <div class="twelve columns">
-                {{ if .validationErrors.Name }}<div class="text-error">{{ .validationErrors.Name }}</div>{{ end }}
-                <label>name</label>
-                <input type="text" name="name" value="" placeholder="name">
-            </div>
-        </div>
-        <div class="row">
-            <div class="twelve columns">
-                {{ if .validationErrors.Slug }}<div class="text-error">{{ .validationErrors.Slug }}</div>{{ end }}
-                <label>slug</label>
-                <input type="text" name="slug" value="" placeholder="name">
-            </div>
-        </div>
-        <div class="row">
-            <div class="twelve columns">
-               {{ if .validationErrors.Content }}<div class="text-error">{{ .validationErrors.Content }}</div>{{ end }}
-               <label>content</label>
-                <textarea name="content"></textarea>
-            </div>
-        </div>
-
-        <p><input type="submit" value="Add" class="button"></p>
-    </fieldset>
-</form>
-{{ end }}
-{{define "sidebar" }}{{ end }}
-{{define "footer" }}{{ end }}