去,AppEngine:如何构建应用程序的模板 [英] Go, AppEngine: How to structure templates for application
问题描述
特别是,我正在寻找一个项目结构,它提供了以下功能:
- 模板和部分模板的分层结构(目录)
- 允许我使用HTML工具/编辑器(在xxx.go文件中嵌入模板文本使这变得困难)
- 在开发服务器上自动重新加载模板文本
潜在的绊脚石是:
- template.ParseGlob()不会递归地遍历。
- 由于性能方面的原因,建议不要以原始文本文件的形式上传您的模板(因为这些文本文件驻留在不同的服务器上,而不是执行代码)
请注意,我不在寻找使用模板包的教程/示例。这更多的是一个应用程序结构问题。这就是说,如果你有解决上述问题的代码,我很乐意看到它。
Go最喜欢的功能之一是可以轻松地在包内添加处理程序。这大大简化了编写模块化代码的过程。
例如:
文件结构 strong>
| - app.yaml
| - app
| + - http.go
| - 模板
| + - base.html
+ - github.com
+ - storeski
+ - appengine
| - 产品
| | - http.go
| + - 模板
| | - list.html
| + - detail.html
+ - 帐户
| - http.go
+ - 模板
| - overview.html
+ - 通知.html
每个软件包都有一个http.go文件,它拥有一个url前缀的所有权。例如, github.com/storeski/appengine/products
下的产品
包将拥有以<$开头的任何入站网址C $ C> /产品。
使用这种模块化方法,将模板存储在产品
包中是有益的。如果您想为该网站维护一个一致的基本模板,则可以在
示例
templates / base.html
$ b <!DOCTYPE HTML>
< html>
< head>
< title> {{。Store.Title}}< / title>
< / head>
< body>
< div id =content>
{{templatecontent。}}
< / div>
< / body>
< / html>
github.com/storeski/appengine/products/templates/list.html
{{definecontent}}
< h1>产品列表< / 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] =存储
tc [产品] =产品
如果err:= listTmpl.Execute(w,tc); err!= nil {
http.Error(w,err.Error(),http.StatusInternalServerError)
}
}
这种方法非常令人兴奋,因为它使得应用程序/包的分享变得微不足道。如果我编写处理身份验证的程序包,它取得 / auth
url的所有权。然后,任何开发人员立即将该软件包添加到他们的产品根目录中即可获得所有功能。他们所要做的就是创建一个基础模板( templates / base.html
),并将他们的用户指向 / auth
。
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.
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
.
这篇关于去,AppEngine:如何构建应用程序的模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!