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