다른 접근 방법 I가 꿈과 협력 재능있는 디바이스가되었다는 템플릿을 정의하고 볼되지 않는 포함 찾기 위해 템플릿 인스턴스를 사후 처리합니다 일치하는 파일에 대한 파일 시스템을 찾고 발견 된 각각에 대해 파싱합니다. 그런 다음 렌더링합니다. 다음과 같이이 당신에게 설정을 제공
:
전망/index.html을 :
{{template "/includes/page-wrapper.html" .}}
{{define "body"}}
<div>Page guts go here</div>
{{end}}
{{define "head_section"}}
<title>Title Tag</title>
{{end}}
가/페이지 wrapper.html 포함
<html>
<head>
{{block "head_section" .}}{{end}}
<head>
<body>
{{template "body" .}}
</body>
</html>
그리고 당신의 ServeHTTP()
방법을 찾습니다 파일을 "views"디렉토리에로드하고 파싱 한 다음 TmplIncludeAll()
(아래)을 호출합니다.
다음과 같은 몇 가지 기능만으로 동일한 기본 개념을 적용했습니다. t
은 파싱 된 후 렌더링되기 전의 템플릿입니다. fs
은 "보기"및 "포함"라이브 (위 참조)가있는 디렉토리입니다.
func TmplIncludeAll(fs http.FileSystem, t *template.Template) error {
tlist := t.Templates()
for _, et := range tlist {
if et != nil && et.Tree != nil && et.Tree.Root != nil {
err := TmplIncludeNode(fs, et, et.Tree.Root)
if err != nil {
return err
}
}
}
return nil
}
func TmplIncludeNode(fs http.FileSystem, t *template.Template, node parse.Node) error {
if node == nil {
return nil
}
switch node := node.(type) {
case *parse.TemplateNode:
if node == nil {
return nil
}
// if template is already defined, do nothing
tlist := t.Templates()
for _, et := range tlist {
if node.Name == et.Name() {
return nil
}
}
t2 := t.New(node.Name)
f, err := fs.Open(node.Name)
if err != nil {
return err
}
defer f.Close()
b, err := ioutil.ReadAll(f)
if err != nil {
return err
}
_, err = t2.Parse(string(b))
if err != nil {
return err
}
// start over again, will stop recursing when there are no more templates to include
return TmplIncludeAll(fs, t)
case *parse.ListNode:
if node == nil {
return nil
}
for _, node := range node.Nodes {
err := TmplIncludeNode(fs, t, node)
if err != nil {
return err
}
}
case *parse.IfNode:
if err := TmplIncludeNode(fs, t, node.BranchNode.List); err != nil {
return err
}
if err := TmplIncludeNode(fs, t, node.BranchNode.ElseList); err != nil {
return err
}
case *parse.RangeNode:
if err := TmplIncludeNode(fs, t, node.BranchNode.List); err != nil {
return err
}
if err := TmplIncludeNode(fs, t, node.BranchNode.ElseList); err != nil {
return err
}
case *parse.WithNode:
if err := TmplIncludeNode(fs, t, node.BranchNode.List); err != nil {
return err
}
if err := TmplIncludeNode(fs, t, node.BranchNode.ElseList); err != nil {
return err
}
}
return nil
}
이것은 내가 가장 좋아하는 방법이며 지금 당분간 이것을 사용해 왔습니다. 템플릿 렌더링이 하나 뿐이므로 오류 메시지가 훌륭하고 깨끗하며 Go 템플리트 마크 업은 매우 읽기 쉽고 분명합니다. html/template의 용기가 있다면 좋을 것입니다.템플릿을 사용하면 구현이 간단 해졌지만 전반적으로 IMO는 훌륭한 솔루션입니다.
@ Boushley gotcha. 내가 방금 사용했던 솔루션을 제공하는 방금 게시 한 다른 대답을 참조하십시오. –
그동안 답변이 있으십니까? – Kiril
나는 또한 그것을 할 방법을 찾고있다 ... – Creasixtine