Larave日記3 - 共通テンプレート - 

Laravel日記シリーズも第3弾です。

前回の内容 → [Laravel日記2](https://qiita.com/kotsuban-teikin/items/9b00d0faa0b7eaf70796)

今回はテンプレートの共通化を行ってみたいと思います。
前回までの工程では、トップページと新規登録ページの2つができただけの状態です、先は長そうだ。。。

## テンプレートの共通化

テンプレートの共通化とは、ページが違っても同じ部分が存在している場合、同じ部分を1ファイルにまとめて管理しやすくするというものです。

```html:index.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="{{ asset('css/style.css') }}">

</head>
<body>
    <header>
        <h1>Laravel Blog</h1>
    </header>
    <p>Laravel Blogです。</p>
    <a href="{{url('/new')}}">新規登録</a>
    <footer>
        <small>copyrights &copy; 2018 kotsuban-teikin All rights Reserved.</small>
    </footer>
</body>
</html>
```


```html:new.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="{{ asset('css/style.css') }}">

</head>
<body>
    <header>
        <h1>Laravel Blog</h1>
    </header>
    <p>Laravel Blog新規登録ページです。</p>
    <a href="{{url('/')}}">トップページへ戻る</a>
    <footer>
        <small>copyrights &copy; 2018 kotsuban-teikin All rights Reserved.</small>
    </footer>
</body>
</html>
```
現状上記のような感じになっていますが、結構共通部分が多いですよね。
例えば、headタグの中に新しいCSSを追加するとなった場合に、このままだと複数のファイルにCSS読み込みのための記述をしないといけません。


この2ファイル、あまりに共通部分が多すぎるので、例えば[Laravel日記2](https://qiita.com/kotsuban-teikin/items/9b00d0faa0b7eaf70796)にもあったように、何かheadタグの中に記述を追加するとなった時に、現状だとindex.blade.phpとnew.blade.phpと両方のファイルに記述を追加しなければならない状態です。

そのため、共通する部分を別途1ファイルにまとめることによって、管理しやすい状態を作りたいと思います。

## 共通テンプレートの作成
それでは、実際に共通化を進めてみたいと思います。
まずは、どういう風に分けるのか、記載してみたいと思います。

![スクリーンショット 2018-12-13 12.07.22.png](https://qiita-image-store.s3.amazonaws.com/0/250202/074a39cd-85b0-e523-ae4b-791522f07a3b.png)


### 各テンプレートファイルを作成
まずは各テンプレートファイルを作成してみたいと思います。
下記のようにまず分解してみます。

- 共通部分・・・・resources/views/layouts/common.blade.php
- 個別部分・・・・index.blade.phpとnew.blade.phpにそれぞれ記載

```html:layouts/common.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="{{ asset('css/style.css') }}">

</head>
<body>
    <header>
        <h1>Laravel Blog</h1>
    </header>

@yield('content')

    <footer>
        <small>copyrights &copy; 2018 kotsuban-teikin All rights Reserved.</small>
    </footer>
</body>
</html>

```

```php:index.blade.php
@extends('layouts.common')
@section('content')
    <p>Laravel Blogです。</p>
    <a href="{{url('/new')}}">新規登録</a>
@endsection
```

```php:new.blade.php
@extends('layouts.common')
@section('content')
    <p>Laravel Blog新規登録ページです。</p>
    <a href="{{url('/')}}">トップページへ戻る</a>
@endsection
```

ここで、@yield()と@section()と@extendsというものが出てきました。

![Web 1920 – 1.png](https://qiita-image-store.s3.amazonaws.com/0/250202/aea360a0-cc85-1e9f-544f-802f7d7bbc95.png)

例えば、ルートディレクトリ（○○.comとかlocalhost:8000とか）を表示した時、今の状態であればindex.blade.phpの内容を表示しようとしますが、今回のようにファイルを分けてsectionとextendsを使用すると


- @extends内でlayout/common.blade.phpが定義されているので、基本的にはcommon.blade.phpの内容を表示
- common.blade.php内のyield('content')の部分には、index.blade.php内で定義された@section
（'content'）の部分が表示

こんな動きがなされます。
@extendsは、共通部分を継承する、という意味で使われるわけですね。

ちなみに僕も途中まで勘違いしていたのですが、@extendsを1番上に書いたからといってcommon.blade.phpの内容が1番上に表示されるというわけではありません。

あくまで、「このテンプレートファイルの内容を継承するよ」という宣言でしかないので注意が必要です。

## @sectionの便利な使い方 
@sectionですが、下記のような使い方もできるようです。

```php:layouts/common.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>@yield('title')</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
    <link rel="stylesheet" href="{{ asset('css/style.css') }}">

</head>

<!--以下省略-->
```
```php:index.blade.php
@extends('layouts.common')

@section('title',"トップページ")

@section('content')
    <p>Laravel Blogです。</p>
    <a href="{{url('/new')}}">新規登録</a>
@endsection
```
```new.blade.php
@extends('layouts.common')

@section('title',"新規ページ")

@section('content')
    <p>Laravel Blogです。</p>
    <a href="{{url('/new')}}">新規登録</a>
@endsection
```

こうすると、titleタグの中身をページによって変えることができます。
ページによって表示内容を変更したいなという時に、便利ですね！

## @includeについて
ちなみに、これ以外にも@includeというものがあります。

@includeというのは、その名の通り、指定したファイルを丸っと読み込みするような、そんなイメージです。

@includeと@extends & @sectionの使い分けが難しいなと思ったのですが、私の中では、

- @extends & @sectionはセット、両方がないとそのページの表示が成り立たない。
- @inlcudeで読み込むところは、その部分がなくてもページの表示が成り立つ（何かの登録をしようとしてエラーになった際にエラー表示部分を読み込んで表示する際に@includeを使う）

とまずは考えるようにしています。

@includeと@extendsと@section、そしてyieldを使い分けることで、共通化を便利に行うことができますが、今のところはここまでにとどめておきます。

## 次回について
次回は、make::authを使った認証機能の実装をしてみたいと思います。