Laravel 7.x Bladeテンプレート

イントロダクション

BladeはシンプルながらパワフルなLaravelのテンプレートエンジンです。他の人気のあるPHPテンプレートエンジンとは異なり、ビューの中にPHPを直接記述することを許しています。全BladeビューはPHPへコンパイルされ、変更があるまでキャッシュされます。つまりアプリケーションのオーバーヘッドは基本的に0です。Bladeビューには.blade.phpファイル拡張子を付け、通常はresources/viewsディレクトリの中に設置します。

テンプレートの継承

レイアウト定義

Bladeを使用する主な利点は、テンプレートの継承セクションです。初めに簡単な例を見てください。通常ほとんどのアプリケーションでは、数多くのページを同じ全体的なレイアウトの中に表示するので、最初は"master"ページレイアウトを確認しましょう。レイアウトは一つのBladeビューとして、簡単に定義できます。

<!-- resources/views/layouts/app.blade.phpとして保存 -->

<html>
    <head>
        <title>アプリ名 - @yield('title')</title>
    </head>
    <body>
        @section('sidebar')
            ここがメインのサイドバー
        @show

        <div class="container">
            @yield('content')
        </div>
    </body>
</html>

ご覧の通り、典型的なHTMLマークアップで構成されたファイルです。しかし、@section@yieldディレクティブに注目です。@sectionディレクティブは名前が示す通りにコンテンツのセクションを定義し、一方の@yieldディレクティブは指定したセクションの内容を表示するために使用します。

これでアプリケーションのレイアウトが定義できました。このレイアウトを継承する子のページを定義しましょう。

レイアウト拡張

子のビューを定義するには、「継承」するレイアウトを指定する、Blade @extendsディレクティブを使用します。Bladeレイアウトを拡張するビューは、@sectionディレクティブを使用し、レイアウトのセクションに内容を挿入します。前例にあるようにレイアウトでセクションを表示するには@yieldを使用します。

<!-- resources/views/child.blade.phpとして保存 -->

@extends('layouts.app')

@section('title', 'Page Title')

@section('sidebar')
    @@parent

    <p>ここはメインのサイドバーに追加される</p>
@endsection

@section('content')
    <p>ここが本文のコンテンツ</p>
@endsection

この例のsidebarセクションでは、レイアウトのサイドバーの内容をコンテンツに上書きするのではなく追加するために@@parentディレクティブを使用しています。@@parentディレクティブはビューをレンダーするときに、レイアウトの内容に置き換わります。

Tip!! 直前の例とは異なり、このsidebarセクションは@showの代わりに@endsectionで終わっています。@endsectionディレクティブはセクションを定義するだけに対し、@showは定義しつつ、そのセクションを即時にその場所に取り込みます

@yieldディレクティブは、デフォルト値を第2引数に受け取ります。この値は埋め込み対象のセクションが未定義の場合にレンダーされます。

@yield('content', View::make('view.name'))

Bladeビューはグローバルなviewヘルパを使用し、ルートから返すことができます。

Route::get('blade', function () {
    return view('child');
});

データ表示

Bladeビューに渡されたデータは、波括弧で変数を囲うことで表示できます。たとえば、次のルートがあるとしましょう。

Route::get('greeting', function () {
    return view('welcome', ['name' => 'Samantha']);
});

name変数の内容を表示しましょう。

Hello, {{ $name }}.

Tip!! Bladeの{{ }}記法はXSS攻撃を防ぐため、自動的にPHPのhtmlspecialchars関数を通されます。

ビューに渡された変数の内容を表示するだけに限られません。PHP関数の結果をechoすることもできます。実際、どんなPHPコードもBladeのecho文の中に書けます。

The current UNIX timestamp is {{ time() }}.

エスケープしないデータの表示

デフォルトでブレードの{{ }}文はXSS攻撃を防ぐために、PHPのhtmlspecialchars関数を自動的に通されます。しかしデータをエスケープしたくない場合は、以下の構文を使ってください。

Hello, {!! $name !!}.

