【Laravel】Webサイトでヘッダー・フッター部などの共通部分をテンプレート化する方法

Laravelのviewでテンプレートを用意して使い回す方法を書いていきたいと思います。Laravelでは、`@extends`、`@section`、`@yield`、`@include`を使うことでテンプレート**（一部ページごとに内容変更なども可能）**を作成することができます。それぞれの意味・使い方を理解すれば簡単にテンプレート作成ができ、無駄のないview作成ができるようになると思います。



## `@extends`とは

`@extends`とは、継承するためのディレクティブです。親テンプレートを継承することで、継承したviewは親テンプレートに記述されたコードを利用することができます。

```php:template.blade.php（親テンプレートview）
<!DOCTYPE html>
<html>
<head>
<!-- 省略 -->
</head>
<body>
    <p>親viewからの記述</p>
</body>
</html>
```
views直下にtemplate.blade.phpがある場合の子viewからの継承

```php:child.blade.php（子view）
@extends('template')
```

上記の例は、ただ継承して`template.blade.php`の内容をそのまま利用している形になります。実際には全て同じでは意味がないので、テンプレートを利用してそれぞれのページの文言などは変えていくことになります。

## `@section`&`@yield`とは

- `@section`とは、コンテンツのセクションを定義するためのディレクティブです。
- `@yield`とは、指定したセクションの内容を表示するためのディレクティブです。


セクションの終わりを`@stop`か`@endsection （@stopのエイリアス）`にした場合はセクションを定義するだけとなり、`@yield`を使ってセクションの内容を表示させる形になります。それに対し、セクションの終わりを`@show`にすると、即時表示される形になります。これは、親テンプレートの文章を利用しつつ追加要素を追加したい場合などに使えます。

```php:セクションの終わりを@endsectionにした場合
@section('test_section')
    <p>テストセクション</p>
@endsection <!-- この時点では表示されない -->

<!-- @yieldを使ってtest_sectionの内容を表示 -->
@yield('test_section')
```

```php:セクションの終わりを@showにした場合
@section('test_section')
    <p>テストセクション</p>
@show <!-- この時点でtest_sectionの内容が表示される -->
```
### `@show`と`@parent`を利用して、親テンプレートの文章を利用しつつ、さらに文章を追加する方法

```php:parent.blade.php
@section('test_section')
    <p>親viewです</p>
@show
```
views直下にparent.blade.phpがある場合

```php:child.blade.php
@extends('parent')

<!-- 子viewで同じセクションを作ることで、親viewのセクションをオーバーライドできます -->
@section('test_section')
    @parent <!-- @parentで親viewの処理を読み込む -->
    <p>追加文章</p>
@endsection
```

## `@include`とは

`@include`とは、部分的に共通のviewを読み込むためのディレクティブです。親viewの全データ変数が取り込み先のviewに継承されますが、第二引数で追加データを配列で渡すこともできます。例として、head要素のテンプレートを作成して読み込み、タイトルとディスクリプションは取り込み先で設定する処理を書いていこうと思います。

### タイトルとディスクリプションを`@include`に渡した変数で記述する方法

```php:head.blade.php
@section('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>{{$title}}</title>
    <meta name="description" content="{{$description}}">
    <!-- 以下省略 -->
@endsection
```
```php:取り込み先のview
@include('head',['title' => 'タイトル','description' => 'ディスクリプション'])
```

### `@include`で読み込む前に、`@section`を使ってタイトルとディスクリプションを指定する方法

`@include`で読み込む前に、`@section`で各値を指定することもできます。

```php:head.blade.php
@section('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>
    <meta name="description" content="@yield('description')">
    <!-- 以下省略 -->
@endsection
```
```php:取り込み先のview
@section('title','タイトル')
@section('description','ディスクリプション')
@include('head')
```

## 親テンプレートを利用したページ作成

上記のことをそれぞれ理解すれば、テンプレートを利用したページ作成ができるようになります。最後に、テンプレートを利用した簡単なページの例を書いていきたいと思います。ヘッダー・フッター部は基本変わらないと思いますのでテンプレートに直接書いて、head要素とコンテンツ部分を`@yield`で読み込む形にしてあります。

```php:template.blade.php
<!DOCTYPE html>
<html>
<head>
	@yield('head')
</head>
<body>
    <header>
        <!-- 省略 -->
    </header>
    <div id="wrapper">
    	@yield('content')
    </div>
    <footer>
        <!-- 省略 -->
    </footer>
</body>
</html>
```

```php:head.blade.php
@section('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>
    <meta name="description" content="@yield('description')">
    <!-- 以下省略 -->
@endsection
```
views直下にtemplate.blade.phpとhead.blade.phpがある場合

```php:取り込み先ページ
@extends('template')

@section('title','タイトル')
@section('description','ディスクリプション')
@include('head')

@section('content')

    <!-- ここにコンテンツ部分の記述 -->

@endsection
```

以上、`@extends`、`@section`、`@yield`、`@include`を利用すれば簡単にテンプレートを作成することができます。それぞれの使い方をしっかり理解してテンプレート化できるものはどんどんテンプレート化しちゃいましょう。