Go html模板

时间:2016-01-01 17:54:41

标签: templates go assets

我正在寻找帮助实现在golang html模板中自动包含版本化文件名的内容。例如,在我的模板中,头部有这样的东西:

<link rel="stylesheet" href="{{ .MyCssFile }}" />

样式表本身有一大块md5哈希值附加到名为gulp-rev

的gulp脚本中。
stylesheet-d861367de2.css

目的是确保浏览器获取新的更改,但也允许缓存。下面是Django中的示例实现,以获得更好的解释:

https://docs.djangoproject.com/en/1.9/ref/contrib/staticfiles/#manifeststaticfilesstorage

  

StaticFilesStorage存储后端的子类,它通过将文件内容的MD5哈希附加到文件名来存储它处理的文件名。例如,文件css / styles.css也将保存为css / styles.55e7cbb9ba48.css。

     

此存储的目的是在某些页面仍然引用这些文件的情况下继续提供旧文件,例如:因为它们是由您或第三方代理服务器缓存的。此外,如果您希望将远期的Expires标头应用于已部署的文件,以加快后续页面访问的加载时间,这将非常有用。

现在我想知道如何在Go中最好地解决这个问题?我打算从内置文件服务器提供文件。

https://golang.org/pkg/net/http/#FileServer

我目前的想法是:

  • 有一个循环检查目录中的最新样式表文件。听起来很慢
  • 对一般命名的文件进行某种重定向/重写(因为file.css是在对file-hash.css的请求中提供的)
  • 管理资产命名本身,附加哈希或时间戳。
  • 也许用nginx或其他东西可以更好地处理它?<​​/ li>

2 个答案:

答案 0 :(得分:2)

写一个template function来解析名称。这是一个示例模板函数:

func resolveName(p string) (string, error) {
  i := strings.LastIndex(p, ".")
  if i < 0 {
    i = len(p)
  }
  g := p[:i] + "-*" + p[i:]
  matches, err := filepath.Glob(g)
  if err != nil {
    return "", err
  }
  if len(matches) != 1 {
    return "", fmt.Errorf("%d matches for %s", len(matches), p)
  }
  return matches[0], nil
}

以下是注册为“resolveName”函数时如何在模板中使用它:

<link rel="stylesheet" href="{{ .MyCssFile | resolveName }}" />

playground example

此函数在每次呈现模板时解析文件的名称。一个更聪明的函数可能会在解析名称时缓存名称,或者在启动时遍历目录树以预构建缓存。

答案 1 :(得分:0)

我知道它太旧了,但是也许this library会为您提供帮助。它允许收集和散列静态文件。它还具有将文件路径从原始位置反向到哈希位置的功能:

staticFilesPrefix := "/static/"
staticFilesRoot := "output/dir"

storage := NewStorage(staticFilesRoot)
err := storage.LoadManifest()

funcs := template.FuncMap{
    "static": func(relPath string) string {
        return staticFilesPrefix + storage.Resolve(relPath)
    },
}
tmpl := template.Must(
    template.New("").Funcs(funcs).ParseFiles("templates/main.tpl")
)

现在,您可以在{{static "css/style.css"}}这样的模板中调用静态函数。呼叫将被转换为/static/css/style.d41d8cd98f00b204e9800998ecf8427e.css