Note: アプリケーションでユーザーの入力内容をechoする場合は注意が必要です。ユーザーの入力を表示するときは、常に二重の波括弧の記法でHTMLエンティティにエスケープすべきです。

JSONのレンダー

JavaScriptの変数を初期化するために、配列をビューに渡してJSONとして描画できます。

<script>
    var app = <?php echo json_encode($array); ?>;
</script>

その際、json_encodeを使う代わりに、@jsonディレクティブを使うことができます。@jsonディレクティブは、PHPのjson_encode関数と同じ引数を受けます。

<script>
    var app = @json($array);

    var app = @json($array, JSON_PRETTY_PRINT);
</script>

Note: @jsonディレクティブは既存の変数をJSONとしてレンダするためだけに使用してください。Bladeテンプレートは正規表現ベースのため、複雑な式をディレクティブに渡すと予期しない不良動作の原因になります。

HTMLエンティティエンコーディング

Blade(およびLaravelのeヘルパ)はデフォルトで、HTMLエンティティをdouble encodeします。double encodeを無効にするには、AppServiceProviderbootメソッドで、Blade::withoutDoubleEncodingメソッドを呼び出してください。

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * アプリケーションの全サービスの初期処理
     *
     * @return void
     */
    public function boot()
    {
        Blade::withoutDoubleEncoding();
    }
}

BladeとJavaScriptフレームワーク

与えられた式をブラウザに表示するため、多くのJavaScriptフレームワークでも波括弧を使っているので、@シンボルでBladeレンダリングエンジンに波括弧の展開をしないように指示することが可能です。

<h1>Laravel</h1>

Hello, @{{ name }}.

この例で、@記号はBladeにより削除されます。しかし、{{ name }}式はBladeエンジンにより変更されずにそのまま残り、JavaScriptフレームワークによりレンダリングできるようになります。

@記号は、Bladeディレクティブをエスケープするためにも使用します。

{{-- Blade --}}
@@json()

<!-- HTML出力 -->
@json()

@verbatimディレクティブ

テンプレートの広い箇所でJavaScript変数を表示する場合は、HTMLを@verbatimディレクティブで囲めば、各Blade echo文の先頭に@記号を付ける必要はなくなります。

@verbatim
    <div class="container">
        Hello, {{ name }}.
    </div>
@endverbatim

制御構文

テンプレートの継承とデータ表示に付け加え、Bladeは条件文やループなどの一般的なPHPの制御構文の便利な短縮記述方法を提供しています。こうした短縮形は、PHP制御構文の美しく簡潔な記述を提供しつつも、対応するPHPの構文と似せています。

If文

if文の構文には、@if@elseif@else@endifディレクティブを使用します。これらの使い方はPHPの構文と同じです。

@if (count($records) === 1)
    1レコードある!
@elseif (count($records) > 1)
    複数レコードある!
@else
    レコードがない!
@endif

便利な@unlessディレクティブも提供しています。

@unless (Auth::check())
    あなたはログインしていません。
@endunless

さらに、すでに説明したように@isset@emptyディレクティブも、同名のPHP関数の便利なショートカットとして使用できます。

@isset($records)
    // $recordsは定義済みでnullでない
@endisset

@empty($records)
    // $recordsが「空」だ
@endempty

認証ディレクティブ

@auth@guestディレクティブは、現在のユーザーが認証されているか、もしくはゲストであるかを簡単に判定するために使用します。

@auth
    // ユーザーは認証済み
@endauth

@guest
    // ユーザーは認証されていない
@endguest

必要であれば、@auth@guestディレクティブ使用時に、確認すべき認証ガードを指定できます。

@auth('admin')
    // ユーザーは認証済み
@endauth

@guest('admin')
    // ユーザーは認証されていない
@endguest

セクションディレクティブ

セクションがコンテンツを持っているかを判定したい場合は、@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

環境ディレクティブ

アプリケーションが実働環境("production")で実行されているかを調べるには、@productionディレクティブを使います。

@production
    // 実働環境のコンテンツを指定…
@endproduction

もしくは、特定の環境でアプリケーションが実行されているかを判定するには、@envディレクティブを使います。

