前回の続きです。
前回は記事を読んだ方にも試してもらえるように丁寧に書きましたが、これを続けていくと参考書のコピーになってしまいますので、今回からは各手順の概要とポイントの整理、そしてやってみて気づいたことやCakePHPとの違いなどについて触れていこうと思います。
初めてのLaravel学習の参考にするには情報が足りないと思いますので、同じ参考書*1 を読んでいただくか、少しバージョンは遡りますが公式の基本のタスクリスト 5.2 Laravelや中級者向けタスクリスト 5.2 Laravelなどをやってみると良いでしょう。
ルーティング設定(参考書Chapter8)
Laravelのルーティングはroutes/に配置されたルートファイルで設定されています。デフォルトでapi.phpやconsole.phpなども用意されていますが、ブラウザで表示する一般的な用途ではWEBインターフェース向けのルートファイルであるweb.phpを編集します。
ルーティングの基本形はURIとクロージャで定義する次のようなものになります。
Route::get('foo', function () {
return 'Hello World';
});
これは「http://[domain]/fooにGET*2 でアクセスしたら、ビューにHello worldを渡す」という意味の記述になります。
参考書Chapter8では、まずはこのクロージャを使って各ページを定義して、その後のChapterでにコントローラに渡す記述に書き換えるようです。これがコントローラとアクションを指定した記述です。
Route::get('/foo', 'FoosController@index');
CakePHPの配列指定よりもスッキリしていますね。
CakePHPではroute.phpではURIに対してどのコントローラ、どのアクションを呼ぶか?という指定をしましたが、Laravelのルーティングではクロージャにビジネスロジックを書くこともできるので、コントローラでやるようなこともルーティングだけでできてしまう自由度の高さがあります。これは上手くコントロールできれば非常に便利ですが、その反面好き勝手できてしまうのでチーム開発ではコーディングルールをしっかりと決める必要があると思います。
他にもリダイレクトを行うリダイレクトルート。
Route::redirect('/here', '/there', 301);
ビューファイルだけを表示するビュールートがあります。
Route::view('/welcome', 'welcome'); Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
参考書ではルーティングの仕組みや機能について詳しく説明されていないので、ルーティング 5.5 Laravelこちらも合わせて確認したほうが良いでしょう。
ルーティングに関しては知っておく必要があることが沢山あるので、もう少しLaravelを使い慣れたらまとめてみたいと思います。
Bladeによるレイアウトとビュー(参考書Chapter9)
ビューファイルは/resources/views/に配置されます。
LaravelではBladeというテンプレートエンジンが使われています。
テンプレートエンジンの意味
私は今までテンプレートエンジンなんか使わなくてもCakePHPのようにビューは素のPHPでいいんじゃないの?と思ってきました。
メリットは特定の記述*3 が楽になるくらいで、逆に制御構文や文字列加工などの処理がしにくくデメリットのほうが大きいでしょう?と。わざわざ新しい構文を覚えて、素のPHPよりも制約の多い記述で書くのはナンセンスじゃないかと思っていたのです。
ただLaravelのBladeはいいですね。まず素のPHPがすんなり書けることが嬉しい。
もしかしたら他のテンプレートエンジンでもできるのかもしれませんが、BladeにはPHPの記述を埋め込むための@phpディレクティブが用意されています。
@php
//
@endphp
もっと言えばビューファイル自体[ファイル名].blade.phpというPHPの拡張子をつけることになっているので、何もしなくても普通に<php ?>の記述が動作します。
もちろん、ビューの役割を徹底させるなら値の加工は全てビジネスロジック側で行われているべきで、ビューにはテンプレートエンジンで書けないようなロジックを書くべきでは無いので極力使いません。・・・ですが、安心感はありますよね?(笑)
Bladeならエスケープ処理が楽にできるし、便利な機能もありそう(使いながら発見します)。しかも素のPHPも動くというならデメリットはありませんので、前向きな気持で使っていきたいと思います。
レイアウトとビューの関係
CakePHP2でいうところの/app/Views/Layouts/に置くレイアウトファイルは、Laravelではresources/views/layouts/に置きます。
ただCakePHPとは考え方が違っていて、LaravelはCakeでいうビュー(Laravel公式ドキュメントでは子のページ)でレイアウトを指定@extends('layouts.ファイル名')して、定義したセクション@section(セクション名)をレイアウトで@yield(セクション名)して表示する感じです。言葉ではわかりにくいと思いますのでコードで見てみましょう。
レイアウト例:/resources/views/layouts/app.blade.php
<html>
<head>
<title>アプリ名 - @yield('title')</title>
</head>
<body>
<div class="container">
{{-- contentセクションを表示 --}}
@yield('content')
</div>
</body>
</html>
ビュー(子ページ)例:/resources/views/index.blade.php
{{-- レイアウトを指定 --}}
@extends('layouts.app')
{{-- contentセクションを定義 --}}
@section(content)
ここにページの中身
@endsection
現時点の知識で言うとCakePHPの方がスッキリしていて好きでした。コントローラでまとめて標準のレイアウトを指定できたし、ビューにはコンテンツとして呼び出されるコードだけを記述できました。
それに比べるとLaravelの場合はわざわざビュー側で毎回レイアウトをextendsしなければならないこと、ページのコンテンツをセクションで定義しなければならなことが煩わしく感じます。
もっとLaravelを知ればこの煩わしさを解消する方法や、逆にこの方がいいんだと思える理由に気づくかもしれないので、それを期待しながら使っていきたいと思います。
よく使うディレクティブ
Bladeでよく使われそうなディレクティブをメモ的にまとめておきます。
- @extends
- 「継承」するレイアウトを指定します。
- @section
-
@section(セクション名)でセクションを定義します。
@section() ... @endsectioonで範囲指定できるほか、@section(セクション名, 'テキストコンテンツ')のように、第2引数でセクションの中身自体を定義することもできます。 - @show
@sectionから@showまでの間をすぐに表示します。- @yield
- 定義したセクションを表示します。
- @@parent
- ビュー(小ページ)のセクションの中で定義するとレイアウト(親)の内容に置き換わります。
うーん、ややこしい。セクションの概念はすんなり頭に入ってきませんね。
使っていればわかってくると思うのでとりあえずは深掘りしないで進めてみます。
データ表示
{{ $変数名 }}がhtmlspecialchars付きで表示。
{!! $変数名 !!}がエスケープ無しで表示。
5.5のドキュメントでは消えていますが{{ $name or 'テスト' }}で$nameという変数が無ければテストを表示するというふうにも書けます。
{{ time() }}のように、ビューに渡された変数を含まなければPHPのコードもそのままechoされます。
PHPの配列をjsonに置き換えてechoする@jsonディレクティブというのもあります。
<script>
var app = @json($array);
// <?php echo json_encode($array); ?>; と同義
</script>
ちなみにjavascript内で{}を使いたい場合には頭に@を付けることでBladeの展開を回避できます。
Hello, @{{ name }}.
広い範囲でBladeの展開を回避したいなら
@verbatim
<div class="container">
Hello, {{ name }}.
</div>
@endverbatim
さて今回はルーティングとBladeを使ったビューと表示周りをやりました。
次回はおそらくビジネスロジックの実装になると思いますが、参考書では初めにroutes/web.phpに記述してからコントローラに実装し直すようです。
たぶん「ルーティングファイルにもビジネスロジックを書けるんだよ」ということだと思いますが、コントローラまで進めてから記事を書きたいと思います。
- Kindle Unlimitedに入ると無料で読めますので、無料体験があればそれでも良いかと。1冊にかかる時間は詰まるところが無ければ数時間で終わると思います。 [↩]
- HTTPリクエストメソッドのGETを指す。https://developer.mozilla.org/ja/docs/Web/HTTP/Methods [↩]
- SmartyやPHPTalを使ったことがあるのですが、テンプレートエンジンは=h($変数)?>が{{変数}}のようなエスケープ処理が楽になることくらいのメリットしか無いと思ってました。テンプレートの継承やコンポーネントやスロットはCakePHPならLayouts,Elements,fetchで再現できていましたし、制御構文もビジネスロジックと違う見慣れない記述が並ぶよりは、素のPHPで統一されていたほうが可読性が高いんじゃない?という感じでした。 [↩]
