Golang でWeb (簡易掲示板) 作成の最終回です!
前回は

でした。
今回は、前回触れなかったViewの部分を解説します!
復習
前回は、ユーザのリクエストに対して処理を実装しました。(ルーティングとコントローラー)
ルーティングでリクエストを受け付けて、それに対応する処理を記述したコントローラでは、データベースからデータを取ってきて、それをテンプレートファイルにデータを埋め込むという処理を書いてました。
知識
テンプレートファイルとは、
普通のHTMLにプラスして、Golang側で、文字列を埋め込むために使うファイルです。
例えば、
<h1>田中さん</h1>
という物をHTMLファイルで出す場合、リクエストに対して、この名前を変えたいという場合、Golangでは、
<div>{{.name}}さん</div>としておくと、
name変数を{{}}のなかに埋め込んでくれます。
このようにGolangで変数を埋め込むためのファイルをテンプレートファイルと言います。
今回はこのテンプレートをみていきます。
ディレクトリ
. ├── controller │ └── article_handler.go ├── go.mod ├── go.sum ├── model │ └── article.go ├── script │ ├── reset_db.sh │ └── reset_db.sql ├── util │ └── db.go ├── view │ ├── index.tmpl <--ここ │ ├── layout.tmpl<--ここ │ └── new.tmpl <--ここ └── web.go
です!!
実践:テンプレート
今回は、前回のハンドラーと対応しながら見ていきます。
記事一覧ページ
func (s *Server) GetArticlePage(c *gin.Context) { errMsg := "" articles, err := model.GetAllArticles(s.DB) if err != nil { errMsg = "エラー発生" articles = []model.Article{} } c.HTML(http.StatusOK, "index.tmpl", gin.H{ "articles": articles, "errMsg": &errMsg, }) }
これが記事一覧ページを表示するハンドラーです。
最後のc.HTML()に注目してください。
index.tmplにgin.Hの中身を埋め込むという処理が書かれています。
- {{.articles}}にはariclesという変数を埋め込む
- {{.errMsg}}にはerrMsgという変数を埋め込む
と意味です。
それでは、index.tmplを見ていきます。
<!DOCTYPE html>
<html lang=”ja”>{{ template “head” . }}
<body >
{{ template “header” .}}
<div class=”container” >
<h1>記事一覧</h1>
{{if .errMsg}}
<div style=”color:red”>
<p> {{.errMsg}} </p>
</div>
{{end}}
<table class=”table” style=”width:100%;”>
<thead>
<tr>
<th>ID</th>
<th>Create</th>
<th>Text</th>
<th>action</th>
</tr>
</thead>
<tbody>
{{range .articles}}
<tr>
<td>{{.ID}}</td>
<td>{{.CreatedAt.Year}}-{{.CreatedAt.Month}}-{{.CreatedAt.Day}}</td>
<td>{{.Text}}</td>
<td> <form action=”/delete/{{.ID}}” method=”post” style=”display:inline;” ><button class=”button”>delete</button></form></td>
</tr>
{{end}}
</tbody>
</table>
{{ template “footer” .}}
</body>
</html>
解説
{{template xx}}については、あとで、説明します。
{{range .articles}}
<tr>
<td>{{.ID}}</td>
<td>{{.CreatedAt.Year}}-{{.CreatedAt.Month}}-{{.CreatedAt.Day}}</td>
<td>{{.Text}}</td>
<td> <form action=”/delete/{{.ID}}” method=”post” style=”display:inline;” ><button class=”button”>delete</button></form></td>
</tr>
{{end}}
上のコードにおいてここが重要です!
{{range .articles}} ~ {{end}}で、articlesというスライス(または配列)を繰り返し生成します。
例えば,下のようなテンプレートに対して、
{{.range .articles}}
<div>{{.name}}</div>
{{end}}
artciles := [{name:”a”},{name:”b”}]を埋め込むと
<div>a</div>
<div>b</div>
となります。
記事一覧はこれと同じように、Article構造体をrangeで表示させます。
記事一覧ページで削除ボタンもつけているので、
<form action=”/delete/{{.ID}}” method=”post” style=”display:inline;” ><button class=”button”>delete</button></form>
ここで、ボタンクリックされるごとに、/delete/:idにリクエストが飛んで記事が削除されます。
新規ページ
<!DOCTYPE html>
<html lang=”ja”>{{ template “head” . }}
<body>
{{ template “header” .}}
<div class=”container”>
<h1>投稿</h1>
{{if .errMsg}}
<div style=”color:red”>
<p> {{.errMsg}} </p>
</div>
{{end}}
<form action=”new” method=”post” style=”width:100%;”>
<p>
<textarea class=”textarea” name=”text” rows=”4″ cols=”40″></textarea>
</p>
<div class=”control”>
<button class=”button is-link”>Submit</button>
</div>
</form>
</div>
{{ template “footer” .}}
</body>
</html>
ここでは、
{{if .errMsg}}
<div style=”color:red”>
<p> {{.errMsg}} </p>
</div>
{{end}}
ここが重要です。
errMsgがあるときは、{{if}}~{{end}}の中を表示させます。
これによって、エラー表示させたいときは、errMsgを埋め込めば良いです。
{{template .xx}}とは何か
これはとても便利です。
layout.tmplを見てみましょう。
{{define “head”}}
<head>
<title>{{.title}}</title>
<meta charset=”utf-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1″>
<link rel=”stylesheet” href=”https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.css”>
<link rel=”stylesheet” href=”https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.css.map”>
<link rel=”stylesheet” href=”https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css”>
<script defer src=”https://use.fontawesome.com/releases/v5.3.1/js/all.js”></script>
</head>
{{end}}{{ define “header” }}
<header>
<nav class=”navbar” role=”navigation” aria-label=”main navigation”>
<div id=”navbarBasicExample” class=”navbar-menu is-active”>
<div class=”navbar-start”>
<a href=”/” class=”navbar-item”>
トップ
</a>
<a href=”/new” class=”navbar-item”>
投稿
</a>
</div>
</div>
</nav>
</header>{{end}}
{{ define “footer” }}
<div class=”content has-text-centered”>
<p> created by <a href=”https://github.com/ryomak”>ryomak</a></p>
</div>
{{end}}
{{define xx}}~{{end}}で設定したものを他のテンプレートでも使いまわすことができます。
つまり、{{define xxx}}~{{end}}で定義し、{{template xxx}}でテンプレートにテンプレートを埋め込むことができます。
共通の記述は使いまわすことをお勧めします。(変更があった場合、一ファイルの修正で済むため)
今回はheaderやfooterなどどのページも同じであるため、{{define}}で定義しておいて、index.tmplなどで、
{{template xx}}を記述し、この{{define xx}}~{{end}}の中身を埋め込むことができます。
以上でVIewの説明は以上です。
テンプレートを使いこなしたい方はこちら

まとめ
今回はViewについて説明しました。
この説明で、
Golang 入門 : Webサイト(簡易掲示板 ) を作成 part1-プロジェクト作成
ここで書いたGolang Webサイト作成の完成品が出来上がります!
見た目は、各々色々書き換えていってください!
ちなみに出来るだけスタイルを当てたくないので、BulmaというCSSフレームワークを利用しています。是非参考にしてみてください!
完成品のコードを貼っておきます!
もう少し理論を知っておきたい方は、こちら

とりあえず外部公開してみたい方はこちら

それでは!
人気記事