Возможно ли иметь вложенные шаблоны в Go, используя стандартную библиотеку? (Google App Engine)
Как получить вложенные шаблоны, такие как Jinja, в среде выполнения python. TBC, что я имею в виду, как у меня есть куча шаблонов, наследуемых от базовых шаблонов, просто заполнение в блоках базовых шаблонов, таких как Jinja/django-templates. Возможно ли использовать только html/template
в стандартной библиотеке.
Если это не возможно, каковы мои альтернативы. Усы, похоже, являются опцией, но тогда я буду упускать из виду те приятные тонкие функции html/template
, как контекстно-зависимое экранирование и т.д.? Какие другие альтернативы?
(Окружающая среда: Google App Engin, Go runtime v1, Dev - Mac OSx lion)
Спасибо за чтение.
Ответы
Ответ 1
Да, это возможно. A html.Template
- фактически набор файлов шаблонов. Если вы выполняете определенный блок в этом наборе, он имеет доступ ко всем остальным блокам, определенным в этом наборе.
Если вы создаете карту таких наборов шаблонов по своему усмотрению, у вас есть та же самая гибкость, которую предлагает Jinja/Django. Единственное различие заключается в том, что пакет html/template не имеет прямого доступа к файловой системе, поэтому вам придется самостоятельно анализировать и составлять шаблоны.
Рассмотрим следующий пример с двумя разными страницами ( "index.html" и "other.html" ), которые наследуются от "base.html":
// Content of base.html:
{{define "base"}}<html>
<head>{{template "head" .}}</head>
<body>{{template "body" .}}</body>
</html>{{end}}
// Content of index.html:
{{define "head"}}<title>index</title>{{end}}
{{define "body"}}index{{end}}
// Content of other.html:
{{define "head"}}<title>other</title>{{end}}
{{define "body"}}other{{end}}
И следующая карта наборов шаблонов:
tmpl := make(map[string]*template.Template)
tmpl["index.html"] = template.Must(template.ParseFiles("index.html", "base.html"))
tmpl["other.html"] = template.Must(template.ParseFiles("other.html", "base.html"))
Теперь вы можете отобразить страницу "index.html", вызвав
tmpl["index.html"].Execute("base", data)
и вы можете отобразить страницу "other.html", вызвав
tmpl["other.html"].Execute("base", data)
С некоторыми трюками (например, последовательное соглашение об именах ваших файлов шаблонов), возможно даже создать карту tmpl
автоматически.
Ответ 2
Обратите внимание, что при выполнении базового шаблона вы должны передавать значения до дочерних шаблонов, здесь я просто передаю ".", чтобы все было передано.
шаблон отображает {{.}}
{{define "base"}}
<html>
<div class="container">
{{.}}
{{template "content" .}}
</div>
</body>
</html>
{{end}}
шаблон два отображает {{.domains}}, который передается в родительский.
{{define "content"}}
{{.domains}}
{{end}}
Обратите внимание, что если мы использовали {{template "content".}} вместо {{template "content".}}, то домен домена не будет доступен из шаблона содержимого.
DomainsData := make(map[string]interface{})
DomainsData["domains"] = domains.Domains
if err := groupsTemplate.ExecuteTemplate(w, "base", DomainsData); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
Ответ 3
Используйте Pongo, который представляет собой супер-набор шаблонов Go, которые поддерживают теги {{extends}} и {{block}} для наследования шаблонов, как Django.
Ответ 4
Я возвращаюсь к этому ответу в течение нескольких дней, наконец, запустил пулю и написал для этого небольшой слой абстракции/предварительный процессор. Это в основном:
- Добавляет ключевое слово 'extends' в шаблоны.
- Позволяет переопределять вызовы 'define' (поэтому значения по умолчанию для greggory возможны)
- Разрешает не определенные "шаблонные" вызовы, они просто дают пустую строку
- Устанавливает значение по умолчанию. в "шаблонных" вызовах. родительского
https://github.com/daemonl/go_sweetpl