Skip to content

Instantly share code, notes, and snippets.

@codelitt
Last active March 17, 2017 14:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codelitt/549a68149add0482c6dc2514a46aa580 to your computer and use it in GitHub Desktop.
Save codelitt/549a68149add0482c6dc2514a46aa580 to your computer and use it in GitHub Desktop.
Trying to add cachebusted css file to the ExecuteTemplate method
package main
imports (
"path/filepath"
"strings"
"github.com/gorilla/mux"
)
func main() {
server_port := ":3000"
r := mux.NewRouter()
r.Handle("/", Home).Methods("GET")
r.HandleFunc("/signup", usersC.New).Methods("GET")
r.PathPrefix("/").Handler(http.FileServer(http.Dir("./assets/")))
http.ListenAndServe(server_port, r)
}
func NewStatic() *Static {
return &Static{
Home: views.NewView("layout", "static/home"),
}
}
type Static struct {
Home *views.View
}
func NewView(layout string, files ...string) *View {
files = append(files, layoutFiles()...)
t, err := template.ParseFiles(files...)
if err != nil {
panic(err)
}
return &View{
Template: t,
Layout: layout,
}
}
type View struct {
Template *template.Template
Layout string
}
func (v *View) Render(w http.ResponseWriter, data interface{}) error {
d := Data{}
d.AddCSSFile()
w.Header().Set("Content-Type", "text/html")
err := v.Template.ExecuteTemplate(w, v.Layout, d)
if err != nil {
log.Println(err)
fmt.Fprintln(w, "<h1>Something went wrong. Please contact us at support")
}
return nil
}
func (v *View) ServeHTTP(w http.ResponseWriter, r *http.Request) {
v.Render(w, nil)
}
func (u *Users) New(w http.ResponseWriter, r *http.Request) {
vd := views.Data{}
form := SignupForm{}
if err := parseQuery(r, &form); err != nil {
vd.AddAlerts(views.AlertGeneric)
u.NewView.RenderError(w, vd)
return
}
u.NewView.Render(w, views.Data{Yield: &form})
}
type Data struct {
Alerts []Alert
Yield interface{}
CSSFile interface{}
}
func (d *Data) AddCSSFile() {
ss, _ := filepath.Glob("./assets/site-*.css")
fp := strings.Join(ss, "")
_, d.CSSFile = filepath.Split(fp)
}
@mkopriva
Copy link

Hi, allow me to add one suggestion, expanding a bit more on the stackoverflow discussion.

First, if you know for a fact that the data argument passed to the Render method will, in many cases, be of different types then you can keep doing what you're doing and disregard the rest of this comment.

But if the data argument you're passing to the Render method will always be of the type Data then you should define the Render method as such that its second argument is not of type interface{} but of type Data or *Data. That way you don't have to use type assertion, not that it's a bad thing to use it but you'll always know what you're getting, the compiler will protect you from petty mistakes, you still can call AddCSSFile inside Render on the data Data argument, and, when in the end, you need to pass some new type to Render just add a new field to the Data type and you're good to go.

Below is an example of what i mean:

func (v *View) Render(w http.ResponseWriter, data Data) error {
	d.AddCSSFile()
	w.Header().Set("Content-Type", "text/html")
	err := v.Template.ExecuteTemplate(w, v.Layout, d)
	if err != nil {
		log.Println(err)
		fmt.Fprintln(w, "<h1>Something went wrong. Please contact us at support")
	}
	return nil
}

// This will work as is, without changing anything. 
func (u *Users) New(w http.ResponseWriter, r *http.Request) {
	vd := views.Data{}
	form := SignupForm{}
	if err := parseQuery(r, &form); err != nil {
		vd.AddAlerts(views.AlertGeneric)
		u.NewView.RenderError(w, vd)
		return
	}
	u.NewView.Render(w, views.Data{Yield: &form})
}

// Here you'll need to initialize the arguemnt to an empty value.
func (v *View) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	v.Render(w, Data{})
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment