Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go, AppEngine: How to structure templates for application

How are people handling the use of templates in their Go-based AppEngine applications?

Specifically, I'm looking for a project structure that affords the following:

  • Hierarchical (directory) structure of templates and partial templates
  • Allow me to use HTML tools/editors on my templates (embedding template text in xxx.go files makes this difficult)
  • Automatic reload of template text when on dev server

Potential stumbling blocks are:

  • template.ParseGlob() will not traverse recursively.
  • For performance reasons it has been recommended not to upload your templates as raw text files (because those text files reside on different servers than executing code).

Please note that I am not looking for a tutorial/examples of the use of the template package. This is more of an app structure question. That being said, if you have code that solves the above problems, I would love to see it. Thanks in advance.

like image 391
laslowh Avatar asked Mar 05 '12 20:03

laslowh


1 Answers

One of my favorite features of Go is the ability to easily add handlers inside of packages. This greatly simplifies the processes of writing modular code.

For Example:

File Structure

|-- app.yaml |-- app |   +-- http.go |-- templates |   +-- base.html +-- github.com     +-- storeski         +-- appengine             |-- products             |   |-- http.go             |   +-- templates             |       |-- list.html             |       +-- detail.html              +-- account                 |-- http.go                 +-- templates                     |-- overview.html                     +-- notifications.html  

Each packages has a http.go file that takes ownership of a url prefix. For example the products package under github.com/storeski/appengine/products would own any inbound url starting with /products.

With this modular approach it is beneficial to store the templates within the products package. If you would like to maintain a consistant base template for the site you can establish a convention where you extend templates/base.html.

Example

templates/base.html

<!DOCTYPE HTML> <html>   <head>     <title>{{.Store.Title}}</title>   </head>    <body>     <div id="content">       {{template "content" .}}     </div>   </body> </html> 

github.com/storeski/appengine/products/templates/list.html

{{define "content"}}   <h1> Products List </h1> {{end}} 

github.com/storeski/appengine/products/http.go

func init() {   http.HandleFunc("/products", listHandler) }  var listTmpl = template.Must(template.ParseFiles("templates/base.html",   "github.com/storeski/appengine/products/templates/list.html"))  func listHandler(w http.ResponseWriter, r *http.Request) {    tc := make(map[string]interface{})   tc["Store"] = Store   tc["Products"] = Products    if err := listTmpl.Execute(w, tc); err != nil {     http.Error(w, err.Error(), http.StatusInternalServerError)   } } 

This approach is very exciting because it makes the sharing of apps/package trivial. If I write a package that handles authentication which takes ownership of the /auth url. Any developer that, then, adds the package to their product root instantly has all of the functionality. All they have to do is create a base template (templates/base.html) and direct their users to /auth.

like image 55
Kyle Finley Avatar answered Oct 04 '22 19:10

Kyle Finley