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 调试会话?

如何为Google App Engine实例指定区域?

如何为 iOS 应用程序构建内部地图导航?

如何为速度模板编写单元测试?

如何为我的App Engine应用设置自定义npm启动脚本?

如何为滚动文件系统日志配置 uber-go/zap 记录器?