I'm trying to build a very simple Go web application, and the golang "a folder per package" structure is making things difficult for me.
I'm using github.com/gorilla/mux
as the router and github.com/unrolled/render
for template rendering. This means that I need to create a new router and a new renderer when the app launches, and I need all my routes to access the renderer.
This is super easy to do in a single file:
func main() {
...
r := render.New(render.Options{
// a lot of app specific setup
})
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
r.HTML(w, http.StatusOK, "myTemplate", nil)
})
...
}
However, this is where I don't understand Go. Because I want the routes in separate files in a subfolder (my project will grow), that forces them to be in a routes
package. Of course that makes the renderer variable inaccesssible. I can't just create the renderer in the routes
package, because the render.New()
call relies on a me passing in a ton of app specific stuff like the template folder, and helpers for asset paths.
I went down the route of making my handler functions work on a struct with an already initialized renderer...
func (app *App) Hello2(w http.ResponseWriter, r *http.Request) {
app.Renderer.HTML(w, http.StatusOK, "myTemplate", nil)
}
But I'm still confused as to how I'm going to access this app *App
in the routes
package when it's initialized in main
. Everything in Go seems super easy if you have a flat list of files, but as soon as you want a bit of folder structure, the package setup becomes problematic.
There's probably something I'm missing here, so any help is appreciated.
myapp/render
package that just sets avar Render
in itsinit()
(or even just declares the var and letsmain.main()
set it). But the setup you linked provides a hook to change behavior later if, say,Render
config is not the same for all requests someday (e.g., you host versions of your app on two domains and use differentLayout
s for each). – twotwotwo