web-dev-qa-db-de.com

Kann ich verschachtelte Vorlagen in Go verwenden, indem Sie die Standardbibliothek verwenden? (Google App Engine)

Wie bekomme ich verschachtelte Vorlagen, die Jinja in der Python-Laufzeit hat? TBC meine ich damit, wie ich eine Reihe von Vorlagen von Basisvorlagen erben kann, indem ich nur Blöcke der Basisvorlagen füge, wie dies bei Jinja/Django-Vorlagen der Fall ist. Ist es möglich, nur html/template in der Standardbibliothek zu verwenden.

Wenn das keine Möglichkeit ist, was sind meine Alternativen. Schnurrbart scheint eine Option zu sein, aber würde ich dann diese schönen subtilen Funktionen von html/template wie das kontextsensitive Fluchtweg-Verhalten usw. verpassen? Welche anderen Alternativen gibt es?

(Umgebung: Google App Engin, Go Runtime v1, Dev - Mac OSx-Löwe)

Danke fürs Lesen.

78
sri

Ja, es ist möglich. Ein html.Template ist eigentlich eine Menge von Vorlagendateien. Wenn Sie einen definierten Block in diesem Set ausführen, hat er Zugriff auf alle anderen in diesem Set definierten Blöcke.

Wenn Sie selbst eine Karte solcher Vorlagen erstellen, haben Sie im Grunde die gleiche Flexibilität, die Jinja/Django bietet. Der einzige Unterschied besteht darin, dass das Paket html/template keinen direkten Zugriff auf das Dateisystem hat. Daher müssen Sie die Vorlagen selbst analysieren und erstellen.

Betrachten Sie das folgende Beispiel mit zwei verschiedenen Seiten ("index.html" und "other.html"), die beide von "base.html" erben:

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

Und die folgende Karte von Vorlagensätzen:

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

Sie können Ihre "index.html" -Seite jetzt durch Aufrufen rendern 

tmpl["index.html"].Execute("base", data)

und Sie können Ihre "other.html" -Seite durch Aufrufen rendern

tmpl["other.html"].Execute("base", data)

Mit einigen Tricks (z. B. einer konsistenten Namenskonvention Ihrer Vorlagendateien) ist es sogar möglich, die tmpl-Map automatisch zu generieren.

120
tux21b

beachten Sie, wenn Sie Ihre Basisvorlage ausführen, müssen Sie Werte an die untergeordneten Vorlagen weitergeben. Hier übergeben Sie einfach ".", damit alles weitergegeben wird.

vorlage eins zeigt {{.}}

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

vorlage zwei zeigt {{.domains}} an, die an das übergeordnete Element übergeben wird.

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

Wenn Sie {{template "content".}} Anstelle von {{template "content".}} Verwenden, kann auf .domains nicht über die Inhaltsvorlage zugegriffen werden.

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

Verwenden Sie Pongo , eine Supermenge von Go-Vorlagen, die die Tags {{extend}} und {{block}} für die Vorlagenvererbung wie Django unterstützt.

5
Rob

Ich komme seit Tagen auf diese Antwort zurück, biss schließlich die Kugel ab und schrieb dazu eine kleine Abstraktionsschicht/einen Vorprozessor. Im Grunde:

  • Fügt den Vorlagen das Schlüsselwort 'extend' hinzu.
  • Erlaubt das Überschreiben von 'define'-Aufrufen (daher sind Standardwerte für greggory möglich)
  • Erlaubt nicht definierte "Vorlagen" -Aufrufe, sie geben nur eine leere Zeichenfolge an
  • Legt den Standardwert von fest. in 'template' ruft an. des Elternteils

https://github.com/daemonl/go_sweetpl

4
daemonl

nachdem ich mit anderen Template-Paketen gearbeitet habe, arbeite ich jetzt meistens mit Standard-HTML/Template-Paketen. Ich schätze, ich war naiv, die Einfachheit, die es bietet, und andere Leckereien nicht zu würdigen. Ich verwende einen sehr ähnlichen Ansatz für akzeptierte Antworten mit folgenden Änderungen

sie müssen Ihre Layouts nicht mit einer zusätzlichen base-Vorlage umschließen. Für jede analysierte Datei wird ein Vorlagenblock erstellt. In diesem Fall ist es überflüssig. Ich verwende auch gerne die in der neuen Version von go bereitgestellte Blockierungsaktion, die es Ihnen ermöglicht haben standardmäßigen Blockinhalt, falls Sie keinen in untergeordneten Vorlagen bereitstellen

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

und Ihre Seitenvorlagen können die gleichen sein wie

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

um nun die Vorlagen auszuführen, müssen Sie es so aufrufen 

tmpl["index.html"].ExecuteTemplate(os.Stdout, "base.html", data)
0
allyraza