Golang 入門 : Web (簡易掲示板) を作成 part4-Viewと完成

この記事は約11分で読めます。

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

前回は

Golang 入門 : Web (簡易掲示板) を作成 part3-コントローラとルーティング
今回の 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の説明は以上です。

テンプレートを使いこなしたい方はこちら

Gin(Golang)におけるHTMLテンプレート記述方法 - Qiita
# はじめに Go言語で使えるウェブフレームワークGin HTMLレンダリング、テンプレートの書き方が分かり辛かったので少し解説 # 環境など goはインストールされている前提で紹介 ```bash $ go version go...

 

まとめ

今回はViewについて説明しました。

この説明で、

Golang 入門 : Webサイト(簡易掲示板 ) を作成 part1-プロジェクト作成

ここで書いたGolang Webサイト作成の完成品が出来上がります!

見た目は、各々色々書き換えていってください!

ちなみに出来るだけスタイルを当てたくないので、BulmaというCSSフレームワークを利用しています。是非参考にしてみてください!

 

完成品のコードを貼っておきます!

ryomak/example-go
for h type programming blog. Contribute to ryomak/example-go development by creating an account on GitHub.

 

もう少し理論を知っておきたい方は、こちら

[ golang ]Go言語入門~ WebAPI ~
今回は、WebAPI を利用するプログラムを作ります。 Day1では、画像分析を通して、他人が作ったプログラムを利...

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

【 ngrok 】1分で簡単にWebを公開する方法!!
今回はngrokを用いて簡単にローカルで立てているWebを外部に公開する方法をご紹介します。negrokを用いることで、簡単に外部公開できるので、ちょっと公開したいときに使う裏技です。他にも使い所はたくさんあるので、是非使ってみてください![ ngrok ]

それでは!

タイトルとURLをコピーしました