@env('staging')
    // アプリケーションが"staging"環境で実行中
@endenv

@env(['staging', 'production'])
    // アプリケーションが"staging"と"production"環境で実行中
@endenv

Switch文

@switch@case@break@default@endswitchディレクティブを使用し、switch文を構成できます。

@switch($i)
    @case(1)
        最初のケース
        @break

    @case(2)
        2番めのケース
        @break

    @default
        デフォルトのケース
@endswitch

繰り返し

条件文に加え、BladeはPHPがサポートしている繰り返し構文も提供しています。これらも、対応するPHP構文と使い方は一緒です。

@for ($i = 0; $i < 10; $i++)
    現在の値は: {{ $i }}
@endfor

@foreach ($users as $user)
    <p>これは {{ $user->id }} ユーザーです。</p>
@endforeach

@forelse ($users as $user)
    <li>{{ $user->name }}</li>
@empty
    <p>ユーザーなし</p>
@endforelse

@while (true)
    <p>無限ループ中</p>
@endwhile

Tip!! 繰り返し中はループ変数を使い、繰り返しの最初や最後なのかなど、繰り返し情報を取得できます。

繰り返しを使用する場合、ループを終了するか、現在の繰り返しをスキップすることもできます。

@foreach ($users as $user)
    @if ($user->type == 1)
        @continue
    @endif

    <li>{{ $user->name }}</li>

    @if ($user->number == 5)
        @break
    @endif
@endforeach

もしくは、ディレクティブに条件を記述して、一行で済ますこともできます。

@foreach ($users as $user)
    @continue($user->type == 1)

    <li>{{ $user->name }}</li>

    @break($user->number == 5)
@endforeach

ループ変数

繰り返し中は、$loop変数が使用できます。この変数により、現在のループインデックスや繰り返しの最初/最後なのかなど、便利な情報にアクセスできます。

@foreach ($users as $user)
    @if ($loop->first)
        これは最初の繰り返し
    @endif

    @if ($loop->last)
        これは最後の繰り返し
    @endif

    <p>これは {{ $user->id }} ユーザーです。</p>
@endforeach

ネストした繰り返しでは、親のループの$loop変数にparentプロパティを通じアクセスできます。

@foreach ($users as $user)
    @foreach ($user->posts as $post)
        @if ($loop->parent->first)
            これは親のループの最初の繰り返しだ
        @endif
    @endforeach
@endforeach

$loop変数は、他にもいろいろと便利なプロパティを持っています。

プロパティ 説明
$loop->index 現在のループのインデックス(初期値0)
$loop->iteration 現在の繰り返し数(初期値1)
$loop->remaining 繰り返しの残り数
$loop->count 繰り返し中の配列の総アイテム数
$loop->first ループの最初の繰り返しか判定
$loop->last ループの最後の繰り返しか判定
$loop->even これは偶数回目の繰り返しか判定
$loop->odd これは奇数回目の繰り返しか判定
$loop->depth 現在のループのネストレベル
$loop->parent ループがネストしている場合、親のループ変数

コメント

Bladeでビューにコメントを書くこともできます。HTMLコメントと異なり、Bladeのコメントはアプリケーションから返されるHTMLには含まれません。

{{-- このコメントはレンダー後のHTMLには現れない --}}

PHP

PHPコードをビューへ埋め込むと便利な場合もあります。Bladeの@phpディレクティブを使えば、テンプレートの中でプレーンなPHPブロックを実行できます。

@php
    //
@endphp

Tip!! Bladeはこの機能を提供していますが、数多く使用しているのであれば、それはテンプレートへ多すぎるロジックを埋め込んでいるサインです。

@onceディレクティブ

@onceディレクティブは、レンダリングサイクルごとに一度だけ評価されるテンプレートの一部を定義できます。これはstacksを使い、JavaScriptをページのヘッダへ挿入するのに便利です。たとえば、ループ内で与えられた コンポーネントをレンダリングしている場合、最初にコンポーネントがレンダリングされたときのみ、JavaScriptをヘッダにプッシュできます。

