从 Revel 模板引擎直接提取模型

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

Pulling model directly from Revel template engine

问题

在Go/Revel的模板中,可以像在erb文件中那样直接从视图中获取模型数据吗?例如:

<script>
  var vm = {
    rows: {{ .ModelName.Rows | jsonify }}
  };
  // 使用客户端JavaScript渲染vm.rows
</script>
<div>
  bla bla
</div>

在Go/Revel的模板中,使用双大括号{{ }}来包裹模型数据,并使用管道符号|来调用相应的函数或过滤器。在上面的示例中,我们使用了.ModelName.Rows来获取模型数据,并使用jsonify过滤器将其转换为JSON格式。然后,我们将结果赋值给JavaScript变量vm.rows,以便在客户端使用JavaScript进行渲染。

英文:

I come from Ruby/PHP background, usually I use pull the model from the View directly without controller, for example inside an erb file:

&lt;script&gt;
  var vm = {
    rows: &lt;%= ModelName.rows.to_json %&gt;
  };
  // render vm.rows using client-side javascript
&lt;/script&gt;
&lt;div&gt; 
  bla bla
&lt;/div&gt;

Is it possible to pull model just like what I did in erb, inside Go/Revel's template?

答案1

得分: 2

将代码直接嵌入模板的方法只适用于解释型语言,如Ruby和PHP。Go模板包支持一些简单的指令(如if、else、range等-详见这里),但这种语法远远不及完整的脚本语言-这可能也不是预期的。你可以从模板中调用诸如to_json方法之类的方法。然而(正如twotwotwo正确指出的那样),你甚至可能不需要额外的方法将数据转换为JSON-如果将其放置在<script>标签之间,Go会自动进行转换。要自定义转换,请实现Marshaler接口,提供一个MarshalJSON方法,如这里所述。

以下示例演示了直接输出结构体,在“script”上下文中使用方法:

package main

import (
	"html/template"
	"log"
	"os"
	"strings"
)

type Greeter struct {
	Repeat     int
	Salutation string
}

func (g Greeter) Perform() string {
	return strings.Repeat(g.Salutation+" ", g.Repeat)
}

func main() {
	sayHi := Greeter{Repeat: 3, Salutation: "Hi!"}
	tmpl, err := template.New("").Parse("{{.}}\n<script>{{.}}</script>\n{{.Perform}}")
	if err != nil {
		log.Fatalf("Parse: %v", err)
	}
	tmpl.Execute(os.Stdout, sayHi)
}

输出:

{3 Hi!}
<script>{"Repeat":3,"Salutation":"Hi!"}</script>
Hi! Hi! Hi!

Revel是基于Go模板包构建的,而不是实现自己的模板系统,因此上述内容也适用于Revel。

英文:

This method of embedding code directly into a template can only be done with interpreted languages such as Ruby and PHP. The Go template packages support some simple instructions (if, else, range etc. - see here for details) but this syntax doesn't come close to a full scripting language - that's probably not intended either. You can call methods such as your to_json method from templates. However (as twotwotwo rightfully pointed out) you may not even need an extra method to convert your data to JSON - if you place it between &lt;script&gt; tags, Go will do the conversion by itself. To customize the conversion, implement the Marshaler interface by providing a MarshalJSON method as described here.

The following example demonstrates outputting a struct directly, in a "script" context and using a method:

package main

import (
	&quot;html/template&quot;
	&quot;log&quot;
	&quot;os&quot;
	&quot;strings&quot;
)

type Greeter struct {
	Repeat     int
	Salutation string
}

func (g Greeter) Perform() string {
	return strings.Repeat(g.Salutation+&quot; &quot;, g.Repeat)
}

func main() {
	sayHi := Greeter{Repeat: 3, Salutation: &quot;Hi!&quot;}
	tmpl, err := template.New(&quot;&quot;).Parse(&quot;{{.}}\n&lt;script&gt;{{.}}&lt;/script&gt;\n{{.Perform}}&quot;)
	if err != nil {
		log.Fatalf(&quot;Parse: %v&quot;, err)
	}
	tmpl.Execute(os.Stdout, sayHi)
}

http://play.golang.org/p/f3HShZfd6H

Output:

{3 Hi!}
&lt;script&gt;{&quot;Repeat&quot;:3,&quot;Salutation&quot;:&quot;Hi!&quot;}&lt;/script&gt;
Hi! Hi! Hi!

Revel builds on the Go template packages rather than implementing its own template system, so the above applies to Revel as well.

huangapple
  • 本文由 发表于 2014年11月24日 20:34:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/27105000.html
匿名

发表评论

匿名网友

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

确定