一尘不染

开始,AppEngine:如何为应用程序构建模板

go

人们如何在基于Go的AppEngine应用程序中处理模板的使用?

具体来说,我正在寻找一个具有以下功能的项目结构:

  • 模板和部分模板的分层(目录)结构
  • 请允许我在模板上使用HTML工具/编辑器(在xxx.go文件中嵌入模板文本使此操作很困难)
  • 在开发服务器上时自动重新加载模板文本

潜在的绊脚石是:

  • template.ParseGlob()不会递归遍历。
  • 出于性能原因,建议不要将模板作为原始文本文件上传(因为这些文本文件与执行代码位于不同的服务器上)。

请注意,我不是在寻找使用模板包的教程/示例。这更多是一个应用程序结构问题。话虽如此,如果您有解决上述问题的代码,我很乐意看到。提前致谢。


阅读 243

收藏
2020-07-02

共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前缀的所有权。例如,products下面的包github.com/storeski/appengine/products将拥有任何以开头的入站URL
/products

使用这种模块化方法,将模板存储在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)
  }
}

这种方法非常令人兴奋,因为它使应用程序/软件包的共享变得微不足道。如果我编写了一个处理身份验证的程序包,则该程序包获取/authURL的所有权。然后,任何将软件包立即添加到其产品根目录的开发人员都具有所有功能。他们要做的就是创建一个基本模板(templates/base.html)并将其用户定向到/auth

2020-07-02