2013-03-12 7 views
7

は、Webアプリケーション内のすべての要求に対処するには、テンプレートに関する通常のコードは次のようである:Goで再利用するためにテンプレートをマップに配置する必要はありますか?

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

は、私はすべての時間は、多くの費用ParseFilesを推測します。テンプレートを再利用することは可能ですか?だから私はこのようにそれを改善:

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

私はマップまたはキャッシュにテンプレートを置くことによって、効率を向上させることが可能か、実用的であるだろうか? 私はまた、関数Executeがスレッドセーフであるかどうか疑問に思っていますか? template.goのソースコードから

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

答えて

12

テンプレートは、実際には、それ自体で、テンプレートのマップとして機能することができます。ここでは、私が何をすべきかです:

私はグローバルテンプレート変数を宣言:

var t = template.New("master") 

私は実際に他のテンプレートのコンテナとして除き、「マスター」テンプレートを使用しないでください。私のアプリの起動時に

その後、私は、すべてのテンプレートを読み込む:

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

をそれから私は、テンプレートのいずれかを使用したい場合、私は名前でそれを求める:おそらく

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

継承を使用するテンプレートでこのアプローチを使用する便利な方法はありますか? (たとえば、いくつかのテンプレートの基本テンプレートがある場合) – carbocation

0

、実行機能は、ロックを使用して、私は初心者だマップにテンプレートのインスタンスを置けば、それは、スレッドセーフであるように見えますが、効率ではないかもしれないし、あなたは同時要求の多くを提供するために必要がある場合は、それを再利用しよう:

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

高価パートは最後にExecuteコールです。クリティカルセクションではテンプレートの一括初期化が行われているため、目立たないようにしてください。 –

関連する問題