Go,AppEngine:如何为应用程序构建模板 [英] Go, AppEngine: How to structure templates for application

查看:34
本文介绍了Go,AppEngine:如何为应用程序构建模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

具体来说,我正在寻找能够提供以下内容的项目结构:

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

潜在的绊脚石是:

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

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

解决方案

我最喜欢的 Go 特性之一是能够轻松地在包内添加处理程序.这大大简化了编写模块化代码的过程.

例如:

文件结构

|-- app.yaml|-- 应用|+-- http.go|-- 模板|+-- base.html+-- github.com+-- 斯托斯基+-- 应用引擎|-- 产品||-- http.go|+-- 模板||-- 列表.html|+-- detail.html+-- 帐户|-- http.go+-- 模板|-- 概览.html+-- 通知.html

每个包都有一个 http.go 文件,该文件拥有 url 前缀的所有权.例如,github.com/storeski/appengine/products 下的 products 包将拥有以 /products 开头的任何入站 url.

采用这种模块化方法,将模板存储在 products 包中是有益的.如果您想为站点维护一个一致的基本模板,您可以建立一个约定来扩展 templates/base.html.

示例

templates/base.html

<头><title>{{.Store.Title}}</title><身体><div id="内容">{{模板内容".}}

github.com/storeski/appengine/products/templates/list.html

{{定义内容"}}<h1>产品列表 </h1>{{结尾}}

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["商店"] = 商店tc["产品"] = 产品如果错误:= listTmpl.Execute(w, tc);错误!= 零{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.

这篇关于Go,AppEngine:如何为应用程序构建模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