@once
    @push('scripts')
        <script>
            // カスタムJavaScriptコード…
        </script>
    @endpush
@endonce

フォーム

CSRFフィールド

アプリケーションでHTMLフォームを定義する場合、CSRF保護ミドルウェアがリクエストを検査できるようにするため、隠しCSRFトークンフィールドを含める必要があります。このトークンフィールドを生成するには、@csrf Bladeディレクティブを使用します。

<form method="POST" action="/profile">
    @csrf

    ...
</form>

Methodフィールド

HTMLフォームでは、PUTPATCHDELETEリクエストを作成できないため、見かけ上のHTTP動詞を指定するための_methodフィールドを追加する必要があります。@method Bladeディレクティブでこのフィールドを生成できます。

<form action="/foo/bar" method="POST">
    @method('PUT')

    ...
</form>

バリデーションエラー

@errorディレクティブは、指定した属性のバリデーションエラーメッセージがあるかを簡単に判定するために使用します。@errorディレクティブの中でエラーメッセージを表示するために、$message変数をエコーすることも可能です。

<!-- /resources/views/post/create.blade.php -->

<label for="title">Post Title</label>

<input id="title" type="text" class="@error('title') is-invalid @enderror">

@error('title')
    <div class="alert alert-danger">{{ $message }}</div>
@enderror

複数のフォームにより構成されたページで、バリデーションエラーを取得するために、@errorディレクティブの第2引数として特定のエラーバッグの名前が渡せます。

<!-- /resources/views/auth.blade.php -->

<label for="email">Email address</label>

<input id="email" type="email" class="@error('email', 'login') is-invalid @enderror">

@error('email', 'login')
    <div class="alert alert-danger">{{ $message }}</div>
@enderror

コンポーネント

コンポーネントとスロットは、レイアウトとセクションに似た利便性をもたらします。ですがコンポーネントとスロットのほうが簡単に理解できるメンタルモデルであるとわかってもらえるでしょう。コンポーネントを書くには2つのアプローチがあります。クラスベースコンポーネントと匿名コンポーネントです。

make:component Artisanコマンドを使えば、クラスベースのコンポーネントを生成できます。コンポーネントの使い方を説明するために、簡単なAlertコンポーネントを作成してみましょう。make:componentコマンドはApp\View\Componentsディレクトリの中にコンポーネントを生成します。

php artisan make:component Alert

make:componentコマンドは、コンポーネントのためのビューテンプレートも生成します。このビューはresources/views/componentsディレクトリに生成されます。

パッケージコンポーネントの登録

アプリケーションのために書いたコンポーネントは、自動的にapp/View/Componentsresources/views/componentsディレクトリの中で見つけられます。

しかしながら、Bladeコンポーネントを活用したパッケージを構築している場合、コンポーネントクラスとそのHTMLタグエイリアスを皆さん自身で登録する必要があります。通常、皆さんのパッケージのサービスプロバイダ内にあるbootメソッドで、コンポーネントを登録する必要があります。

use Illuminate\Support\Facades\Blade;

/**
 * パッケージのサービスの初期処理
 */
public function boot()
{
    Blade::component('package-alert', AlertComponent::class);
}

コンポーネントを登録したら、そのタグエイリアスを使用してレンダーします。

<x-package-alert/>

コンポーネントの表示

コンポーネントを表示するには、Bladeテンプレートの中でBladeコンポーネントタグを使用します。Bladeコンポーネントタグとは、コンポーネントクラス名のケバブケースをx-に続けた文字列のことです。

<x-alert/>

<x-user-profile/>

App\View\Componentsディレクトリの中にコンポーネントクラスをネストしている場合は、ディレクトリのネストを表すために.を使います。たとえばApp\View\Components\Inputs\Button.phpがコンポーネントだとすると、次のようにレンダーします。

<x-inputs.button/>

コンポーネントへのデータ渡し

HTML属性を使い、Bladeコンポーネントへデータを渡すことができます。シンプルなHTML属性を使い、ハードコードしたプリミティブ値をコンポーネントへ渡します。PHP表現と変数は、:を前に付けた属性によりコンポーネントへ渡します。

