基于加载的模板的 CSS 类。

huangapple go评论107阅读模式
英文:

css class based on loaded template

问题

我在_base.html模板中有一个这样的bootstrap导航:

<ul class="nav navbar-nav">
    <li><a href="/" class="">Home</a></li>
    <li><a href="/blog/">Blog</a></li>
</ul>

我想使用Golang为相应的列表项添加一个

class="active"

我已经阅读了html/template文档和像这个这样的文章,但我觉得我必须编写一个Golang函数来为每个相应的列表项添加

class="active"

但不知何故,我觉得如果我可以添加类似于

<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>

或类似的内容会更清晰。我记得Rob Pike说过Golang应该为你做所有的计算,但为什么html/template包中会有一个"if"语句呢?

英文:

I've got this bootstrap nav in my _base.html template like this:

&lt;ul class=&quot;nav navbar-nav&quot;&gt;
   &lt;li&gt;&lt;a href=&quot;/&quot; class=&quot;&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;&lt;a href=&quot;/blog/&quot;&gt;Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

Using Golang I want to add a

class=&quot;active&quot;

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=&quot;active&quot;

to every correspondending corresponding list-item. But somehow still I think it would be cleaner if I could just add something like

&lt;ul&gt;
    &lt;li{{ if .template = &quot;index.html&quot; }} class=&quot;active&quot;{{ end }}&gt;&lt;a href=&quot;/&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;
    &lt;li{{ if .template = &quot;blog.html&quot; }} class=&quot;active&quot;{{ end }}&gt;&lt;a href=&quot;/blog/&quot;&gt;Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

得分: 5

我个人经常为这样的任务实现一个小的eq助手:

var tmpl = template.Must(template.New("").Funcs(template.FuncMap{
    "eq": func(a, b interface{}) bool {
        return a == b
    },
}).ParseGlob("templates/*.html"))

示例用法:

<li{{if eq .Active "index"}} class="active"{{end}}><a href="/">Home</a></li>

但只在显示逻辑中使用它。将显示逻辑和实际计算分开是一个好的做法。

英文:

I personally often implement a small eq helper for tasks like that:

var tmpl = template.Must(template.New(&quot;&quot;).Funcs(template.FuncMap{
    &quot;eq&quot;: func(a, b interface{}) bool {
        return a == b
    },
}).ParseGlob(&quot;templates/*.html&quot;)

Example Usage:

&lt;li{{if eq .Active &quot;index&quot;}} class=&quot;active&quot;{{end}}&gt;&lt;a href=&quot;/&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;

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

得分: 5

现在你不需要自己实现eq助手函数,它已经包含在template包中。

<ul>
  <li {{if eq .Active "info" }}class="active"{{end}}>
    <a href="/info">{{.User.Info}}</a>
  </li>
</ul>

现在使用匿名结构体来渲染这个模板。

// 从文件中获取模板
view := template.Must(template.ParseFiles(
  "views/info.html",
  "views/layout.html",
))

// 在路由处理程序中使用数据渲染模板
data := struct {
  User   *User  // 一些包含更多详细信息的自定义结构体
  Active string
}{
  user,  // 一个User实例
  "info",
}
err = view.ExecuteTemplate(w, "layout", data)
check(err)
英文:

Nowadays you don't have to implement your own eq helper. It is already included in the template package.

&lt;ul&gt;
  &lt;li {{if eq .Active &quot;info&quot; }}class=&quot;active&quot;{{end}}&gt;
    &lt;a href=&quot;/info&quot;&gt;{{.User.Info}}&lt;/a&gt;
  &lt;/li&gt;
&lt;/ul&gt;

Now render this template with an anonymous struct.

// get template from file
view := template.Must(template.ParseFiles(
  &quot;views/info.html&quot;,
  &quot;views/layout.html&quot;,
))

// render template with data in route handler
data := struct {
  User   *User  // some custom struct with further details
  Active string
}{
  user,  // a User instance
  &quot;info&quot;,
}
err = view.ExecuteTemplate(w, &quot;layout&quot;, data)
check(err)

答案3

得分: 0

我认为这是你的情况下应该采取的方式。根据你的具体用例,你可以稍微改写一下:

type State struct {
    active string
}

func (s *State) Class(page string) string {
    if s.active == page {
        return `class="active"`
    }
    return `class="notactive"` // 或者你想要的默认情况
}

tmplt := `
<ul class="nav navbar-nav">
    <li><a href="/" {{.Class "index"}}>Home</a></li>
    <li><a href="/blog/" {{.Class "blog"}}>Blog</a></li>
</ul>`

或者类似这样的代码,但是在模板中使用 if 的目的正是为了允许这些情况。尽管你的 Go 代码将决定哪个页面是活动的,但你仍然需要将其传递给模板。我认为某种形式的 if 语句(或者像我上面做的调用)是必需的,以提取你传递的状态,即使它已经包含了所有的信息。

英文:

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=&quot;active&quot;`
    }
    return `class=&quot;notactive&quot;` // Or whatever default case you want
}

tmplt = `
&lt;ul class=&quot;nav navbar-nav&quot;&gt;
    &lt;li&gt;&lt;a href=&quot;/&quot; {{.Class &quot;index&quot;}}&gt;Home&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/blog/&quot; {{.Class &quot;blog&quot;}}&gt;Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;`

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.

huangapple
  • 本文由 发表于 2013年8月21日 16:15:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/18352192.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定