Go,AppEngine:如何为应用程序构建模板
Posted
技术标签:
【中文标题】Go,AppEngine:如何为应用程序构建模板【英文标题】:Go, AppEngine: How to structure templates for application 【发布时间】:2012-03-23 08:06:32 【问题描述】:人们如何在基于 Go 的 AppEngine 应用程序中处理模板的使用?
具体来说,我正在寻找一个能够提供以下功能的项目结构:
模板和部分模板的分层(目录)结构 允许我在我的模板上使用 html 工具/编辑器(在 xxx.go 文件中嵌入模板文本会使这变得困难) 在开发服务器上自动重新加载模板文本潜在的绊脚石是:
template.ParseGlob() 不会递归遍历。 出于性能原因,建议不要将模板作为原始文本文件上传(因为这些文本文件与执行代码位于不同的服务器上)。请注意,我不是在寻找使用模板包的教程/示例。这更像是一个应用程序结构问题。话虽如此,如果您有解决上述问题的代码,我很乐意看到它。提前致谢。
【问题讨论】:
【参考方案1】:我最喜欢的 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
包将拥有以 /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
。
【讨论】:
不错的布局,凯尔。您可能应该在包含内容模板时添加点 (.),例如template "content" .
。否则,您的 tc 将无法在 products/templates/list.html 中访问
谢谢@alex -- 我已经编辑了答案以包含您的建议。
非常好,凯尔。你建议如何使用这种布局处理模型?我的意思是在 http.go 中声明类型或者创建一个 model.go 文件?提前致谢。
嗨@PatrickLinskey,您的app.yaml
文件应该不包含templates
目录。 App Engine 将app.yaml
文件中列出的目录视为静态资源,但app.yaml
文件中未列出的任何目录都可以通过代码访问。我希望这会有所帮助。
@425nesp,是的,只需创建另一个var detailTmpl = ...
将list.html
替换为detail.html
并在同一个http.go
文件中创建一个func detailHandler(...
。【参考方案2】:
提前道歉,因为这篇文章不是你真正想要的,你可能已经听过我要说的一百万次了。不过,总比没有帖子好,所以就这样吧:
Go 1 将很快发布(一两周内)。我很肯定 App Engine 将在不久之后转而支持 Go 1 over r60。模板 corelibs(以及其他库)在那个时候得到了相当多的使用,因此由于语言发生了许多变化,因此找到与自己相关的流行的做事方式有点混乱。
话虽如此,我已经看到不少人以不同的方式解决这个问题,但其中很少有人是特定于 AppEngine 的,因为在 Go 中完成的大部分工作都与该语言保持同步(它有长期与r60不兼容)。如果你想查看人们在类似项目中使用的一些代码,你应该跳上 IRC 并询问。模板是一个热门话题,我只使用了非常基本的功能——我从未接触过集合。 IRC 非常友好,你可以在那里学到很多东西。它绝对是目前该语言除了文档之外的最佳资源。如果你还不知道 IRC 频道是 FreeNode 上的#go-nuts。
感谢您阅读并祝您在 App Engine 上开发顺利。我希望 Go 1 的更新能够迅速进行。
【讨论】:
谢谢。基于 Go1 的 SDK 测试版已经发布:groups.google.com/forum/?fromgroups#!topic/google-appengine-go/… 新的模板包已经相对稳定了几个月,所以我希望已经对这些问题进行了一些思考。即使是针对 AppEngine 的答案,我也会很高兴。 但是我会听取您的建议并在 IRC 上询问。我会回来报告的。 IRC 不是很有成果,但邮件列表上有这样的讨论:groups.google.com/forum/?fromgroups#!topic/google-appengine-go/…以上是关于Go,AppEngine:如何为应用程序构建模板的主要内容,如果未能解决你的问题,请参考以下文章
如何为 Golang 和 AppEngine 设置 VScode 调试会话?