<x-alert type="error" :message="$message"/>

コンポーネントで必須のデータは、クラスのコンストラクタで定義する必要があります。コンポーネント上のパブリックプロパティはすべて、コンポーネントのビューで自動的に使えます。コンポーネントのrenderメソッドからビューへデータを渡す必要はありません。

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Alert extends Component
{
    /**
     * alertのタイプ
     *
     * @var string
     */
    public $type;

    /**
     * alertのメッセージ
     *
     * @var string
     */
    public $message;

    /**
     * コンポーネントインスタンスの生成
     *
     * @param  string  $type
     * @param  string  $message
     * @return void
     */
    public function __construct($type, $message)
    {
        $this->type = $type;
        $this->message = $message;
    }

    /**
     * コンポーネントを表すビュー/コンテンツの取得
     *
     * @return \Illuminate\View\View|\Closure|string
     */
    public function render()
    {
        return view('components.alert');
    }
}

コンポーネントがレンダーされるときに、名前が一致するコンポーネントのパブリック変数がエコーされることにより、コンテンツは表示されます。

<div class="alert alert-{{ $type }}">
    {{ $message }}
</div>

キャスト

コンポーネントのコンストラクタ引数はキャメルケース(camelCase)を使用し、HTML属性の中で引数名を参照するときはケバブケース(kebab-case)を使用します。たとえば、以下のようなコンポーネントコンストラクタがあったとしましょう。

/**
 * コンポーネントインスタンスの生成
 *
 * @param  string  $alertType
 * @return void
 */
public function __construct($alertType)
{
    $this->alertType = $alertType;
}

$alertType引数は以下のように指定します。

<x-alert alert-type="danger" />

コンポーネントメソッド

コンポーネントテンプレートではパブリックな変数が使えるのに加え、コンポーネントの全パブリックメソッドも実行可能です。たとえば、コンポーネントにisSelectedメソッドがあると想像してください。

/**
 * 指定されたオプションが現在選ばれているか判定する
 *
 * @param  string  $option
 * @return bool
 */
public function isSelected($option)
{
    return $option === $this->selected;
}

メソッド名と一致する変数を呼び出せば、コンポーネントテンプレートからこのメソッドを実行できます。

<option {{ $isSelected($value) ? 'selected="selected"' : '' }} value="{{ $value }}">
    {{ $label }}
</option>

クラス内での属性/スロットの使用

Bladeコンポーネントはクラスのrenderメソッドの中からコンポーネント名、属性、スロットへアクセスできます。しかし、このデータにアクセスするにはコンポーネントのrenderメソッドからクロージャを返す必要があります。クロージャは唯一の引数として$data配列を受け取ります。

/**
 * コンポーネントを表すビュー/内容の取得
 *
 * @return \Illuminate\View\View|\Closure|string
 */
public function render()
{
    return function (array $data) {
        // $data['componentName'];
        // $data['attributes'];
        // $data['slot'];

        return '<div>Component content</div>';
    };
}

componentNameは、HTMLタグ中でx-プレフィックスに続けて使用している名前と同じです。そのため、<x-alert />componentNamealertとなります。attributes要素はHTMLタグ中に現れるすべての属性を含みます。slot要素はそのコンポーネントのスロットの内容のIlluminate\Support\HtmlStringインスタンスです。

依存の追加

コンポーネントがLaravelのサービスコンテナからの依存注入を必要としているなら、コンポーネントのデータ属性の前に依存をリストしておけば、コンテナにより自動的に注入されます。

use App\AlertCreator

/**
 * コンポーネントインスタンスの生成
 *
 * @param  \App\AlertCreator  $creator
 * @param  string  $type
 * @param  string  $message
 * @return void
 */
public function __construct(AlertCreator $creator, $type, $message)
{
    $this->creator = $creator;
    $this->type = $type;
    $this->message = $message;
}

属性の管理

