Go, AppEngine:如何为应用程序构建模板结构

huangapple go评论73阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2012年3月6日 04:39:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/9573644.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定