2013-03-12 9 views
7

Aby poradzić sobie z każdą prośbę w aplikacji internetowej, normalny kod o szablonów jest tak:Czy konieczne jest umieszczenie szablonów w mapie do ponownego użycia w Go?

t:= template.New("welcome") 
t, _ = t.ParseFiles("welcome.tpl") 
t.Execute(w, data) 

Chyba ParseFiles za każdym razem kosztuje dużo. Czy można ponownie użyć szablonu? Więc poprawiła to tak:

//templateMap := make(map[string][template]) 
//... 
tplName :="welcome" 
t := templateMap[tplName] 
if t=nil{ 
    t:= template.New(tplName) 
    t, _ = t.ParseFiles("welcome.tpl") 
    templateMap[tplName] = t 
} 

t.Execute(w, data) 

Zastanawiam to możliwe lub wykonalne w celu poprawy efektywności poprzez umieszczenie szablonów na mapie lub cache? Zastanawiam się również, czy funkcja Execute jest bezpieczna dla wątków, czy nie?

func (t *Template) Execute(wr io.Writer, data interface{}) (err error)

Odpowiedz

12

szablon może rzeczywiście działać jako mapa szablonów sama. Oto, co zrobić:

zadeklarować zmienną globalną szablonu:

var t = template.New("master") 

I faktycznie nie korzystać z „master” szablon, z wyjątkiem jako kontener dla innych szablonów.

Następnie załadować wszystkie szablony kiedy zaczyna moja aplikacja:

func init() { 
    _, err := t.ParseGlob("templates/*.html") 
    if err != nil { 
     log.Fatalln("Error loading templates:", err) 
    } 
} 

Potem, gdy chcę użyć jednego z szablonów, pytam o to po imieniu:

t.ExecuteTemplate(w, "user.html", data) 
+0

Czy istnieje wygodny sposób, aby to podejście działało z szablonami, które używają dziedziczenia? (Np., Gdzie jest szablon podstawowy dla niektórych szablonów?) – carbocation

0

z kodu źródłowego template.go funkcja Execute użyć blokady, jestem nowicjuszem, to wygląda to bezpieczne wątek, ale może nie sprawność jeśli umieścić instancję szablonu na mapie i spróbuj go ponownie użyć, jeśli trzeba służyć wiele jednoczesnych żądań:

func (t *Template) Execute(wr io.Writer, data interface{}) (err error) { 
     t.nameSpace.mu.Lock() 
     if !t.escaped { 
       if err = escapeTemplates(t, t.Name()); err != nil { 
         t.escaped = true 
       } 
     } 
     t.nameSpace.mu.Unlock() 
     if err != nil { 
       return 
     } 
     return t.text.Execute(wr, data) 
} 
+0

Przypuszczalnie drogie część to wywołanie Execute na końcu. Sekcja krytyczna dokonuje jednorazowej inicjalizacji szablonu, więc nie powinna być zauważalna. –

Powiązane problemy