コンポーネントへデータ属性を渡す方法はすでに説明しました。しかしながら、たとえばコンポーネントが機能するためには必須でないデータであるclassのような、追加のHTML属性を指定する必要も起き得ます。コンポーネントテンプレートのルート要素へ追加の属性を渡したい場合が、典型例でしょう。例として、alertコンポーネントを次のようにレンダーするのを想像してください。

<x-alert type="error" :message="$message" class="mt-4"/>

コンポーネントのコンストラクタで依存していしていない残りの属性すべては、そのコンポーネントの「属性バッグ」へ追加されます。この属性バッグは$attributes変数によりコンポーネントで使用可能になります。この変数をエコーすることにより、コンポーネント中ですべての属性がレンダーされます。

<div {{ $attributes }}>
    <!-- コンポーネントのコンテンツ -->
</div>

Note: コンポーネントでの変数({{ $attributes }})の表示や、@envディレクティブの使用は、今のところサポートしていません。

デフォルト/属性のマージ

属性にデフォルト値を指定、またはコンポーネントの属性へ追加の値をマージする必要も時に起きます。これには属性バッグのmergeメソッドを使用します。

<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
    {{ $message }}
</div>

このコンポーネントを次のように使用すると仮定してみましょう。

<x-alert type="error" :message="$message" class="mb-4"/>

最終的にこのコンポーネントは、以下のようなHTMLでレンダーされます。

<div class="alert alert-error mb-4">
    <!-- ここには$message変数の内容がレンダーされる -->
</div>

属性のフィルタリング

filterメソッドを使い、属性をフィルタリングできます。このメソッドはクロージャを引数に取り、属性バックの中へ残す属性に対しtrueを返してください。

{{ $attributes->filter(fn ($value, $key) => $key == 'foo') }}

より便利に使うため、指定文字列から始まるキー名の属性を全部取得する、whereStartsWithメソッドを使うことも可能です。

{{ $attributes->whereStartsWith('wire:model') }}

firstメソッドを使い、指定した属性バッグの中の最初の属性をレンダーすることもできます。

{{ $attributes->whereStartsWith('wire:model')->first() }}

スロット

コンポーネントに「スロット」を使用して、追加のコンテンツを渡す必要性がしばしばあると思います。次のようなaleatコンポーネントを作ったとイメージしてください。

<!-- /resources/views/components/alert.blade.php -->

<div class="alert alert-danger">
    {{ $slot }}
</div>

コンポーネントにコンテンツを挿入することにより、slotに内容を渡せます。

<x-alert>
    <strong>あーーー!</strong> なんか変だ!
</x-alert>

コンポーネント中の別々の場所に、複数の別々なスロットをレンダーする必要も起きるでしょう。ではalertコンポーネントへ"title"を挿入できるように変更してみましょう。

<!-- /resources/views/components/alert.blade.php -->

<span class="alert-title">{{ $title }}</span>

<div class="alert alert-danger">
    {{ $slot }}
</div>

x-slotタグを使い、名前付きスロットのコンテンツを定義します。x-slotの外のコンテンツは、すべて$slot変数によりコンポーネントへ渡されます。

<x-alert>
    <x-slot name="title">
        サーバエラー
    </x-slot>

    <strong>Whoops!</strong> Something went wrong!
</x-alert>

スコープ付きスロット

VueのようなJavaScriptフレームワークを使用している方は「スコープ付きスロット」に慣れていると思います。これは、スロットの中でコンポーネントのデータやメソッドへアクセスできる機構です。同様の振る舞いはLaravelでも、コンポーネントでpublicメソッドやプロパティを定義すれば可能です。component変数によりスロットの中でコンポーネントへアクセスします。

<x-alert>
    <x-slot name="title">
        {{ $component->formatAlert('Server Error') }}
    </x-slot>

    <strong>あーーー!</strong> なんか変だ!
</x-alert>

インラインコンポーネントビュー

小さなコンポーネントでは、コンポーネントクラスとコンポーネントのビューテンプレート両方を管理するのは面倒に感じるでしょう。そのため、コンポーネントのマークアップを直接renderメソッドから返せます。

/**
 * コンポーネントを表すビュー/コンテンツの取得
 *
 * @return \Illuminate\View\View|\Closure|string
 */
