olang勉強するンGo(4) ~ ページの返却
前回まででリクエストに対するハンドラーを登録できた。
今回はハンドラーでHTMLを返却できるようにしたい。
home、about、contactページを作成しようと思う。
完成品
先に完成後のイメージを貼っておく。
レイアウト
まずは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アクセス周りか、その準備を行いたい。