olang勉強するンGo(4) ~ ページの返却

前回まででリクエストに対するハンドラーを登録できた。

今回はハンドラーでHTMLを返却できるようにしたい。

home、about、contactページを作成しようと思う。

完成品

先に完成後のイメージを貼っておく。

f:id:kituman:20190120233455p:plain

レイアウト

まずはlayoutを作成する。

layout.html.tplというファイル名でhtmlのテンプレートを作成した。

ちなみに拡張子はなんでも良いのだが、.tpl形式が一般的らしい。

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>golang-blog</title>
    <meta charset="utf-8">
    <meta name="description" content="golang-blog">
    <meta name="author" content="kituman">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
        crossorigin="anonymous">
</head>

<body>
    <nav class="navbar navbar-dark bg-dark navbar-expand-lg">
        <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
            <div class="navbar-nav">
                <a class="nav-item nav-link" href="http://localhost:8080/">Home</a>
                <a class="nav-item nav-link" href="http://localhost:8080/about">About</a>
                <a class="nav-item nav-link" href="http://localhost:8080/contact">Contact</a>
            </div>
        </div>
    </nav>

    {{.}}

    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
        crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut"
        crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k"
        crossorigin="anonymous"></script>
</body>

</html>

見た目が壊滅的だったので、Bootstrapを使用して体裁を整えた。

Go言語のhtml/templateでは{{.}}となっている箇所にデータを流し込める。

リクエストを処理する

前回同様にリクエストに対するハンドラーを作成していく。

main.goの内容を以下のように編集する。

package main

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

func main() {
    mux := http.NewServeMux()

    // handler登録
    aboutHandler := new(AboutHandler)
    contactHandler := new(ContactHandler)
    articleHandler := new(ArticleHandler)

    mux.Handle("/about", aboutHandler)
    mux.Handle("/contact", contactHandler)
    mux.Handle("/", articleHandler)

    // サーバ起動
    http.ListenAndServe(":8080", mux)
}

// AboutHandler : aboutを表示
type AboutHandler struct{}

func (handler *AboutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    t := template.Must(template.ParseFiles("layout.html.tpl"))

    str := "これはGo言語を勉強するためのブログです。"

    err := t.ExecuteTemplate(w, "layout.html.tpl", str)

    if err != nil {
        log.Fatal(err)
    }
}

// ContactHandler : aboutを表示
type ContactHandler struct{}

func (handler *ContactHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    t := template.Must(template.ParseFiles("layout.html.tpl"))

    str := "ご連絡ください。"

    err := t.ExecuteTemplate(w, "layout.html.tpl", str)

    if err != nil {
        log.Fatal(err)
    }
}

// ArticleHandler : 記事を表示
type ArticleHandler struct{}

func (handler *ArticleHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    t := template.Must(template.ParseFiles("layout.html.tpl"))

    str := "今後、記事を表示できるようにします。"

    err := t.ExecuteTemplate(w, "layout.html.tpl", str)

    if err != nil {
        log.Fatal(err)
    }
}

今回使用したhtml/templateについて順番に説明していく。

t := template.Must(template.ParseFiles("layout.html.tpl"))について、 ここではtemplate.ParseFilesにより先ほど作成したlayout.html.tplをパースしている。

通常ではtemplate.ParseFilesだけで十分だが、template.Mustを通すことでエラー処理を自動で行っている。

err := t.ExecuteTemplate(w, "layout.html.tpl", str)について、 ここではhttp.ResponseWriterに対して先ほどパースしたファイルを出力している。

パースしたテンプレートの名前は、ファイル名と同一になる。

また、第三引数でテンプレートに流し込むデータを指定できる。 これによりstrの内容がテンプレート内の{{.}}に展開される。


とりあえずhtmlを表示させることが可能になった。

ただ、入れ後のテンプレートなどの表示の仕方がわからないので今後調べていきたい。

次回はDBアクセス周りか、その準備を行いたい。