public function render()
{
    return <<<'blade'
        <div class="alert alert-danger">
            {{ $slot }}
        </div>
    blade;
}

インラインビューコンポーネントの生成

インラインビューをレンダーするコンポーネントを生成するには、make:componentコマンド実行時にinlineオプションを使用します。

php artisan make:component Alert --inline

無名コンポーネント

インラインコンポーネントと同様に、一つのファイルでコンポーネントを管理する仕組みを提供しているのが、無名コンポーネントです。違いは、無名コンポーネントは一つのビューファイルを使用し、関係するクラスはありません。無名コンポーネントを定義するには、resources/views/componentsディレクトリの中にBladeテンプレートを設置する必要があります。ここではresources/views/components/alert.blade.phpにコンポーネントを定義すると仮定しましょう。

<x-alert/>

componentsディレクトリ下にネストしたサブディレクトリ中へコンポーネントを設置する場合は、.を使ってください。たとえば、resources/views/components/inputs/button.blade.phpへ定義する場合、次のようになります。

<x-inputs.button/>

データプロパティ/属性

無名コンポーネントには関連するクラスがないため、どのデータが変数を通じてコンポーネントへ渡され、どの属性がコンポーネントの属性バッグに入れられるのかの違いに迷うと思います。

コンポーネントのBladeテンプレートの先頭で@propsディレクティブを使い、データ変数としてどの属性を取り扱うかを指定します。コンポーネント中の他の属性は、属性バッグを使い利用可能です。データ変数にデフォルト値を指定する場合は、変数の名前を配列キーとして指定し、デフォルト値を配列値として指定します。

<!-- /resources/views/components/alert.blade.php -->

@props(['type' => 'info', 'message'])

<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
    {{ $message }}
</div>

サブビューの読み込み

Bladeの@includeディレクディブを使えば、ビューの中から簡単に他のBladeビューを取り込めます。読み込み元のビューで使用可能な変数は、取り込み先のビューでも利用可能です。

<div>
    @include('shared.errors')

    <form>
        <!-- フォームの内容 -->
    </form>
</div>

親のビューの全データ変数が取り込み先のビューに継承されますが、追加のデータも配列で渡すことができます。

@include('view.name', ['some' => 'data'])

存在しないビューを@includeすれば、Laravelはエラーを投げます。存在しているかどうかわからないビューを取り込みたい場合は、@includeIfディレクティブを使います。

@includeIf('view.name', ['some' => 'data'])

指定した論理条件がtrueの場合に@includeしたい場合は、@includeWhenディレクティブを使用します。

@includeWhen($boolean, 'view.name', ['some' => 'data'])

指定した論理条件がfalseの場合に@includeしたい場合は、@includeUnlessディレクティブを使用します。

@includeUnless($boolean, 'view.name', ['some' => 'data'])

指定するビューの配列から、最初に存在するビューを読み込むには、includeFirstディレクティブを使用します。

@includeFirst(['custom.admin', 'admin'], ['some' => 'data'])

Note: Bladeビューの中では__DIR____FILE__を使わないでください。キャッシュされたコンパイル済みのビューのパスが返されるからです。

サブビューのエイリアス

Bladeのサブビューがサブディレクトリへ設置されている場合でも簡潔にアクセスできるよう、エイリアスを使用できます。たとえば、以下の内容のBladeサブビューが、resources/views/includes/input.blade.phpへ保存されていると想像してください。

<input type="{{ $type ?? 'text' }}">

includes.inputへのinputエイリアスを設定するには、includeメソッドを使用します。通常これは、AppServiceProviderbootメソッドの中で行うべきです。

use Illuminate\Support\Facades\Blade;

Blade::include('includes.input', 'input');

サブビューのエイリアスを設定したら、Bladeディレクティブとして、そのエイリアス名を使用することにより、レンダーされます。

@input(['type' => 'email'])

コレクションのレンダービュー

Bladeの@eachディレクティブを使い、ループとビューの読み込みを組み合わせられます。

@each('view.name', $jobs, 'job')

