[google-app-engine] 표준 라이브러리를 사용하여 Go에서 중첩 된 템플릿을 가질 수 있습니까?

Python 런타임에서 Jinja와 같은 중첩 템플릿을 얻으려면 어떻게해야합니까? TBC가 의미하는 바는 Jinja / django-templates처럼 기본 템플릿의 블록으로 파일을 작성하여 기본 템플릿에서 여러 템플릿을 상속받는 방법입니다. html/template표준 라이브러리 에서만 사용할 수 있습니까?

그것이 가능성이 아니라면 내 대안은 무엇입니까? 콧수염은 옵션 인 것 같지만 html/template상황에 맞는 이스케이프와 같은 멋진 미묘한 기능을 놓치고 있습니까? 다른 대안은 무엇입니까?

(환경 : Google App Engin, Go 런타임 v1, Dev-Mac OSx lion)

읽어 주셔서 감사합니다.



답변

네 가능합니다. A html.Template는 실제로 템플릿 파일 집합입니다. 이 세트에서 정의 된 블록을 실행하면이 세트에 정의 된 다른 모든 블록에 액세스 할 수 있습니다.

이러한 템플릿 세트의 맵을 직접 생성하면 기본적으로 Jinja / Django가 제공하는 것과 동일한 유연성을 갖게됩니다. 유일한 차이점은 html / template 패키지는 파일 시스템에 직접 액세스 할 수 없으므로 직접 템플릿 을 구문 분석하고 구성해야한다는 것입니다.

둘 다 “base.html”에서 상속되는 두 개의 다른 페이지 ( “index.html”및 “other.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지도를 자동으로 생성 할 수도 있습니다 .


답변

기본 템플릿을 실행할 때 하위 템플릿에 값을 전달해야합니다. 여기서는 “.”를 전달하여 모든 것이 전달되도록합니다.

템플릿 1에 {{.}} 표시

{{define "base"}}
<html>
        <div class="container">
            {{.}}
            {{template "content" .}}
        </div>
    </body>
</html>
{{end}}

템플릿 2는 상위에 전달 된 {{.domains}}를 표시합니다.

{{define "content"}}
{{.domains}}
{{end}}

{{template “content”.}} 대신 {{template “content”.}}를 사용한 경우 콘텐츠 템플릿에서 .domains에 액세스 할 수 없습니다.

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)
    }


답변

다른 템플릿 패키지로 작업 한 후, 지금은 주로 표준 html / 템플릿 패키지로 작업하고 있는데, 그것이 제공하는 단순함과 다른 장점에 감사하지 않는 것이 순진하다고 생각합니다. 나는 다음과 같은 변경 사항으로 수락 된 답변에 매우 유사한 접근 방식을 사용합니다.

추가 base템플릿으로 레이아웃을 래핑 할 필요가 없습니다. 파싱 ​​된 모든 파일에 대해 템플릿 블록이 생성되므로이 경우에는 중복됩니다. 새로운 버전의 go에서 제공하는 블록 액션을 사용하여 하위 템플릿에 제공하지 않는 경우 기본 블록 콘텐츠

// base.html
<head>{{block "head" .}} Default Title {{end}}</head>
<body>{{block "body" .}} default body {{end}}</body>

페이지 템플릿은 다음과 같을 수 있습니다.

// 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["index.html"].ExecuteTemplate(os.Stdout, "base.html", data)


답변

Django와 마찬가지로 템플릿 상속을 위해 {{extends}} 및 {{block}} 태그를 지원하는 Go 템플릿의 상위 집합 인 Pongo를 사용 합니다.


답변

나는 며칠 동안이 대답으로 돌아 왔고 마침내 총알을 깨물고 이것을 위해 작은 추상화 계층 / 사전 프로세서를 작성했습니다. 기본적으로 :

  • 템플릿에 ‘확장’키워드를 추가합니다.
  • ‘정의’호출 재정의 허용 (따라서 greggory에 대한 기본값이 가능함)
  • 정의되지 않은 ‘템플릿’호출을 허용하며 빈 문자열 만 제공합니다.
  • 의 기본값을 설정합니다. ‘템플릿’에서. 부모의

https://github.com/daemonl/go_sweetpl


답변