Go HTML 模板中的自动资产修订文件名
Automatic asset revision filenames in Go HTML templates
我正在寻求帮助,以实现在 Go 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
A subclass of the StaticFilesStorage storage backend which stores the file names it handles by appending the MD5 hash of the file’s content to the filename. For example, the file css/styles.css would also be saved as css/styles.55e7cbb9ba48.css.
The purpose of this storage is to keep serving the old files in case some pages still refer to those files, e.g. because they are cached by you or a 3rd party proxy server. Additionally, it’s very helpful if you want to apply far future Expires headers to the deployed files to speed up the load time for subsequent page visits.
现在我想知道如何在 Go 中最好地实现这一点?我打算提供内置 file server.
中的文件
我目前的想法是:
- 有一个循环来检查目录中的最新样式表文件。听起来很慢。
- 对一般命名的文件执行某种 redirect/rewrite(如 file.css 是根据对文件 hash.css 的请求提供的)。
- 让 Go 自行管理资产命名,附加哈希或时间戳。
- 也许用 nginx 或其他东西更好地处理它?
写一个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 }}" />
此函数在每次渲染模板时解析文件名。一个更聪明的函数可能会在解析名称时缓存名称,或者在启动时遍历目录树以预先构建缓存。
我知道它太旧了,但也许 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
.
我正在寻求帮助,以实现在 Go 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
A subclass of the StaticFilesStorage storage backend which stores the file names it handles by appending the MD5 hash of the file’s content to the filename. For example, the file css/styles.css would also be saved as css/styles.55e7cbb9ba48.css.
The purpose of this storage is to keep serving the old files in case some pages still refer to those files, e.g. because they are cached by you or a 3rd party proxy server. Additionally, it’s very helpful if you want to apply far future Expires headers to the deployed files to speed up the load time for subsequent page visits.
现在我想知道如何在 Go 中最好地实现这一点?我打算提供内置 file server.
中的文件我目前的想法是:
- 有一个循环来检查目录中的最新样式表文件。听起来很慢。
- 对一般命名的文件执行某种 redirect/rewrite(如 file.css 是根据对文件 hash.css 的请求提供的)。
- 让 Go 自行管理资产命名,附加哈希或时间戳。
- 也许用 nginx 或其他东西更好地处理它?
写一个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 }}" />
此函数在每次渲染模板时解析文件名。一个更聪明的函数可能会在解析名称时缓存名称,或者在启动时遍历目录树以预先构建缓存。
我知道它太旧了,但也许 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
.