英文:
Go, AppEngine: How to structure templates for application
问题
人们如何处理在他们的基于Go的AppEngine应用程序中使用模板的问题?
具体来说,我正在寻找一个项目结构,可以提供以下功能:
- 模板和部分模板的分层(目录)结构
- 允许我在模板上使用HTML工具/编辑器(将模板文本嵌入xxx.go文件中会使此操作变得困难)
- 在开发服务器上自动重新加载模板文本
可能的障碍是:
- template.ParseGlob()不会递归遍历。
- 出于性能原因,建议不要将模板作为原始文本文件上传(因为这些文本文件位于与执行代码不同的服务器上)。
请注意,我不是在寻找有关模板包使用的教程/示例。这更多是一个应用程序结构问题。话虽如此,如果您有解决上述问题的代码,我很乐意看到。提前感谢。
英文:
How are people handling the use of templates in their Go-based AppEngine applications?
Specifically, I'm looking for a project structure that affords the following:
- Hierarchical (directory) structure of templates and partial templates
- Allow me to use HTML tools/editors on my templates (embedding template text in xxx.go files makes this difficult)
- Automatic reload of template text when on dev server
Potential stumbling blocks are:
- template.ParseGlob() will not traverse recursively.
- For performance reasons it has been recommended not to upload your templates as raw text files (because those text files reside on different servers than executing code).
Please note that I am not looking for a tutorial/examples of the use of the template package. This is more of an app structure question. That being said, if you have code that solves the above problems, I would love to see it. Thanks in advance.
答案1
得分: 69
我最喜欢 Go 语言的一个特性是能够轻松地在包内添加处理程序。这极大地简化了编写模块化代码的过程。
例如:
文件结构
|-- app.yaml
|-- app
| +-- http.go
|-- templates
| +-- base.html
+-- github.com
+-- storeski
+-- appengine
|-- products
| |-- http.go
| +-- templates
| |-- list.html
| +-- detail.html
+-- account
|-- http.go
+-- templates
|-- overview.html
+-- notifications.html
每个包都有一个名为 http.go 的文件,它负责处理一个 URL 前缀。例如,github.com/storeski/appengine/products
包会处理以 /products
开头的任何传入 URL。
采用这种模块化的方法,将模板存储在 products
包内是有益的。如果您想为网站保持一致的基础模板,可以约定扩展 templates/base.html
。
示例
templates/base.html
<!DOCTYPE HTML>
<html>
<head>
<title>{{.Store.Title}}</title>
</head>
<body>
<div id="content">
{{template "content" .}}
</div>
</body>
</html>
github.com/storeski/appengine/products/templates/list.html
{{define "content"}}
<h1> Products List </h1>
{{end}}
github.com/storeski/appengine/products/http.go
func init() {
http.HandleFunc("/products", listHandler)
}
var listTmpl = template.Must(template.ParseFiles("templates/base.html",
"github.com/storeski/appengine/products/templates/list.html"))
func listHandler(w http.ResponseWriter, r *http.Request) {
tc := make(map[string]interface{})
tc["Store"] = Store
tc["Products"] = Products
if err := listTmpl.Execute(w, tc); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
这种方法非常令人兴奋,因为它使得共享应用/包变得非常简单。如果我编写了一个处理身份验证的包,它负责处理 /auth
URL。任何开发者只需将该包添加到他们的产品根目录,即可立即获得所有功能。他们只需要创建一个基础模板(templates/base.html
)并将用户重定向到 /auth
。
英文:
One of my favorite features of Go is the ability to easily add handlers inside of packages. This greatly simplifies the processes of writing modular code.
For Example:
File Structure
|-- app.yaml
|-- app
| +-- http.go
|-- templates
| +-- base.html
+-- github.com
+-- storeski
+-- appengine
|-- products
| |-- http.go
| +-- templates
| |-- list.html
| +-- detail.html
+-- account
|-- http.go
+-- templates
|-- overview.html
+-- notifications.html
Each packages has a http.go file that takes ownership of a url prefix. For example the products
package under github.com/storeski/appengine/products
would own any inbound url starting with /products
.
With this modular approach it is beneficial to store the templates within the products
package. If you would like to maintain a consistant base template for the site you can establish a convention where you extend templates/base.html
.
Example
templates/base.html
<!DOCTYPE HTML>
<html>
<head>
<title>{{.Store.Title}}</title>
</head>
<body>
<div id="content">
{{template "content" .}}
</div>
</body>
</html>
github.com/storeski/appengine/products/templates/list.html
{{define "content"}}
<h1> Products List </h1>
{{end}}
github.com/storeski/appengine/products/http.go
func init() {
http.HandleFunc("/products", listHandler)
}
var listTmpl = template.Must(template.ParseFiles("templates/base.html",
"github.com/storeski/appengine/products/templates/list.html"))
func listHandler(w http.ResponseWriter, r *http.Request) {
tc := make(map[string]interface{})
tc["Store"] = Store
tc["Products"] = Products
if err := listTmpl.Execute(w, tc); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
This approach is very exciting because it makes the sharing of apps/package trivial. If I write a package that handles authentication which takes ownership of the /auth
url. Any developer that, then, adds the package to their product root instantly has all of the functionality. All they have to do is create a base template (templates/base.html
) and direct their users to /auth
.
答案2
得分: 0
事先道歉,因为这篇帖子可能不是你真正想要的,而且你可能已经听过我要说的一百万次了。不过,总比没有帖子好,所以我就说了:
Go 1很快就会发布(大约在一两周内)。我相信App Engine很快就会转而支持Go 1而不是r60。在那段时间里,模板核心库(以及其他库)经历了很多变动,所以很难找到与自己相关的流行做法,因为语言正在经历许多变化。
话虽如此,我看到很多人以不同的方式解决了这个问题,但很少有人是针对AppEngine特定的,因为大部分使用Go的工作都与语言保持同步(长期以来与r60不兼容)。如果你想看看人们为类似项目使用的一些代码,你可以进入IRC并询问。模板是一个热门话题,我只使用了它们的基本功能,从来没有碰过集合。IRC非常友好,你可以在那里学到很多东西。除了文档之外,它绝对是目前语言的最佳资源。如果你还不知道,IRC频道是FreeNode上的#go-nuts。
感谢阅读,祝你在App Engine上开发好运。希望Go 1的更新顺利进行。
英文:
Apologies beforehand because this post isn't what you're really looking for and you may have already heard what I'm about to say a million times. It's better than no posts at all though, so here it goes:
Go 1 will be released very soon (in a week or two). I'm positive that App Engine will be switching to supporting Go 1 over r60 relatively soon after. The template corelibs (among other libs) got played with a decent amount in that time so it's kind of a mess to find the popular way of doing things relevant to oneself because of the many changes going through the language.
That being said, I've seen quite a few people tackling this different ways, but very few of them were AppEngine specific because most of the working being done in Go is kept up-to-date with the language (which has long been non-compatible with r60). If you want to see some of the code that people have been using for similar projects, you should hop on IRC and ask. Templates are a popular topic and I've only very used basic functionality with them -- I've never touched sets. The IRC is super friendly and you can learn a lot there. It's definitely the best resource besides the docs right now for the language. In case you don't already know the IRC channel is #go-nuts on FreeNode.
Thanks for reading and good luck developing on App Engine. I hope the updates to Go 1 go swiftly.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论