見出し画像

Goでのテンプレートの使い方をまとめる

はじめに

Goでサーバーを開発してhtmlテンプレートを使いたいということありませんか?基本的にはreactなりnextなりフロントエンドフレームワークを使ったので良いと思いますが事例によってはhtmlテンプレートをあえて使いたいということがあると思います。
自分自身そのような事例に出会して扱い方を勉強しました。
今回はその知識を共有したいと思います。

また今回はfiberというフレームワークを使っています。サーバーサイドのコードはフレームワークによって変わると思いますがテンプレートのコードには影響ないと思います。他のフレームワークを使っている場合は読み替えていただければと思います。

HTMLテンプレートの送信方法

まず値を渡さずに単純にhtmlを送信する方法です。値は「.」を使ってアクセスします。簡単ですね。

ディレクトリ

.
├── go.mod
├── go.sum
├── main.go
└── views
    └── index.html

main.go

package main

import (
	"log"

	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/template/html"
)

func main() {
	engine := html.New("./views", ".html")

	app := fiber.New(fiber.Config{
		Views: engine,
	})
	app.Get("/", func(c *fiber.Ctx) error {
		return c.Render("index", fiber.Map{})
	})

	log.Fatal(app.Listen(":3000"))
}

index.html

<h1>index</h1>


ここから下の例では最初のコードブロックでmain.goの一部を二つ目のコードブロックでindex.htmlを示します。

値の取得

構造体を送って値を取得する方法です。基本的な渡し方ですね。

	app.Get("/", func(c *fiber.Ctx) error {
		return c.Render("index", fiber.Map{
			"Name":     "fumi",
			"Platform": "note",
		})
	})
<div>
  <h1>{{ .Name }}</h1>
  <h1>{{ .Platform }}</h1>
</div>

if

例えば値があるかどうか判定したい場合に活用できます。もちろんある値が10以上の場合に表示といったこともできます!

ちなみにある値がない場合に何も表示しないで良いのであればifなどは挟まなくてもその箇所は何も表示されないです。この例だとnameの値を渡さなかった場合最初のh1が表示されなくなるだけでエラーは出ないです。

	app.Get("/", func(c *fiber.Ctx) error {
		return c.Render("index", fiber.Map{
			"Color":    "",
		})
	})
<div>
  <h1>Color: {{if .Color}}{{.Color}}{{else}} None {{end}}</h1>
</div>

for

配列を渡してそれを表示させたいといったこともあると思います。そういうときに役に立つのがこのforです。

	app.Get("/", func(c *fiber.Ctx) error {
		type article struct {
			Title string
			Likes int
		}
		articles := []article{
			{Title: "programming", Likes: 5},
			{Title: "diet", Likes: 4},
			{Title: "vtuber", Likes: 3},
		}
		return c.Render("index", fiber.Map{
			"Articles": articles,
		})
	})
<span>
  {{ range .Articles}}
  <div>
    <h1>{{ .Title }}</h1>
    <h2>{{ .Likes }}</h2>
  </div>
  {{end}}
</span>

レイアウト

ヘッダーとフッターを作りたいとき用です。defineで囲うことによってテンプレートを定義してtemplateを使って呼び出します。

views/header.html

{{define "header"}}
<h1>Header</h1>
{{end}}

index.html

{{ template "header"}}
<span>
  {{ range .Articles}}
  <div>
    <h1>{{ .Title }}</h1>
    <h2>{{ .Likes }}</h2>
  </div>
  {{end}}
</span>

main.goはforの例と同じです。

まとめ

これくらい知っておけばやりたいことに対しても応用が効いてテンプレートを書いていけるのではないかと思います!
Goのテンプレート自体使用回数が少ないかもしれませんが参考になれば幸いです!

補足

ここからは直接は関係ないですが知っておくべき内容を補足としてQ&A形式でいくつか書いておきます。

  • デザインを追加したい→cssを書いてもいいですが簡単なのでいいならbootstrapのcdnとかどうですか?

  • 認証を追加したい→サーバーサイドの実装に依存するのでなんとも言えないですがfirebaseをcdnで持って来てコードを書くと比較的簡単に実装できます。

cdnを有効活用していきましょう!

  • フッターやヘッダーにも値を渡したい→templateの横に値を追加すれば渡すことができます。

// 例
{{ template "header" . }}
  • GoからJavaScriptに値を渡したい→scriptタグの変数に対して値を渡すことができます。

goコードはforのものと同じ

<script>
  var Articles = {{ .Articles}}
  console.log(Articles)
</script>

結果

[
    {
        "Title": "programming",
        "Likes": 5
    },
    {
        "Title": "diet",
        "Likes": 4
    },
    {
        "Title": "vtuber",
        "Likes": 3
    }
]

この記事が気に入ったらサポートをしてみませんか?