LoginSignup
12
9

More than 5 years have passed since last update.

[Go言語] templateパッケージでtwigとかのextends的なあれをやるにはどうしようか

Last updated at Posted at 2013-09-29

やりたいこと

twigでいくと以下のようなやつ。
でも、デフォルトがあってそれを上書きするとかいう機能は別にいらない。
共通部分を使い回せればそれでいい。

参考:http://twig.sensiolabs.org/doc/tags/extends.html

base.html
<!DOCTYPE html>
<html>
    <head>
        {% block head %}
            <link rel="stylesheet" href="style.css" />
            <title>{% block title %}{% endblock %} - My Webpage</title>
        {% endblock %}
    </head>
    <body>
        <div id="content">{% block content %}{% endblock %}</div>
        <div id="footer">
            {% block footer %}
                &copy; Copyright 2011 by <a href="http://domain.invalid/">you</a>.
            {% endblock %}
        </div>
    </body>
</html>
child.html
{% extends "base.html" %}

{% block title %}Index{% endblock %}
{% block head %}
    {{ parent() }}
    <style type="text/css">
        .important { color: #336699; }
    </style>
{% endblock %}
{% block content %}
    <h1>Index</h1>
    <p class="important">
        Welcome on my awesome homepage.
    </p>
{% endblock %}

やってみた

とりあえず、PlayGroundでやってみた。

main.go
package main

import (
    "fmt"
    "os"
    "text/template"
)

var layoutStr = `{{define "layout"}}header
{{template "content"}}
footer{{end}}`

var hogeStr = `{{define "content"}}hoge{{end}}`

var piyoStr = `{{define "content"}}piyo{{end}}`

func main() {
    hoge := template.Must(template.New("hoge").Parse(hogeStr))
    hoge.Parse(layoutStr)
    hoge.ExecuteTemplate(os.Stdout, "layout", nil)

    fmt.Println()

    piyo := template.Must(template.New("piyo").Parse(piyoStr))
    piyo.Parse(layoutStr)
    piyo.ExecuteTemplate(os.Stdout, "layout", nil)

}

もっとちゃんとやってみた

baseを作る

まずは、baseとなるhtmlを作る。
テンプレートの名前は、baseとしておく。
templatecontentという別のテンプレートを読み込んでいる。

base.html
{{define "base"}}
<!DOCTYPE html>
<html>
    <body>

      <header>
        <h1>Title of {{.}}</h1>
        <nav>
          <ul>
            <li><a href="hoge">Hoge</a></li>
            <li><a href="piyo">Piyo</a></li>
          </ul>
        </nav>
      </header>

      <article id="content">
        {{template "content" .}}
      </article>

      <footer>
        &copy; Copyright 2013 by golang-samples.
      </footer>
    </body>
</html>
{{end}}

コンテンツを作る

続いて、コンテンツとなるhtmlを作る。
base.htmlに埋め込まれるので、テンプレートの名前は2つともcontentにしておく。

hoge.html
{{define "content"}}
<h1>Hoge</h1>
<p>
  I'm Hoge.
</p>
{{end}}
piyo.html
{{define "content"}}
<h1>Piyo</h1>
<p>
  I'm Piyo.
</p>
{{end}}

Goから読み込む

以下のように、別々のテンプレートとしてパースすることで、contentという名前が被ってもできる。もちろん、ParseGlobとかで一気にパースするとダメ。

ベースで指定した部分を上書きするtwigのextendsの方が自由度高いが、まぁコレくらいできたら別にいいや。

main.go
package main

import (
    "html/template"
    "net/http"
)

var hogeTmpl = template.Must(template.New("hoge").ParseFiles("base.html", "hoge.html"))

func hogeHandler(w http.ResponseWriter, r *http.Request) {
    hogeTmpl.ExecuteTemplate(w, "base", "Hoge")
}

var piyoTmpl = template.Must(template.New("piyo").ParseFiles("base.html", "piyo.html"))

func piyoHandler(w http.ResponseWriter, r *http.Request) {
    piyoTmpl.ExecuteTemplate(w, "base", "Piyo")
}

func main() {
    // hoge
    http.HandleFunc("/", hogeHandler)
    http.HandleFunc("/hoge", hogeHandler)

    // piyo
    http.HandleFunc("/piyo", piyoHandler)

    http.ListenAndServe(":8080", nil)
}
12
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9