Skip to content

Commit

Permalink
content: use interface to abstract Execute method
Browse files Browse the repository at this point in the history
Use interface renderer which acts as a field in content struct
corresponding to html/template or text/template object depending on the
tplType field. This should simplify the entire logic of Execute and
hence eliminating the need of an extra switch statement.
  • Loading branch information
sahildua2305 committed Dec 19, 2017
1 parent 2dd7862 commit bed54bc
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 37 deletions.
21 changes: 12 additions & 9 deletions ui/content.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package ui

import (
htemplate "html/template"
ttemplate "text/template"
"io"
)

// Current versions of some dependencies.
Expand All @@ -13,6 +12,15 @@ const (

var contents map[string]*content

// This interface abstracts the Execute method on template which is
// structurally similar in both html/template and text/template.
// We need to use an interface instead of a direct template field
// because then we will need two different fields for html template
// and text template.
type renderer interface {
Execute(w io.Writer, data interface{}) error
}

type content struct {

// The uri for accessing this asset
Expand All @@ -24,13 +32,8 @@ type content struct {
// The JavaScript sources used in this HTML page
sources []string

// This is only created in prd-mode, the pre-parsed template
// HTML template - used for serving HTML content
htpl *htemplate.Template

// This is only created in prd-mode, the pre-parsed template
// Text template - currently used for /open_search.xml only
ttpl *ttemplate.Template
// The parsed template - can be of html/template or text/template type
tpl renderer

// This is used to determine if a template is to be parsed as text or html
tplType string
Expand Down
48 changes: 20 additions & 28 deletions ui/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,24 +63,25 @@ func (h *devHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Renders a templated asset in dev-mode. This simply embeds external script tags
// for the source elements.
func renderForDev(w io.Writer, root string, c *content, cfg *config.Config, r *http.Request) error {
// If the requested asset is of type xml or text, short cut the execution
// using text/template package.
// See - https://github.com/etsy/hound/issues/239
if c.tplType == "xml" || c.tplType == "text" {
t, err := ttemplate.ParseFiles(
filepath.Join(root, c.template))
var err error
// For more context, see: https://github.com/etsy/hound/issues/239
switch c.tplType {
case "html":
// Use html/template to parse the html template
c.tpl, err = htemplate.ParseFiles(filepath.Join(root, c.template))
if err != nil {
return err
}
return t.Execute(w, map[string]interface{}{
"Host": r.Host,
})
}

t, err := htemplate.ParseFiles(
filepath.Join(root, c.template))
if err != nil {
return err
case "xml", "text":
// Use text/template to parse the xml or text templates
// We are using text/template here for parsing xml to keep things
// consistent with html/template parsing.
c.tpl, err = ttemplate.ParseFiles(filepath.Join(root, c.template))
if err != nil {
return err
}
default:
return errors.New("invalid tplType for content")
}

json, err := cfg.ToJsonString()
Expand All @@ -100,7 +101,7 @@ func renderForDev(w io.Writer, root string, c *content, cfg *config.Config, r *h
path)
}

return t.Execute(w, map[string]interface{}{
return c.tpl.Execute(w, map[string]interface{}{
"ReactVersion": ReactVersion,
"jQueryVersion": JQueryVersion,
"ReposAsJson": json,
Expand Down Expand Up @@ -149,15 +150,6 @@ func (h *prdHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Renders a templated asset in prd-mode. This strategy will embed
// the sources directly in a script tag on the templated page.
func renderForPrd(w io.Writer, c *content, cfgJson string, r *http.Request) error {
// If the requested asset is of type xml or text, short cut the execution
// using text/template package.
// See - https://github.com/etsy/hound/issues/239
if c.tplType == "xml" || c.tplType == "text" {
return c.ttpl.Execute(w, map[string]interface{}{
"Host": r.Host,
})
}

var buf bytes.Buffer
buf.WriteString("<script>")
for _, src := range c.sources {
Expand All @@ -169,7 +161,7 @@ func renderForPrd(w io.Writer, c *content, cfgJson string, r *http.Request) erro
}
buf.WriteString("</script>")

return c.htpl.Execute(w, map[string]interface{}{
return c.tpl.Execute(w, map[string]interface{}{
"ReactVersion": ReactVersion,
"jQueryVersion": JQueryVersion,
"ReposAsJson": cfgJson,
Expand Down Expand Up @@ -213,15 +205,15 @@ func newPrdHandler(cfg *config.Config) (http.Handler, error) {
switch cnt.tplType {
case "html":
// Use html/template to parse the html template
cnt.htpl, err = htemplate.New(cnt.template).Parse(string(a))
cnt.tpl, err = htemplate.New(cnt.template).Parse(string(a))
if err != nil {
return nil, err
}
case "xml", "text":
// Use text/template to parse the xml or text templates
// We are using text/template here for parsing xml to keep things
// consistent with html/template parsing.
cnt.ttpl, err = ttemplate.New(cnt.template).Parse(string(a))
cnt.tpl, err = ttemplate.New(cnt.template).Parse(string(a))
if err != nil {
return nil, err
}
Expand Down

0 comments on commit bed54bc

Please sign in to comment.