Closed blachniet closed 10 years ago
@blachniet: Anything is possible. I think what you're looking for is here: http://golang.org/pkg/text/template/ or {{template "path/to/my/template" .}}
On your layout you can do something like:
<body>
{{template "shared/header" .}}
{{yield}}
{{template "shared/footer" .}}
</body>
Make sure you put your layout and all other associated templates in your templates directory and that you remember that yield acts more like a placeholder for whatever template you call. For example if I had:
m.Get("/", func(r render.Render) {
r.HTML(200, "index")
})
<h1>Widgets and Gizmos!</h1>
My first page would get rendered/displayed as:
<body>
<header>My content from shared/header.tmpl</header>
<h1>Widgets and Gizmos!</h1>
<footer>My content from shared/footer.tmpl</footer>
</body>
The main thing to watch out for is that your file paths are pointing to the right spots, otherwise you'll get errors. Also, keep in mind that the {{template}} way of doing things is built into the Go templating system, so you can build things to act like web components and re-use them in different parts of your web application. Hope this helps!
Yeah problem is different pages need to inject different javascript into the HEAD section of the page. In rails they allow named yields, so the inner template can inject in multiple spots into the layout
Sounds like a nifty feature in Rails. If I were trying to tackle this using Go templates/render package, I would probably set mine up something like this:
<html>
<head>
{{range .JavaScriptFiles}}
<script type="text/javascript" src="{{.}}"></script>
{{end}}
</head>
<body>
<header>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About Us</a></li>
</ul>
</header>
<section>
{{yield}}
</section>
<footer>
© MyCompany Inc.
</footer>
</body>
</html>
package main
import (
"net/http"
"github.com/go-martini/martini"
"github.com/martini-contrib/render"
)
func main() {
m := martini.Classic()
m.Use(render.Renderer(render.Options{
Directory: "templates",
Layout: "layout",
Extensions: []string{".tmpl", ".html"},
Delims: render.Delims{"{{", "}}"},
Charset: "UTF-8",
HTMLContentType: "text/html",
}))
m.Get("/", func(req *http.Request, r render.Render) {
data := make(map[string]interface{})
data["JavaScriptFiles"] = getJavaScriptFiles(req.URL.Path)
r.HTML(200, "home", data)
})
m.Get("/about", func(req *http.Request, r render.Render) {
data := make(map[string]interface{})
data["JavaScriptFiles"] = getJavaScriptFiles(req.URL.Path)
r.HTML(200, "about", data)
})
m.Run()
}
func getJavaScriptFiles(path string) []string {
var scripts []string
//common scripts that all pages have
scripts = []string{
"https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js",
}
//specific pages
switch path {
case "/about":
scripts = append(scripts,
"https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.min.js",
)
}
//application script
scripts = append(scripts, "scripts/app.js")
return scripts
}
Setting it up this way you have some control on what scripts go what page, in what order, etc. This works, but I would look into using something like RequireJS for javascript loading on specific pages, managing dependencies, modularizing the javascript, etc. It is also nice because your template would have a single javascript file. Lastly, it is good practice to put scripts at the bottom of the page in the body section of the page. Good luck and I hope this helps!
The only thing that I don't like about this approach is that the controller-esque code needs some view-specific knowledge. However, as you pointed out, this could be avoided by using RequireJS.
Maybe this is already possible, and I just don't know how to do it. I would like to be able to define different extensible areas in my layout. I'm thinking of something similar to Jade's named blocks.
So here I've defined 2 different sections that can be extended,
content
andjavascripts
. In my template I would want to be able to extend each of those areas.The syntax here is obviously theoretical. I'm new to Go, so maybe this is somehow already possible, or maybe I'm thinking about the problem wrong. If so, feel free to set me straight.