2

私はGolang + AppEngineで基本的なアプリに取り組んでおり、Djangoのようなテンプレート継承を実装しようとしています.これまでのところ、次のコードがあります:

var TmplBasePath = "templates/"

var BasePageTmplPath = []string{TmplBasePath + "base.html"}

type Page struct {
    Title string
    Ctx   appengine.Context
}

func NewPage(r *http.Request, title string) *Page {
    return &Page{Title: title}
}

func (p *Page) Display(w http.ResponseWriter, tmplPath string) {
    tmplPath = TmplBasePath + tmplPath
    tmpl := template.New("PAGE")
    tmpl = template.Must(template.ParseFiles(BasePageTmplPath...))
    tmpl = template.Must(template.ParseFiles(tmplPath))
    if err := tmpl.Execute(w, nil); err != nil {
        p.Ctx.Errorf("%v ", err)
    }
}

func init() {
    http.HandleFunc("/", home)
}

func home(w http.ResponseWriter, r *http.Request) {
    p := NewPage(r, "home")
    p.Display(w, "index.html")

}

私のテンプレート: base.html

{{ define "PAGE"}}

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
            <title> Expat Duka </title>
        <link rel="stylesheet" href="css/bootstrap.min.css"/>
    </head>
    <body>

        <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Project name</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">Home</a></li>
            <li><a href="#about">About</a></li>
            <li><a href="#contact">Contact</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>

         <div class="container">

      <div class="starter-template">
        {{template "CONTENT" .}}

      </div>

    </div><!-- /.container -->

    </body>
    </html>
  {{end}}

index.html

{{define "CONTENT"}}
        <h1> Welcome to Expat Duka </h1>

{{end}}

ページが読み込まれ、エラーはありませんが、空白です。何が間違っているのかわかりません

4

1 に答える 1

4

事前に:関数があり、メソッドがあることに注意してください。最初のものは新しいテンプレートを返し、2 番目のものは既に作成されたテンプレートを呼び出す必要があり、関連付けられたテンプレートを返します。関連付けられたテンプレートはお互いを認識しているため、メソッドを呼び出したテンプレートを既に保存している場合は、返された新しいテンプレートを保存する必要さえありません。template.ParseFiles() Template.ParseFiles()


まず、これはあなたの問題です:

tmpl := template.New("PAGE")
tmpl = template.Must(template.ParseFiles(BasePageTmplPath...))
tmpl = template.Must(template.ParseFiles(tmplPath))

template.ParseFiles()新しいテンプレートを返します(Must()そのパラメータをチェックして同じものを返します)。したがって、最初の行で ( を使用して) 新しいものを作成すると、2 行目で別のものを作成して同じ変数に割り当てるtemplate.New()ため、それが失われます。さらに、3 行目に新しい完全に独立した 3 番目のテンプレートを作成し、それを変数に割り当てます。ParseFiles()tmpltmpl

これら 3 つのテンプレートは完全に独立しており、お互いを認識していません。

テンプレートにお互いを認識させたい (そしてお互いを参照/インクルードできるようにしたい) 場合は、次の例のようにTemplate.Parse()またはTemplate.ParseFiles()メソッドを使用します。

tmpl := template.New("PAGE")
template.Must(tmpl.ParseFiles(BasePageTmplPath...))
template.Must(tmpl.ParseFiles(tmplPath))

これで、変数に複数の関連付けられたテンプレートがtmplできたので、関心のあるテンプレートを実行します。

if err := tmpl.ExecuteTemplate(w, "index.html", nil); err != nil {
    p.Ctx.Errorf("%v ", err)
}

ノート:

また、リクエストを処理するハンドラーでテンプレートを解析することは非常に悪い習慣であり、比較的長い時間がかかります。また、リクエストを処理するたびにテンプレートを解析して作成すると、メモリ内に大量の値が生成されますが、これらの値は (再利用されないため) 破棄され、ガベージ コレクターに追加の作業が与えられます。

アプリケーションの起動時にテンプレートを解析し、それを変数に保存します。リクエストが来たときにのみテンプレートを実行する必要があります。詳細については、この回答を参照してください。

于 2015-03-12T03:50:24.330 に答える