2017-05-06 3 views
1

Ich beginne gerade mit Go, und ich möchte damit eine Web App erstellen. Was ich jetzt versuche ist, das Template in einer Lenker-ähnlichen Art zu verwenden. Ich möchte meine Kopf- und Fußzeile aus meiner Hauptseite ziehen, damit ich sie auf jeder Webseite einfügen kann.HTML Partials in GoLang

Meine aktuelle Einrichtung soll HTML-Dateien der Startseite, der Kopfzeile und der Fußzeile analysieren und zwischenspeichern. Dann führe ich meine home.html Vorlage aus, die Felder für die Seiten Titel, die Datei header.html und die Datei footer.html enthält.

Immer wenn ich nach ähnlichen Seiten suche, sehe ich nur Javascript-Seiten, also wenn das ein repost ist, lassen Sie mich wissen, wo ich suchen soll.

edit: Ich habe meinen Code aktualisiert Tipps von den Antworten von @Minty und @putu zu nehmen. Ich versuche, die HTML-Dateien zu lesen und sie in einer Datenzuordnung zu speichern, während ich auch die Vorlage zu meinen Vorlagen hinzufüge. Es gibt einige neue Bugs, die ich an Squashing arbeite, daher wird die Site derzeit nicht gerendert. Aber, wenn es irgendwelche neuen Tipps gibt, die Sie geben können, würde das viel helfen.

server.go

package main 

import (
    "html/template" 
    "io/ioutil" 
    "net/http" 
    "regexp" 
) 

var tPath = "./temps/" 
var dPath = "./data/" 

var templates = template.Must(template.ParseFiles(tPath+"home.html", dPath+"header.html", dPath+"footer.html")) 
var validPath = regexp.MustCompile("^/") 

func rootHandler(wr http.ResponseWriter, req *http.Request) { 
    title := "home" 
    headerFile, headErr := ioutil.ReadFile(dPath + "header.html") 
    footerFile, footErr := ioutil.ReadFile(dPath + "footer.html") 

    if headErr != nil || footErr != nil { 
     http.Error(wr, headErr.Error(), http.StatusInternalServerError) 
     http.Error(wr, footErr.Error(), http.StatusInternalServerError) 
    } 

    data := map[string]interface{}{ 
     "Title": title, 
     "Header": string(headerFile), 
     "Footer": string(footerFile), 
    } 

    err := templates.ExecuteTemplate(wr, title+".html", data) 

    if err != nil { 
     http.Error(wr, err.Error(), http.StatusInternalServerError) 
    } 
} 

func main() { 
    http.HandleFunc("/", rootHandler) 
    http.ListenAndServe(":8080", nil) 
} 

home.html:

{{define "homeHTML"}} 
<!DOCTYPE html> 
<html> 
    <head> 
     <meta charset="utf-8"> 
     <title>{{.Title}} - MySite</title> 
     <link rel="stylesheet" type="text/css" href="style.css"> 
    </head> 
    <body> 
     {{.Header}} 
     <h1>Welcome!</h1> 
     {{.Footer}} 
    </body> 
</html> 
{{end}} 

header.html:

{{define "headerHTML"}} 
<header> 
    <h1>MySite</h1> 
    <br> 
    <nav> 
     <a href="/">Home</a> 
    </nav> 
</header> 
{{end}} 

footer.html

{{define "footerHTML"}} 
<footer> 
    <p>Thank You for Visiting</p> 
</footer> 
{{end}} 
+1

meine neue Lösung prüfen, seine volle Arbeitsbeispiel. Kopieren Sie einfach die Paste richtig und es wird funktionieren – Minty

Antwort

2

Dies ist ein voll funktionsfähiges Beispiel.

// home.html inside temps folder 
{{define "homeHTML"}} 

{{template "headHTML" .}} 

{{template "headerHTML" .}} 

{{template "footerHTML" .}} 

{{end}} 

// head.html inside data folder 
{{define "headHTML"}} 
<!DOCTYPE html> 
<html> 
    <head> 
     <meta charset="utf-8"> 
     <title>{{.title}} - MySite</title> 
     <link rel="stylesheet" type="text/css" href="style.css"> 
    </head> 
{{end}} 

// header.html inside data folder 
{{define "headerHTML"}} 
<header> 
    {{.header}} 
    <h1>Welcome to my site!</h1> 
    <br> 
    <nav> 
     <a href="/">Home</a> 
    </nav> 
</header> 
{{end}} 


// footer.html inside data folder 
{{define "footerHTML"}} 
<h1>Welcome! {{.footer}}</h1> 
<footer> 
<p>Thank You for Visiting</p> 
</footer> 
</body> 
</html> 
{{end}} 

und der Code wird wie folgt

package main 

import (
    "html/template" 
    "io/ioutil" 
    "net/http" 
    "path/filepath" 
    "strings" 
) 

var tPath = "./temps/" 
var dPath = "./data/" 

var templateDirs = []string{"temps", "data"} 
var templates *template.Template 

func getTemplates() (templates *template.Template, err error) { 
    var allFiles []string 
    for _, dir := range templateDirs { 
     files2, _ := ioutil.ReadDir(dir) 
     for _, file := range files2 { 
      filename := file.Name() 
      if strings.HasSuffix(filename, ".html") { 
       filePath := filepath.Join(dir, filename) 
       allFiles = append(allFiles, filePath) 
      } 
     } 
    } 

    templates, err = template.New("").ParseFiles(allFiles...) 
    return 
} 

func init() { 
    templates, _ = getTemplates() 
} 

func rootHandler(wr http.ResponseWriter, req *http.Request) { 
    title := "home" 

    data := map[string]interface{}{ 
     "title": title, 
     "header": "My Header", 
     "footer": "My Footer", 
    } 

    err := templates.ExecuteTemplate(wr, "homeHTML", data) 

    if err != nil { 
     http.Error(wr, err.Error(), http.StatusInternalServerError) 
    } 
} 

func main() { 
    http.HandleFunc("/", rootHandler) 
    http.ListenAndServe(":8080", nil) 
} 
+0

Funktioniert gut! Vielen Dank!!! – zgangwer20

1

Sie müssen die Daten als struct oder map an Vorlage übergeben. Beispiel Ihrer rootHandler mit map:

func rootHandler(wr http.ResponseWriter, req *http.Request) { 
    title := "home" 
    //Wrap your variable into a map 
    data := map[string]interface{}{ 
     "Title": title, 
     "IntVar": 100, 
    } 

    err := templates.ExecuteTemplate(wr, title+".html", data) 

    //other codes... 
} 

Weitere Einzelheiten finden Sie documentation.