css class based on loaded template

泪湿孤枕 提交于 2019-12-24 07:18:47

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!