From f563a1f0f5ede37b1dbaa7f0927b79ad775a5b6c Mon Sep 17 00:00:00 2001 From: Robert Daniel Kortschak Date: Tue, 8 Jul 2014 15:27:33 +1000 Subject: [PATCH] go.tools/cmd/present: move dirListTemplate into template file This change allows the directory front page to be more easily configurable. Templates are now read only at start-up and stored in a map rather than re-parsed for each page rendering. LGTM=adg R=adg CC=golang-codereviews https://golang.org/cl/109080044 --- cmd/present/appengine.go | 1 + cmd/present/dir.go | 156 ++++++++++----------------------- cmd/present/local.go | 4 + cmd/present/templates/dir.tmpl | 81 +++++++++++++++++ 4 files changed, 130 insertions(+), 112 deletions(-) create mode 100644 cmd/present/templates/dir.tmpl diff --git a/cmd/present/appengine.go b/cmd/present/appengine.go index f8604b99..b7d8574e 100644 --- a/cmd/present/appengine.go +++ b/cmd/present/appengine.go @@ -17,6 +17,7 @@ import ( var basePath = "./present/" func init() { + initTemplates(basePath) playScript(basePath, "HTTPTransport") present.PlayEnabled = true diff --git a/cmd/present/dir.go b/cmd/present/dir.go index a039f69d..dd3e0810 100644 --- a/cmd/present/dir.go +++ b/cmd/present/dir.go @@ -5,7 +5,6 @@ package main import ( - "fmt" "html/template" "io" "log" @@ -30,7 +29,7 @@ func dirHandler(w http.ResponseWriter, r *http.Request) { const base = "." name := filepath.Join(base, r.URL.Path) if isDoc(name) { - err := renderDoc(w, basePath, name) + err := renderDoc(w, name) if err != nil { log.Println(err) http.Error(w, err.Error(), 500) @@ -47,21 +46,53 @@ func dirHandler(w http.ResponseWriter, r *http.Request) { http.FileServer(http.Dir(base)).ServeHTTP(w, r) } -// extensions maps the presentable file extensions to the name of the -// template to be executed. -var extensions = map[string]string{ - ".slide": "slides.tmpl", - ".article": "article.tmpl", -} - func isDoc(path string) bool { - _, ok := extensions[filepath.Ext(path)] + _, ok := contentTemplate[filepath.Ext(path)] return ok } -// renderDoc reads the present file, builds its template representation, +var ( + // dirListTemplate holds the front page template. + dirListTemplate *template.Template + + // contentTemplate maps the presentable file extensions to the + // template to be executed. + contentTemplate map[string]*template.Template +) + +func initTemplates(base string) error { + // Locate the template file. + actionTmpl := filepath.Join(base, "templates/action.tmpl") + + contentTemplate = make(map[string]*template.Template) + + for ext, contentTmpl := range map[string]string{ + ".slide": "slides.tmpl", + ".article": "article.tmpl", + } { + contentTmpl = filepath.Join(base, "templates", contentTmpl) + + // Read and parse the input. + tmpl := present.Template() + tmpl = tmpl.Funcs(template.FuncMap{"playable": playable}) + if _, err := tmpl.ParseFiles(actionTmpl, contentTmpl); err != nil { + return err + } + contentTemplate[ext] = tmpl + } + + var err error + dirListTemplate, err = template.ParseFiles(filepath.Join(base, "templates/dir.tmpl")) + if err != nil { + return err + } + + return nil +} + +// renderDoc reads the present file, gets its template representation, // and executes the template, sending output to w. -func renderDoc(w io.Writer, base, docFile string) error { +func renderDoc(w io.Writer, docFile string) error { // Read the input and build the doc structure. doc, err := parse(docFile, 0) if err != nil { @@ -69,22 +100,7 @@ func renderDoc(w io.Writer, base, docFile string) error { } // Find which template should be executed. - ext := filepath.Ext(docFile) - contentTmpl, ok := extensions[ext] - if !ok { - return fmt.Errorf("no template for extension %v", ext) - } - - // Locate the template file. - actionTmpl := filepath.Join(base, "templates/action.tmpl") - contentTmpl = filepath.Join(base, "templates", contentTmpl) - - // Read and parse the input. - tmpl := present.Template() - tmpl = tmpl.Funcs(template.FuncMap{"playable": playable}) - if _, err := tmpl.ParseFiles(actionTmpl, contentTmpl); err != nil { - return err - } + tmpl := contentTemplate[filepath.Ext(docFile)] // Execute the template. return doc.Render(w, tmpl) @@ -195,87 +211,3 @@ type dirEntrySlice []dirEntry func (s dirEntrySlice) Len() int { return len(s) } func (s dirEntrySlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s dirEntrySlice) Less(i, j int) bool { return s[i].Name < s[j].Name } - -var dirListTemplate = template.Must(template.New("").Parse(dirListHTML)) - -const dirListHTML = ` - - - - Talks - The Go Programming Language - - - - - -
- -
- -

Go talks

- - {{with .Path}}

{{.}}

{{end}} - - {{with .Articles}} -

Articles:

-
- {{range .}} -
{{.Name}}: {{.Title}}
- {{end}} -
- {{end}} - - {{with .Slides}} -

Slide decks:

-
- {{range .}} -
{{.Name}}: {{.Title}}
- {{end}} -
- {{end}} - - {{with .Other}} -

Files:

-
- {{range .}} -
{{.Name}}
- {{end}} -
- {{end}} - - {{with .Dirs}} -

Sub-directories:

-
- {{range .}} -
{{.Name}}
- {{end}} -
- {{end}} - -
- - - - -` diff --git a/cmd/present/local.go b/cmd/present/local.go index 81684372..294a5247 100644 --- a/cmd/present/local.go +++ b/cmd/present/local.go @@ -43,6 +43,10 @@ func main() { } basePath = p.Dir } + err := initTemplates(basePath) + if err != nil { + log.Fatalf("Failed to parse templates: %v", err) + } ln, err := net.Listen("tcp", *httpAddr) if err != nil { diff --git a/cmd/present/templates/dir.tmpl b/cmd/present/templates/dir.tmpl new file mode 100644 index 00000000..aa838683 --- /dev/null +++ b/cmd/present/templates/dir.tmpl @@ -0,0 +1,81 @@ + + + + + Talks - The Go Programming Language + + + + + +
+ +
+ +

Go talks

+ + {{with .Path}}

{{.}}

{{end}} + + {{with .Articles}} +

Articles:

+
+ {{range .}} +
{{.Name}}: {{.Title}}
+ {{end}} +
+ {{end}} + + {{with .Slides}} +

Slide decks:

+
+ {{range .}} +
{{.Name}}: {{.Title}}
+ {{end}} +
+ {{end}} + + {{with .Other}} +

Files:

+
+ {{range .}} +
{{.Name}}
+ {{end}} +
+ {{end}} + + {{with .Dirs}} +

Sub-directories:

+
+ {{range .}} +
{{.Name}}
+ {{end}} +
+ {{end}} + +
+ + + + +