golang实现Closure/Soy模板渲染的插件库Soyofficial spec的使用

Golang实现Closure/Soy模板渲染的插件库Soyofficial spec的使用

Soy是Google Closure Templates的Go语言实现,它允许你在Go应用中使用Soy模板引擎。下面是如何使用这个库的完整示例。

安装

首先确保你的Go版本在1.12或以上,然后设置环境变量:

export GO111MODULE=on

然后安装soy库:

go get github.com/robfig/soy

基本使用示例

下面是一个完整的示例,展示如何使用soy库渲染模板:

package main

import (
	"fmt"
	"github.com/robfig/soy"
)

func main() {
	// 1. 创建模板集
	templateSet := soy.NewSet()

	// 2. 注册模板
	templateSet.AddTemplate("example.soy", `{namespace example}

/**
 * Greets a person using "Hello" by default.
 * @param name The name of the person.
 * @param? greetingWord Optional greeting word to use instead of "Hello".
 */
{template .helloName}
  {$greetingWord ?: 'Hello'}, {$name}!
{/template}`)

	// 3. 编译模板
	_, err := templateSet.Compile()
	if err != nil {
		panic(err)
	}

	// 4. 渲染模板
	output, err := templateSet.Render("example.helloName", soy.Vars{
		"name": "World",
	})
	if err != nil {
		panic(err)
	}

	fmt.Println(output) // 输出: Hello, World!
}

带参数的模板示例

这是一个更复杂的示例,展示如何使用带参数的模板:

package main

import (
	"fmt"
	"github.com/robfig/soy"
)

func main() {
	templateSet := soy.NewSet()
	
	// 定义带参数的模板
	templateSet.AddTemplate("user.soy", `{namespace user}

/**
 * Displays user information
 * @param user The user object containing name and age
 */
{template .userInfo}
  <div class="user">
    <h1>{$user.name}</h1>
    <p>Age: {$user.age}</p>
    {if $user.isAdmin}
      <p class="admin">Administrator</p>
    {/if}
  </div>
{/template}`)

	_, err := templateSet.Compile()
	if err != nil {
		panic(err)
	}

	// 渲染带参数的模板
	output, err := templateSet.Render("user.userInfo", soy.Vars{
		"user": map[string]interface{}{
			"name":    "John Doe",
			"age":     30,
			"isAdmin": true,
		},
	})
	if err != nil {
		panic(err)
	}

	fmt.Println(output)
	// 输出:
	// <div class="user">
	//   <h1>John Doe</h1>
	//   <p>Age: 30</p>
	//   <p class="admin">Administrator</p>
	// </div>
}

从文件加载模板

通常你会将模板存储在单独的文件中,下面是如何从文件加载模板的示例:

package main

import (
	"fmt"
	"github.com/robfig/soy"
	"io/ioutil"
	"path/filepath"
)

func main() {
	templateSet := soy.NewSet()
	
	// 从文件加载模板
	templatePath := filepath.Join("templates", "welcome.soy")
	templateContent, err := ioutil.ReadFile(templatePath)
	if err != nil {
		panic(err)
	}
	
	templateSet.AddTemplate("welcome.soy", string(templateContent))
	
	_, err = templateSet.Compile()
	if err != nil {
		panic(err)
	}
	
	output, err := templateSet.Render("welcome.greeting", soy.Vars{
		"name": "Alice",
	})
	if err != nil {
		panic(err)
	}
	
	fmt.Println(output)
}

假设welcome.soy文件内容如下:

{namespace welcome}

/**
 * Greets a user
 * @param name The name of the user
 */
{template .greeting}
  Welcome, {$name}!
{/template}

高级功能

自定义函数

你可以注册自定义函数在模板中使用:

package main

import (
	"fmt"
	"github.com/robfig/soy"
	"strings"
)

func main() {
	templateSet := soy.NewSet()
	
	// 注册自定义函数
	templateSet.AddFunc("toUpper", func(in string) string {
		return strings.ToUpper(in)
	})
	
	templateSet.AddTemplate("funcs.soy", `{namespace funcs}

{template .useFunc}
  Original: {$name}
  Upper: {toUpper($name)}
{/template}`)

	_, err := templateSet.Compile()
	if err != nil {
		panic(err)
	}
	
	output, err := templateSet.Render("funcs.useFunc", soy.Vars{
		"name": "hello world",
	})
	if err != nil {
		panic(err)
	}
	
	fmt.Println(output)
	// 输出:
	// Original: hello world
	// Upper: HELLO WORLD
}

模板继承

Soy支持模板继承,这是一个示例:

package main

import (
	"fmt"
	"github.com/robfig/soy"
)

func main() {
	templateSet := soy.NewSet()
	
	templateSet.AddTemplate("base.soy", `{namespace base}

{template .baseTemplate}
  <html>
    <head>
      <title>{$title}</title>
    </head>
    <body>
      {delcall .content /}
    </body>
  </html>
{/template}`)

	templateSet.AddTemplate("page.soy", `{namespace page}

{template .pageTemplate}
  {delpackage base}
  {call .baseTemplate}
    {param content}
      <h1>{$heading}</h1>
      <p>{$body}</p>
    {/param}
    {param title: 'My Page' /}
  {/call}
{/template}`)

	_, err := templateSet.Compile()
	if err != nil {
		panic(err)
	}
	
	output, err := templateSet.Render("page.pageTemplate", soy.Vars{
		"heading": "Welcome",
		"body":    "This is the content of the page.",
	})
	if err != nil {
		panic(err)
	}
	
	fmt.Println(output)
	// 输出:
	// <html>
	//   <head>
	//     <title>My Page</title>
	//   </head>
	//   <body>
	//     <h1>Welcome</h1>
	//     <p>This is the content of the page.</p>
	//   </body>
	// </html>
}

