Laravel 5.1 入門記 その9(Blade Templates 編)
今回は Blade Templates に入ります。
Blade Templates - Laravel - The PHP Framework For Web Artisans
ちらちらサンプル的なものが見えてたので、簡単なシンタックスシュガーは飛ばしていきたいところ。
Introduction
Blade テンプレートファイルは resource/views 配下に拡張子 .blade.php を配置して使います。そしてテンプレートファイルは、PHP にコンパイルされて、変更があるまではキャッシュを読み込むようです。
Template Inheritance
いきなりテンプレートの継承か…。
<!-- Stored in resources/views/layouts/master.blade.php -->
<html>
<head>
<title>App Name - @yield('title')</title>
</head>
<body>
@section('sidebar')
This is the master sidebar.
@show
<div class="container">
@yield('content')
</div>
</body>
</html>
これがベースになるテンプレート。@yield や @section などをこのベーステンプレートを継承したファイルにおいて記述していきます。続いて、ベースを継承する子供テンプレート。
<!-- Stored in resources/views/layouts/child.blade.php -->
@extends('layouts.master')
@section('title', 'Page Title')
@section('sidebar')
@parent
<p>This is appended to the master sidebar.</p>
@endsection
@section('content')
<p>This is my body content.</p>
@endsection
子供のテンプレートでは、親テンプレートになかった @extends で親となるテンプレートを指定しています。そして親テンプレートで定義のあった、 title / sidebar / content を @section で定義してあります。 @section('sidebar') の直後にある @parent は、親テンプレートの section の内容が展開されます。これを書いておくと上書きでは無く、追記する感じになります。
続いて、ルーティングを登録します。
Route::get('blade', function () {
return view('child');
});
view に渡すべきは子供のテンプレート名です。 そういえば、.blade は要らないんだな。ブラウザで http://localhost:8080/blade にアクセス!
This is the master sidebar.
This is appended to the master sidebar.
This is my body content.
\(^o^)/\(^o^)/\(^o^)/
何か一山越えた感があります。
Displaying Data
Blade テンプレートを使うと、変数の出力のシンタックスも変わります。
{{ $name }}
{{ time() }}
これで $name の出力になります。簡略化されました。time() のようにすると同じやり方で関数の戻り値の表示もできます。
ちなみに {{ }} で出力した内容は、HTML escape が自動的に行われるらしい。HTML escape をさせたくない場合は
{!! $name !!}
という書き方をすれば、そのままの文字列が出力される。
{{ name }} のような表現を Blade に無視させるには @{{ name }} とすれば良いらしい。これで、 {{ name }} がそのまま HTML に表示される。
$name がセットされていないときにデフォルト値を表示したい場合は、
{{ isset($name) ? $name : 'Default' }}
のようにも書けるが
{{ $name or 'Default' }}
と簡略化できる。
Control Structures
If Statements
まぁ、見れば分かるので、こんな感じ。
@if (count($records) === 1)
I have one record!
@elseif (count($records) > 1)
I have multiple records!
@else
I don't have any records!
@endif
unless というのもあるらしい。
@unless (Auth::check())
You are not signed in.
@endunless
Loops
いくつかループには種類があり、for foreach forelse while がある。これも見れば一目瞭然。
@for ($i = 0; $i < 10; $i++)
The current value is {{ $i }}
@endfor
@foreach ($users as $user)
<p>This is user {{ $user->id }}</p>
@endforeach
@forelse ($users as $user)
<li>{{ $user->name }}</li>
@empty
<p>No users</p>
@endforelse
@while (true)
<p>I'm looping forever.</p>
@endwhile
Including Sub-Views
要は、Blade テンプレートなどのインクルードですね。書き方はこんな感じ
<div>
@include('shared.errors')
<form>
<!-- Form Contents -->
</form>
</div>
インクルードする View にパラメータが必要な場合は、次のように書ける。
@include('view.name', ['some' => 'data'])
ちょっと試したいことがあるので、前回作った greeting.php を以下の様に変更します。
Hello, <?php echo $name; ?>. I'm <?php echo $my_name; ?>
compoer_value: <?php echo $composer_value; ?>
html と body タグは外しちゃいました。そして、 child.blade.php も変更
@extends('layouts.master')
@section('title', 'Page Title')
@section('sidebar')
@parent
<p>This is appended to the master sidebar.</p>
@endsection
@section('content')
<p>This is my body content.</p>
@include('greeting', ['name' => 'James'])
@endsection
@include('greeting', ['name' => 'James']) というのを追加しました。これで何を試したかったかと言うと、include したときにも View Composer が働くかどうかと言う点。ではブラウザでアクセスしてみると
This is the master sidebar.
This is appended to the master sidebar.
This is my body content.
Hello, James. I'm tnamao
compoer_value: class composer!!
できたー\(^o^)/\(^o^)/\(^o^)/ インクルードしたタイミングでも View Composer は実行されているようですね。
Comments
Blade でのコメントは以下の様な感じ。まぁ、たまに使いたくなりますよね。
{{-- This comment will not be present in the rendered HTML --}}
Service Injection
テンプレートでやるのか… という感じも受けたけど、やり方だけ確認しておきます。
@inject('metrics', 'App\Services\MetricsService')
<div>
Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>
@inject でサービスクラスを指定し、第1引数がテンプレート内で使う変数名で、第2引数がクラスやインターフェース名とのこと。
Extending Blade
Blade 拡張。要は、ディレクティブの拡張らしい。次の例が datetime をフォーマットしちゃうディレクティブの例のようです。
<?php
namespace App\Providers;
use Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
Blade::directive('datetime', function($expression) {
return "<?php echo with{$expression}->format('m/d/Y H:i'); ?>";
});
}
/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
//
}
}
Blade::directive の第1引数で追加するディレクティブ名を指定し、第2引数に Closure を書くらしい。この Closure が返すのは PHP のコードの模様。これをテンプレート上から呼び出すとディレクティブは最終的に次の PHP コードとなって生成される。
<?php echo with($var)->format('m/d/Y H:i'); ?>
ここで使用している with helper は単純に指定された object / value を返すもので、メソッドチェインを行う時に便利らしい。
with helper イマイチ分からなかった…。
締まらない感じですが、これで Blade Templates のセクションも終了!!\(^o^)/
The Basic を一通りやりきったので、続いては Architecture Foundations か、Database のどちらかに進みます。実用的なのは Database かなぁ…。