Одна из моих любимых функций 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)
}
}
Этот подход очень интересен, поскольку делает совместное использование приложений / пакетов тривиальным.Если я напишу пакет, который обрабатывает аутентификацию, которая становится владельцем /auth
url.Любой разработчик, который затем добавляет пакет в корневой каталог своего продукта, сразу же получает всю функциональность.Все, что им нужно сделать, это создать базовый шаблон (templates/base.html
) и направить своих пользователей на /auth
.