注意事项

  1. 确保你的Go版本在1.12或以上
  2. 使用前设置环境变量 GO111MODULE=on
  3. 模板语法遵循Google Closure Templates规范
  4. 复杂的模板建议拆分成多个文件管理

以上示例展示了soy库的基本和高级用法,你可以根据需要组合这些功能来构建复杂的模板系统。


更多关于golang实现Closure/Soy模板渲染的插件库Soyofficial spec的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang实现Closure/Soy模板渲染的插件库Soyofficial spec的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang 实现 Closure/Soy 模板渲染的 Soyofficial 库使用指南

Closure Templates (也称为 Soy 模板) 是 Google 开发的一种模板语言,Soyofficial 是 Go 语言实现的 Soy 模板渲染库。下面我将介绍如何在 Go 项目中使用 Soyofficial 库。

安装 Soyofficial

首先需要安装 Soyofficial 库:

go get github.com/robfig/soy

基本使用方法

1. 定义 Soy 模板

创建一个简单的 Soy 模板文件 example.soy:

{namespace example}

/**
 * 问候模板
 * @param name 姓名
 */
{template .greet}
  Hello, {$name}!
{/template}

2. Go 代码渲染模板

package main

import (
	"fmt"
	"os"

	"github.com/robfig/soy"
)

func main() {
	// 1. 创建 Soy 配置
	config := soy.NewConfig()

	// 2. 注册模板文件
	err := config.AddTemplateFile("example.soy")
	if err != nil {
		fmt.Printf("加载模板文件失败: %v\n", err)
		os.Exit(1)
	}

	// 3. 创建渲染器
	renderer, err := config.NewRenderer("example.greet")
	if err != nil {
		fmt.Printf("创建渲染器失败: %v\n", err)
		os.Exit(1)
	}

	// 4. 渲染模板
	data := soy.Params{
		"name": "World",
	}
	result, err := renderer.Render(data)
	if err != nil {
		fmt.Printf("渲染失败: %v\n", err)
		os.Exit(1)
	}

	fmt.Println(result) // 输出: Hello, World!
}

高级功能

1. 使用模板继承

Soy 支持模板继承,可以创建基础模板和派生模板:

{namespace layouts}

{template .base}
  <html>
    <head>
      <title>{$title}</title>
    </head>
    <body>
      {call .content /}
    </body>
  </html>
{/template}

{template .page}
  {call .base}
    {param title: $title /}
    {param content}
      <h1>{$title}</h1>
      <p>{$body}</p>
    {/param}
  {/call}
{/template}

2. 在 Go 中渲染继承模板

// 注册模板
err := config.AddTemplateFile("layouts.soy")
if err != nil {
    // 处理错误
}

// 渲染页面
renderer, err := config.NewRenderer("layouts.page")
if err != nil {
    // 处理错误
}

data := soy.Params{
    "title": "My Page",
    "body":  "This is the page content.",
}
result, err := renderer.Render(data)

3. 使用自定义函数

Soy 支持自定义函数:

config := soy.NewConfig()

// 注册自定义函数
config.RegisterFn("truncate", func(s string, max int) string {
    if len(s) <= max {
        return s
    }
    return s[:max] + "..."
})

// 在模板中使用
// {$text|truncate:10}

4. 模板缓存

对于生产环境,建议启用模板缓存:

config := soy.NewConfig()
config.EnableCache(true) // 启用缓存

完整示例

下面是一个完整的 Web 服务器示例,使用 Soy 模板渲染 HTML:

package main

import (
	"fmt"
	"net/http"

	"github.com/robfig/soy"
)

func main() {
	// 配置 Soy
	config := soy.NewConfig()
	err := config.AddTemplateFile("templates/greeting.soy")
	if err != nil {
		panic(err)
	}

	// 注册 HTTP 处理函数
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		// 获取查询参数
		name := r.URL.Query().Get("name")
		if name == "" {
			name = "Guest"
		}

		// 创建渲染器
		renderer, err := config.NewRenderer("example.greet")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		// 渲染模板
		data := soy.Params{"name": name}
		result, err := renderer.Render(data)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		// 输出结果
		w.Header().Set("Content-Type", "text/html")
		fmt.Fprint(w, result)
	})

	// 启动服务器
	fmt.Println("Server started at :8080")
	http.ListenAndServe(":8080", nil)
}

注意事项

  1. Soyofficial 实现了大部分 Soy 模板功能,但不是 100% 兼容 Google 的官方实现
  2. 对于复杂项目,建议将模板文件组织在单独的目录中
  3. 生产环境中应考虑预编译模板以提高性能
  4. 模板文件通常使用 .soy 扩展名

通过以上示例,你应该能够在 Go 项目中使用 Soyofficial 库来渲染 Soy 模板了。这个库特别适合需要与前端共享模板逻辑的项目,或者从其他使用 Soy 模板的系统迁移到 Go 的项目。

回到顶部