Laravel

【Laravel】Bladeテンプレートでレイアウトを共通化する

LaravelのBladeテンプレートにて用意されている「継承」と「セクション」という機能で、テンプレートを組み合わせてレイアウトを作成していく方法を軽くまとめておきたいと思います。

継承とセクション

「継承」とは、親ビューの持っている機能を子ビューが使うというイメージです。
ヘッダーやフッターなどの決まった共通部分は基底のテンプレート(親ビュー)に定義して、body の中だけを(子ビュー)で定義するといった使い方をします。

@sectionと@yield

@section

様々な部品を作成(定義)するために使用します。
以下のように記述します。

[php]
@section( 名前 )
…表示内容…
@endsection
[/php]

これで指定した名前でセクションが用意されます。
このセクションは同じ名前の @yield にはめ込まれ表示されます。

また @section は継承したページで @section によって上書きすることも可能との事です(まだ良くわかっていない)。

@yield

@yield はセクションの内容をはめ込んで表示するためのものです。
以下のように使用します。

[php]
@yield( 名前 )
[/php]

@yield で指定した名前のセクションがあると、そのセクションが @yield のところにはめ込まれます。
@yield は配置場所を示すものなので、 @yieldend のようなものは有りません。

レイアウトの作成

最終目的のHTML

親ビューは共通部分を記述し、子ビューにて詳細を記述するのが基本とのこと。
ということで、まずは最終的に記述したいHTMLを作ってからBladeの機能に置き換えてみます。

[php]




ページタイトル|nodoame.net


ヘッダー

コンテンツ内容(各ページにより異なる)

フッター



[/php]

ページごとに設定したい内容は以下とします。

  • titleタグの内容
  • description
  • keywords
  • page.css(ページ毎のCSS)
  • コンテンツ内容

ベーステンプレート

以下がベースとなるテンプレートファイルです。
プロジェクトディレクトリ/resources/views へ「layout」ディレクトリを作成し、common.blade.php の名称で新規作成します。

[php]




@yield('title')|nodoame.net

@yield('pageCss')

@yield('header')

@yield('content')

@yield('submenu')

@yield('footer')


[/php]

先にも書きましたが @yield() にて別途作成する内容を配置する仕組みとなっています。
この仕組み(機能)を使って、title、description、keywords、pageCss、header、content、submenu、footerを管理していきます。

スタイルシートは、プロジェクトディレクトリ/public へ「css」ディレクトリを作成してそちらへ配置することとします。

部品レイアウト

ヘッダー、フッター、サブメニュー用の部品レイアウトを作成します。

ヘッダー用(views/layout/header.blade.php)

[php]
@section('header')

ヘッダー

@endsection
[/php]

サブメニュー用(views/layout/submenu.blade.php)

[php]
@section('submenu')

@endsection
[/php]

フッター用(views/layout/footer.blade.php)

[php]
@section('footer')

フッター

@endsection
[/php]

継承レイアウト

先に作成したベースレイアウトを継承して実際のWEBページに使用するテンプレートを用意します。
ページごとに用意するものと捉えればわかりやすいでしょうか。

views/star/index.blade.php

[php]
@extends('layout.common')

@section('title', 'インデックスページ')
@section('keywords', 'キーワード1,キーワード2,キーワード3')
@section('description', 'インデックスページの説明文です')
@section('pageCss') @endsection

@include('layout.header')

@section('content')

このページはインデックスページです。

星画像

@endsection

@include('layout.submenu')

@include('layout.footer')
[/php]

HTMLらしい記述があまりなく、なんだか戸惑ってしまいます。

@extends()
レイアウトの継承設定として用います。
今回は layoutディレクトリ以下の common.blade.php を使用するという設定です。

@section
@endsection を使用する/しない、2種類の書き方があります。
使用しない場合は、名称に当てはめるテキストを設定します。
上記のサンプルでは内容では、ページごとのCSSを読み込むところで @endsection を使用しています。(6~8行目)

@include
サブビューと呼ばれる機能で、別のビューとして用意したものを読み込ませる機能です。(10行目)

インデックスページの結果

views/star/sun.blade.php

続けて「SUN」「MOON」ページも作成してみます。

[php]
@extends('layout.common')

@section('title', '太陽のページ')
@section('keywords', 'キーワード4,キーワード5,キーワード6')
@section('description', '太陽ページの説明文です')
@section('pageCss') @endsection

@include('layout.header')

@section('content')

このページは太陽ページです。

太陽画像

@endsection

@include('layout.submenu')

@include('layout.footer')
[/php]

太陽ページの結果

views/star/moon.blade.php

[php]
@extends('layout.common')

@section('title', '月のページ')
@section('keywords', 'キーワード7,キーワード8,キーワード9')
@section('description', '月ページの説明文です')
@section('pageCss') @endsection

@include('layout.header')

@section('content')

このページは月ページです。

月画像

@endsection

@include('layout.submenu')

@include('layout.footer')
[/php]

月ページの結果

アクションとルーティング

コントローラー(アクション)と、ルーティングはそれぞれ以下の通りとします。
これで正解なのかが今のところまだ解りきっていないので、間違っている場合は訂正したいと思います。

アクション(app/Http/Controllers/StarController.php)

[php]
public function index()
{
return view('star.index');
}

public function sun()
{
return view('star.sun');
}

public function moon()
{
return view('star.moon');
}
[/php]

ルーティング(routes/web.php)

[php]
Route::get('/star', 'StarController@index');
Route::get('/star/sun', 'StarController@sun');
Route::get('/star/moon', 'StarController@moon');
[/php]

-Laravel
-, , ,