はじめに
こんにちは、エンジニア2年目の嶋田です。
まずは、この記事を開いていただきありがとうございます!
今回は、LaravelのBladeディレクティブについて解説したいと思います。
最後までお付き合いください!
目次
- Bladeとは
- ディレクティブについて
- 分岐
- 認証ディレクティブ
- 環境ディレクティブ
- セクションディレクティブ
- 繰り返し
- ループ変数
- レイアウト作成用
- HTML要素に追加
- @onceディレクティブ
- 生PHP
- 最後に
Bladeとは
Laravelのview作成にはHTMLではなくBladeが使用されます。
ベースとなる書き方はHTMLですが、加えてBlade固有の色々な機能を使用することができます。
Bladeを使うと、テンプレートを継承したり、レイアウトの一部をセクションの一部としてはめ込むことができます。
効率的にレイアウトを作成したいならBladeを使うといいと思います!
Bladeは、Laravelに含まれているシンプルでありながら強力なテンプレートエンジンです。一部のPHPテンプレートエンジンとは異なり、BladeはテンプレートでプレーンなPHPコードの使用を制限しません。実際、すべてのBladeテンプレートはプレーンなPHPコードにコンパイルされ、変更されるまでキャッシュされます。つまり、Bladeはアプリケーションに実質的にオーバーヘッドをかけません。Bladeテンプレートファイルは.blade.phpファイル拡張子を使用し、通常はresources/viewsディレクトリに保存します。
ディレクティブについて
構文のような役割を果たすものでテンプレートに簡単に組み込むことができます。
@から始まる範囲内で特定の処理を実行することができる記述方法です。
例)
@include('layouts.footer')
@include('layouts.header', ["banana" => 'yellow'])
ディレクティブの利点は動的な部分のコードを比較的少ないコードで記述が可能となることです。
分岐
分岐のディレクトリは以下のようにまとめられます。
ディレクティブ | 役割 |
---|---|
@if(条件) |
条件分岐 |
@unless(変数) |
条件非成立の時表示 |
@empty(変数) |
変数が空の場合表示 |
@isset(変数) |
変数が定義済みの場合表示 |
@switch |
複数の条件に基づいた分岐処理を実行 |
if
@if
、@elseif
、@else
、@endif
ディレクティブを使用してif文を作成できます。
これらのディレクティブは、対応するPHPの構文と同じように機能します。
使用例は以下の通りです。
@if (count($records) === 1)
1レコードあります。
@elseif (count($records) > 1)
複数レコードあります。
@else
レコードがありません。
@endif
unless
unlessはifと逆の動きをします。
要は判定がfalseの場合に生じる処理が実行されるということです。
@unless (Auth::check())
あなたはサインインしていません。
@endunless
empty
emptyは変数内が空の時に実行されるという書き方です。
空文字列, null, 0などの時にtrueとなります。
@empty($records)
// $recordsは「空」だ…
@endempty
isset
issetはその変数が定義済みでnullではない時に実行されるという書き方です。
定義されていた場合にtrueとなります。
@isset($records)
// $recordsが定義済みで、NULLではない…
@endisset
上記、empty,issetに関しては判定が複雑なので私はこちらの早見表をよくみていました。
switch
switch文は、@switch
、@case
、@break
、@default
、@endswitch
ディレクティブを使用して作成できます。
これらのディレクティブは、対応するPHPの構文と同じように機能します。
使用例は以下の通りです。
@switch($i)
@case(1)
最初のケース…
@break
@case(2)
2番めのケース…
@break
@default
デフォルトのケース…
@endswitch
認証ディレクティブ
こちらは非常に便利です。
@auth
および@guest
ディレクティブを使用すると、現在のユーザーが認証済みであるか、ゲストであるかを簡潔に判断できます。使用例は以下の通りです。
@auth
// ユーザーは認証済み…
@endauth
@guest
// ユーザーは認証されていない…
@endguest
環境ディレクティブ
@production
ディレクティブを使用して、アプリケーションが本番環境で実行されているかを確認できます。
@production
// Production限定コンテンツ…
@endproduction
また、@env
ディレクティブを使用して、アプリケーションが特定の環境で実行されているかどうかを判断できます。
@env('staging')
// アプリケーションは"staging"で動作している…
@endenv
@env(['staging', 'production'])
// アプリケーションは"staging"か"production"で動作している…
@endenv
セクションディレクティブ
@hasSection
ディレクティブを使用して、テンプレート継承セクションにコンテンツがあるかどうかを判断できます。
@hasSection('navigation')
<div class="pull-right">
@yield('navigation')
</div>
<div class="clearfix"></div>
@endif
また、@sectionMissing
ディレクティブを使用して、セクションにコンテンツがないかどうかを判断できます。
@sectionMissing('navigation')
<div class="pull-right">
@include('default-navigation')
</div>
@endif
繰り返し
条件文に加えて、BladeはPHPのループ構造を操作するための簡単なディレクティブを提供します。繰り返しますが、これらの各ディレクティブは、対応するPHPと同じように機能します。
今回は記載していませんが、@continue
および@break
ディレクティブを使用して、反復をスキップするか、ループを終了することもできます。
繰り返しのディレクトリは以下のようにまとめられます。
ディレクティブ | 役割 |
---|---|
@for(初期化 ; 条件; 後処理;) |
PHPのfor構文に相当するもの |
@foreach(配列, 変数) |
PHPのforeach構文に相当するもの |
@while(条件) |
PHPのwhile構文に相当するもの |
for
for文として使用できます。指定の回数処理を繰り返す場合に有効です。
@for ($i = 0; $i < 10; $i++)
現在の値は、{{ $i }}
@endfor
while
while文として使用できます。
指定した条件がtrueの間はループし続けます。
@php
$counter = 0;
@endphp
@while ($counter < 10)
<p>現在の値は {{ $counter }}</p>
@php
$counter++;
@endphp
@endwhile
foreach
foreach文として使用できます。
配列やコレクションの要素分ループします。ループ処理のなかでは最もよく使うと思います。
@foreach ($users as $user)
<p>このユーザーは:{{ $user->id }}</p>
@endforeach
forelse
foreachと同じく配列やコレクションの要素をループします。
foreachに加え、配列やコレクションに要素が存在しない場合の処理を@emptyディレクティブに記述することができます。
@forelse ($users as $user)
<li>{{ $user->name }}</li>
@empty
<p>ユーザーはいません。</p>
@endforelse
ループ変数
Bladeでは、$loop
という繰り返し処理で使用できる特殊な変数が存在します。
「$loop->取り出したい値」とアクセスすることで、様々なプロパティにアクセスすることが可能となります。
繰り返しのディレクティブに用意されている変数 $loop
の使い方は以下の通りです。
ループ変数 | 役割 |
---|---|
$loop->index |
現在のインデックス(0~) |
$loop->iteration |
現在の繰り返し数(1~) |
$loop->remaining |
後何回繰り返すのか |
$loop->count |
繰り返しで使っている配列の要素数 |
$loop->first |
最初の繰り返しかどうか |
$loop->last |
最後の繰り返しかどうか |
$loop->depth |
繰り返しのネスト数 |
$loop->parent |
ネストしている場合、親の繰り返しループ変数を示す |
foreach
ループの反復処理中、ループの内部では$loop
変数を利用できます。
この変数により、現在のループのインデックスや、ループの最初の反復なのか最後の反復なのか、といった便利な情報にアクセスすることができます。
@foreach ($users as $user)
@if ($loop->first)
これが最初の繰り返しです。
@endif
@if ($loop->last)
これが最後の繰り返しです。
@endif
<p>このユーザーは:{{ $user->id }}</p>
@endforeach
ネストしたループ内にいる場合は、parent
プロパティを介して親ループの$loop
変数にアクセスできます。
@foreach ($users as $user)
@foreach ($user->posts as $post)
@if ($loop->parent->first)
これは親ループの最初の繰り返しです。
@endif
@endforeach
@endforeach
ちなみに、ネストとは、あるものの中に、それと同じ形や種類の(一回り小さい)ものが入っている状態や構造のことです!
レイアウト作成用
レイアウト作成時に必要なディレクティブは以下のようにまとめられます。
ディレクティブ | 役割 |
---|---|
@section(名前) |
指定した名前でセクションが用意される |
@yield(名前) |
配置場所を示すもの |
@extends(Bladeのファイル名) |
レイアウトの継承設定 |
@parent |
親レイアウトのセクションを示す |
@component(名前) |
コンポーネントの組み込み |
@slot(名前) |
コンポーネントに動的なコンテンツを挿入する |
@include(読み込むテンプレート名, [値の指定]) |
サブビューの読み込み |
@each(テンプレート名, 配列, 配列から取り出したデータを入れる変数名) |
配列などから値を取り出し指定のテンプレートにはめ込んで出力する |
section
@section
ディレクティブは、テンプレート内でセクションを定義するために使います。
セクションは、後で他のテンプレートで展開するために内容を保持するものです。
例えば、ウェブページのタイトルやコンテンツ部分を定義するのに役立ちます。
セクションを定義するには、@section
ディレクティブにセクション名を第一引数に指定し、その中にHTMLやテキストを記述します。使用例は以下の通りです。
@section('title', 'laratimes')
@section('content')
<div>
{{ $hoge }}
</div>
@endsection
title
と content
という2つのセクションを定義しています。これらのセクションは、後で@yield
ディレクティブを使用して展開することができます。
yield
@yield
ディレクティブは、@section
ディレクティブで定義されたセクションを展開します。
指定したセクション名を引数として渡すことで、そのセクションの内容を表示できます。
@yield('content')
このコードは、content
セクションの内容を表示します。
また、第二引数を指定することで、セクションが未定義の場合に代替コンテンツを表示することもできます。
@yield('content', View::make('view.id'))
上記の例では、content
セクションが未定義の場合にview.id
テンプレートを表示します。
extend
@extends
ディレクティブは、親レイアウトを子ビューに継承させるために使います。
親レイアウト内で@yield
ディレクティブで定義したセクションを、子ビュー内で具体的なコンテンツで埋めることができます。
@extends('layouts.app')
この例では、layouts.app
テンプレートを親レイアウトとして継承しています。
parent
@parent
ディレクティブは、親レイアウトからセクションの内容を引き継ぐために使用されます。通常、親レイアウトで定義されたセクションを子ビューで上書きすることができますが、一部の場合にはセクションの内容を拡張したり、追加したりしたい場合があります。その際に @parent
ディレクティブが役立ちます。
例えば、親レイアウトで以下のようにセクションが定義されているとします。
@section('content')
<div>
親レイアウトのコンテンツ
</div>
@endsection
子ビューで同じセクションを上書きしつつ、親レイアウトの内容も表示したい場合、@parent
ディレクティブを使用します。
@extends('layouts.app')
@section('content')
@parent
<div>
子ビューの追加コンテンツ
</div>
@endsection
この例では、@parent
ディレクティブを使用して親レイアウトのコンテンツを引き継ぎつつ、子ビュー独自のコンテンツを追加しています。最終的に、親レイアウトのコンテンツと子ビューの追加コンテンツが合わさって表示されます。
include
each
componentとslot
@component
ディレクティブを使用すると、コンポーネントをビューに組み込むことができます。
コンポーネントは再利用可能な部品で、ビュー内で何度も使うことができます。
@component('components.header')
@slot('header_title')
ページタイトル
@endslot
@slot('header_content')
<li>項目1</li>
<li>項目2</li>
@endslot
@endcomponent
上記の例では、components.header
コンポーネントをビューに組み込んでいます。
@slot
ディレクティブを使用して、コンポーネント内のスロットに値を設定しています。
細かい解説はこちらをご覧ください…
include
この記事の冒頭ディレクティブの書き方の際にも出てきた@include
です。
@include
ディレクティブを使用すると、他のテンプレートを読み込むことができます。
第一引数に読み込みたいテンプレートの名前を指定し、必要に応じて第二引数にテンプレートに渡す値を配列で指定できます。
@include('layouts.footer')
@include('layouts.header', ["banana" => 'yellow'])
上記の例では、layouts.footer
とlayouts.header
テンプレートを読み込んでいます。
["banana" => 'yellow']
のように第二引数に値を渡すことができます。
each
@each
ディレクティブを使用すると、配列やコレクションから値を取り出し、指定のテンプレートに組み込んで出力することができます。これを使って、繰り返し表示する要素を簡単に生成できます。
@each('view.name', $jobs, 'job')
上記の例では、view.name
テンプレートを$jobs
配列から取り出した値を使って繰り返し表示しています。
また、job
という変数名を指定しています。
HTML要素に追加
HTML要素に追加するディレクティブは以下のようにまとめられます。
ディレクティブ | 役割 |
---|---|
@class |
指定したクラス名を条件に基づいて追加する |
@style |
指定したスタイルを条件に基づいて追加する |
@checked |
チェックボックスのchecked 属性を条件に基づいて追加する |
@selected |
セレクトボックスのオプションにselected 属性を条件に基づいて追加する |
@disabled |
HTML要素にdisabled 属性を条件に基づいて追加する。 |
@readonly |
HTML要素にreadonly 属性を条件に基づいて追加する |
@required |
HTML要素にrequired 属性を条件に基づいて追加する |
class
@class
を使って、条件に応じてクラスを追加できます。
条件付きクラスは、HTML要素にクラス(スタイルやデザインを適用するための指示)を追加する方法です。
たとえば、ウェブページで「ログインしているかどうか」や「エラーが発生しているかどうか」によって、要素のスタイルを変えたい場合があります。以下はその例です。
@php
$isLoggedIn = false;
$hasError = true;
@endphp
<span @class([
'p-4',
'font-bold' => $isLoggedIn,
'text-gray-500' => !$isLoggedIn,
'bg-red' => $hasError,
])></span>
このコードでは、$isLoggedIn
がtrue
の場合はfont-bold
クラスを追加し、$isLoggedIn
がfalse
の場合はtext-gray-500
クラスを追加します。また、$hasError
がtrue
の場合はbg-red
クラスを追加します。
これにより、条件に応じて要素のスタイルを変更できます。
style
@style
を使って、条件に応じてスタイルを適用できます。
条件付きスタイルは、HTML要素にインラインのCSSスタイルを追加する方法です。
たとえば、特定の状況で背景色やフォントの太さを変えたい場合があります。以下はその例です。
@php
$isActive = true;
@endphp
<span @style([
'background-color: red',
'font-weight: bold' => $isActive,
])></span>
このコードでは、$isActive
がtrue
の場合は背景色を赤にし、$isActive
がfalse
の場合は太字のフォントを適用します。
これにより、条件に応じて要素のスタイルをカスタマイズできます。
checked
@checked
ディレクティブを使用すると、指定したHTMLのチェックボックス入力がchecked
であることを条件に基づいて設定できます。
たとえば、フォームでユーザーが事前にチェックしたい場合、次のように使えます。
<input type="checkbox"
name="active"
value="active"
@checked(old('active', $user->active)) />
このコードでは、old
関数とユーザーモデルから取得した値に基づいて、チェックボックスが事前にチェックされるかどうかを制御します。
selected
@selected
ディレクティブは、セレクトボックスのオプションにselected
属性を条件に基づいて追加します。
たとえば、特定のバリューが選択済みであるかどうかを制御したい場合、次のように使用します。
<select name="version">
@foreach ($product->versions as $version)
<option value="{{ $version }}" @selected(old('version') == $version)>
{{ $version }}
</option>
@endforeach
</select>
このコードでは、old
関数を使用してフォームの以前のバリューを取得し、選択したバリューと一致するオプションにselected
属性を追加します。
disabled
@disabled
ディレクティブは、指定したHTML要素にdisabled
属性を条件に基づいて追加します。
たとえば、エラーが発生した場合に送信ボタンを無効にする場合、次のように使えます。
<button type="submit" @disabled($errors->isNotEmpty())>Submit</button>
このコードでは、$errors->isNotEmpty()
の条件に基づいて送信ボタンが無効になります。
readonly
@readonly
ディレクティブを使用すると、指定したHTML要素にreadonly
属性を条件に基づいて追加します。
たとえば、特定のユーザーが編集できないようにする場合、次のように使えます。
<input type="email"
name="email"
value="email@laravel.com"
@readonly($user->isNotAdmin()) />
このコードでは、$user->isNotAdmin()
の条件に基づいて、メール入力フィールドが読み取り専用になります。
required
@required
ディレクティブは、指定したHTML要素にrequired
属性を条件に基づいて追加します。
たとえば、特定の条件下でフォームフィールドを必須にする場合、次のように使えます。
<input type="text"
name="title"
value="title"
@required($user->isAdmin()) />
このコードでは、$user->isAdmin()
の条件に基づいて、タイトル入力フィールドが必須になります。
onceディレクティブ
@once
ディレクティブを使用すると、テンプレートの特定の部分をレンダリングサイクルごとに1回だけ評価できます。
これは、JavaScriptの特定のコードをページのヘッダーに追加する場合に便利です。
たとえば、ループ内で特定のコンポーネントをレンダリングし、そのコンポーネントが初めてレンダリングされるときにのみJavaScriptをヘッダーに追加したい場合などに役立ちます。
@once
@push('scripts')
<script>
// カスタムJavaScript…
</script>
@endpush
@endonce
このコードでは、@once
ディレクティブ内のコードブロックは1回だけ評価され、その後のレンダリングサイクルでは無視されます。これにより、不要な重複を避けてカスタムJavaScriptを追加できます。
@once
ディレクティブは、通常、@push
や@prepend
ディレクティブと組み合わせて使用されます。
便利な@pushOnce
と@prependOnce
ディレクティブも用意されており、使用例は以下の通りです。
@pushOnce('scripts')
<script>
// カスタムJavaScript…
</script>
@endPushOnce
これで、同じJavaScriptコードが重複して追加されるのを防ぎながら、必要な部分にJavaScriptを追加できます。
生PHP
状況によっては、PHPコードをビューに埋め込めると便利ですよね。
@php
ディレクティブを使用して、テンプレート内でプレーンPHPのブロックを定義し、実行することが可能です。
@php
$counter = 1;
@endphp
また、PHP文を1つ書くだけなら、@php
ディレクティブ内に含められます。
@php($counter = 1)
最後に
記事を読んでくださり、ありがとうございます!
長くなってしまいましたが、少しでもお役に立てたら嬉しいです。
Bladeディレクティブは、便利でコードの簡略化につながるところが魅力ですよね。
私自身もまだまだ学びの途中なので、もし何か誤った情報がありましたら、コメントでご指摘いただければ幸いです!