问题
I've got this bootstrap nav in my _base.html template like this:
<ul class="nav navbar-nav">
<li><a href="/" class="">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
Using Golang I want to add a
class="active"
to the corresponding list-item.
I've read the html/template docs and articles like thisone, but it appears to me that I have to write a golang function that adds
class="active"
to every correspondending corresponding list-item. But somehow still I think it would be cleaner if I could just add something like
<ul>
<li{{ if .template = "index.html" }} class="active"{{ end }}><a href="/">Home</a></li>
<li{{ if .template = "blog.html" }} class="active"{{ end }}><a href="/blog/">Blog</a></li>
</ul>
or something like that. I remember Rob Pike saying Golang should be doing all the calculations for you, but why is there an "if" statement in the html/template-package?
回答1:
I personally often implement a small eq
helper for tasks like that:
var tmpl = template.Must(template.New("").Funcs(template.FuncMap{
"eq": func(a, b interface{}) bool {
return a == b
},
}).ParseGlob("templates/*.html")
Example Usage:
<li{{if eq .Active "index"}} class="active"{{end}}><a href="/">Home</a></li>
But use it only for the display logic itself. It's a good practice to keep the display logic and the real computation apart.
回答2:
Nowadays you don't have to implement your own eq
helper. It is already included in the template package.
<ul>
<li {{if eq .Active "info" }}class="active"{{end}}>
<a href="/info">{{.User.Info}}</a>
</li>
</ul>
Now render this template with an anonymous struct.
// get template from file
view := template.Must(template.ParseFiles(
"views/info.html",
"views/layout.html",
))
// render template with data in route handler
data := struct {
User *User // some custom struct with further details
Active string
}{
user, // a User instance
"info",
}
err = view.ExecuteTemplate(w, "layout", data)
check(err)
回答3:
I think that is the way to go in your case. You can reformulate this slightly differently depending on your exact use case such as:
type State struct {
active string
}
func (s *State) Class(page string) {
if s.active == page {
return `class="active"`
}
return `class="notactive"` // Or whatever default case you want
}
tmplt = `
<ul class="nav navbar-nav">
<li><a href="/" {{.Class "index"}}>Home</a></li>
<li><a href="/blog/" {{.Class "blog"}}>Blog</a></li>
</ul>`
Or something along these lines, but the point of if
in templates is precisely to allow for these kind of things. Although your Go code will decide WHICH page is active, you still have to pass it to your template, and I think some sort of if
statement (or call as I did above) is required to extract the state you pass, even though it already contains all the information.
来源:https://stackoverflow.com/questions/18352192/css-class-based-on-loaded-template