最初の引数は配列かコレクションの各要素をレンダーするための部分ビューです。第2引数は繰り返し処理する配列かコレクションで、第3引数はビューの中の繰り返し値が代入される変数名です。ですから、たとえばjobs配列を繰り返す場合なら、部分ビューの中で各ジョブにはjob変数としてアクセスしたいと通常は考えるでしょう。 現在の繰り返しのキーは、部分ビューの中のkey変数で参照できます。

@eachディレクティブには第4引数を渡たせます。この引数は配列が空の場合にレンダーされるビューを指定します。

@each('view.name', $jobs, 'job', 'view.empty')

Note: @eachを使ってレンダーされるビューは、親のビューから変数を継承しません。子ビューで親ビューの変数が必要な場合は、代わりに@foreach@includeを使用してください。

スタック

Bladeはさらに、他のビューやレイアウトでレンダーできるように、名前付きのスタックへ内容を退避できます。子ビューで必要なJavaScriptを指定する場合に、便利です。

@push('scripts')
    <script src="/example.js"></script>
@endpush

必要なだけ何回もスタックをプッシュできます。スタックした内容をレンダーするには、@stackディレクティブにスタック名を指定してください。

<head>
    <!-- Headの内容 -->

    @stack('scripts')
</head>

スタックの先頭に内容を追加したい場合は、@prependディレクティブを使用してください。

@push('scripts')
    ここは2番目
@endpush

// …後から

@prepend('scripts')
    ここは最初
@endprepend

サービス注入

@injectディレクティブはLaravelのサービスコンテナからサービスを取得するために使用します。@injectの最初の引数はそのサービスを取り込む変数名で、第2引数は依存解決したいクラス/インターフェイス名です。

@inject('metrics', 'App\Services\MetricsService')

<div>
    Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>

Blade拡張

Bladeではdirectiveメソッドを使い、自分のカスタムディレクティブを定義できます。Bladeコンパイラがそのカスタムディレクティブを見つけると、そのディレクティブに渡される引数をコールバックへの引数として呼び出します。

次の例は@datetime($var)ディレクティブを作成し、渡されるDateTimeインスタンスの$varをフォーマットします。

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 全アプリケーションサービスの登録
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * アプリケーションの全サービスの初期処理
     *
     * @return void
     */
    public function boot()
    {
        Blade::directive('datetime', function ($expression) {
            return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
        });
    }
}

ご覧の通り、ディレクティブがどんなものであれ、渡された引数にformatメソッドをチェーンし、呼び出しています。そのため、この例のディレクティブの場合、最終的に生成されるPHPコードは、次のようになります。

<?php echo ($var)->format('m/d/Y H:i'); ?>

Note: Bladeディレクティブのロジックを更新した後に、Bladeビューのキャッシュを全部削除する必要があります。view:clear Artisanコマンドで、キャッシュされているBladeビューを削除できます。

カスタムif文

シンプルなカスタム条件文を定義する時、必要以上にカスタムディレクティブのプログラミングが複雑になってしまうことが、ときどき起きます。そのため、Bladeはクロージャを使用し、カスタム条件ディレクティブを素早く定義できるように、Blade::ifメソッドを提供しています。例として、現在のアプリケーションのクラウドプロバイダをチェックするカスタム条件を定義してみましょう。AppServiceProviderbootメソッドで行います。

use Illuminate\Support\Facades\Blade;

/**
 * 全アプリケーションサービスの初期起動
 *
 * @return void
 */
public function boot()
{
    Blade::if('cloud', function ($provider) {
        return config('filesystems.default') === $provider;
    });
}

カスタム条件を定義したら、テンプレートの中で簡単に利用できます。

@cloud('digitalocean')
    // アプリケーションはdigitaloceanクラウドプロバイダを使用している
@elsecloud('aws')
    // アプリケーションはawsプロバイダを使用している
@else
    // アプリケーションはdigitaloceanとawsプロバイダを使用していない
@endcloud

@unlesscloud('aws')
    // アプリケーションはawsプロバイダを使用していない
@endcloud

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる