はじめに
Bladeは、Laravelに含まれるシンプルでありながら強力なテンプレートエンジンです。他のPHPテンプレートエンジンとは異なり、Bladeはテンプレート内でプレーンなPHPコードを使用することを制限しません。実際、すべてのBladeテンプレートはプレーンなPHPコードにコンパイルされ、変更されるまでキャッシュされるため、Bladeはアプリケーションに実質的にゼロのオーバーヘッドを追加します。Bladeテンプレートファイルは.blade.php
ファイル拡張子を使用し、通常はresources/views
ディレクトリに保存されます。
Bladeビューは、グローバルview
ヘルパーを使用してルートやコントローラーから返すことができます。もちろん、ビューに関するドキュメントで述べたように、データはview
ヘルパーの第二引数を使用してBladeビューに渡すことができます:
Route::get('/', function () {
return view('greeting', ['name' => 'Finn']);
});
LivewireでBladeを強化する
Bladeテンプレートを次のレベルに引き上げ、簡単に動的インターフェースを構築したいですか?Laravel Livewireをチェックしてください。Livewireを使用すると、通常はReactやVueのようなフロントエンドフレームワークを介してのみ可能な動的機能を強化したBladeコンポーネントを書くことができ、複雑さやクライアントサイドレンダリング、JavaScriptフレームワークのビルドステップなしで、現代的で反応的なフロントエンドを構築するための優れたアプローチを提供します。
データの表示
Bladeビューに渡されたデータは、変数を波括弧で囲むことで表示できます。たとえば、次のルートがあるとします:
Route::get('/', function () {
return view('welcome', ['name' => 'Samantha']);
});
``````blade
Hello, {{ $name }}.
`
Bladeの{{ }}
エコーステートメントは、自動的にPHPのhtmlspecialchars
関数を通じて送信され、XSS攻撃を防ぎます。
ビューに渡された変数の内容を表示することに制限されるわけではありません。任意のPHP関数の結果をエコーすることもできます。実際、Bladeエコーステートメント内に任意のPHPコードを記述できます:
The current UNIX timestamp is {{ time() }}.
HTMLエンティティのエンコーディング
デフォルトでは、Blade(およびLaravelのe
関数)はHTMLエンティティを二重にエンコードします。二重エンコードを無効にしたい場合は、Blade::withoutDoubleEncoding
メソッドをboot
メソッドから呼び出します:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Blade::withoutDoubleEncoding();
}
}
エスケープされていないデータの表示
デフォルトでは、Blade {{ }}
ステートメントは自動的にPHPのhtmlspecialchars
関数を通じて送信され、XSS攻撃を防ぎます。データをエスケープしたくない場合は、次の構文を使用できます:
Hello, {!! $name !!}.
アプリケーションのユーザーから提供されたコンテンツをエコーする際は、非常に注意してください。ユーザー提供データを表示する際は、通常、エスケープされた二重波括弧構文を使用してXSS攻撃を防ぐべきです。
ブレードテンプレート
- はじめに
- データの表示
- ブレードディレクティブ
- コンポーネント
- 匿名コンポーネント
- レイアウトの構築
- フォーム
- スタック
- サービスインジェクション
- インラインブレードテンプレートのレンダリング
- ブレードフラグメントのレンダリング
- ブレードの拡張
JSONのレンダリング
時には、JavaScript変数を初期化するためにJSONとしてレンダリングする意図で配列をビューに渡すことがあります。たとえば:
<script>
var app = <?php echo json_encode($array); ?>;
</script>
ただし、json_encode
を手動で呼び出す代わりに、Illuminate\Support\Js::from
メソッドディレクティブを使用できます。from
メソッドは、PHPのjson_encode
関数と同じ引数を受け入れますが、結果のJSONがHTMLの引用符内に適切にエスケープされることを保証します。from
メソッドは、指定されたオブジェクトまたは配列を有効なJavaScriptオブジェクトに変換する文字列JSON.parse
JavaScriptステートメントを返します:
<script>
var app = {{ Illuminate\Support\Js::from($array) }};
</script>
Laravelアプリケーションスケルトンの最新バージョンには、Bladeテンプレート内でこの機能に便利にアクセスできるJs
ファサードが含まれています:
<script>
var app = {{ Js::from($array) }};
</script>
既存の変数をJSONとしてレンダリングするためにJs::from
メソッドのみを使用するべきです。Bladeテンプレートは正規表現に基づいており、ディレクティブに複雑な式を渡そうとすると予期しない失敗を引き起こす可能性があります。
@verbatimディレクティブ
テンプレートの大部分でJavaScript変数を表示している場合、@verbatim
ディレクティブでHTMLをラップすることで、各Bladeエコーステートメントに@
シンボルをプレフィックスする必要がなくなります:
@verbatim
<div class="container">
Hello, {{ name }}.
</div>
@endverbatim
Bladeディレクティブ
テンプレートの継承やデータの表示に加えて、Bladeは条件文やループなどの一般的なPHP制御構造のための便利なショートカットも提供します。これらのショートカットは、PHPの対応物に慣れ親しみながら、PHP制御構造を扱う非常にクリーンで簡潔な方法を提供します。
If文
``````blade
@if (count($records) === 1)
I have one record!
@elseif (count($records) > 1)
I have multiple records!
@else
I don't have any records!
@endif
`
便利のために、Bladeは@unless
ディレクティブも提供します:
@unless (Auth::check())
You are not signed in.
@endunless
すでに説明した条件ディレクティブに加えて、@isset
および@empty
ディレクティブは、それぞれのPHP関数の便利なショートカットとして使用できます:
@isset($records)
// $records is defined and is not null...
@endisset
@empty($records)
// $records is "empty"...
@endempty
認証ディレクティブ
``````blade
@auth
// The user is authenticated...
@endauth
@guest
// The user is not authenticated...
@endguest
`
必要に応じて、@auth
および@guest
ディレクティブを使用する際にチェックすべき認証ガードを指定できます:
@auth('admin')
// The user is authenticated...
@endauth
@guest('admin')
// The user is not authenticated...
@endguest
環境ディレクティブ
アプリケーションが本番環境で実行されているかどうかを@production
ディレクティブを使用して確認できます:
@production
// Production specific content...
@endproduction
また、@env
ディレクティブを使用して、アプリケーションが特定の環境で実行されているかどうかを判断できます:
@env('staging')
// The application is running in "staging"...
@endenv
@env(['staging', 'production'])
// The application is running in "staging" or "production"...
@endenv
セクションディレクティブ
``````blade
@hasSection('navigation')
<div class="pull-right">
@yield('navigation')
</div>
<div class="clearfix"></div>
@endif
`
``````blade
@sectionMissing('navigation')
<div class="pull-right">
@include('default-navigation')
</div>
@endif
`
セッションディレクティブ
``````blade
@session('status')
<div class="p-4 bg-green-100">
{{ $value }}
</div>
@endsession
`
スイッチ文
スイッチ文は、@switch
、@case
、@break
、@default
および@endswitch
ディレクティブを使用して構築できます:
@switch($i)
@case(1)
First case...
@break
@case(2)
Second case...
@break
@default
Default case...
@endswitch
ループ
条件文に加えて、BladeはPHPのループ構造を扱うためのシンプルなディレクティブを提供します。これらのディレクティブは、PHPの対応物と同様に機能します:
@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
ループを使用する際は、`````@continue`````および`````@break`````ディレクティブを使用して現在の反復をスキップしたり、ループを終了したりできます:
``````blade
@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
ループ変数
``````blade
@foreach ($users as $user)
@if ($loop->first)
This is the first iteration.
@endif
@if ($loop->last)
This is the last iteration.
@endif
<p>This is user {{ $user->id }}</p>
@endforeach
`
ネストされたループにいる場合、$loop
変数にparent
プロパティを介してアクセスできます:
@foreach ($users as $user)
@foreach ($user->posts as $post)
@if ($loop->parent->first)
This is the first iteration of the parent loop.
@endif
@endforeach
@endforeach
| プロパティ | 説明 |
| --- | --- |
| `````$loop->index````` | 現在のループ反復のインデックス(0から始まる)。 |
| `````$loop->iteration````` | 現在のループ反復(1から始まる)。 |
| `````$loop->remaining````` | ループ内の残りの反復。 |
| `````$loop->count````` | 反復されている配列内のアイテムの総数。 |
| `````$loop->first````` | これがループの最初の反復であるかどうか。 |
| `````$loop->last````` | これがループの最後の反復であるかどうか。 |
| `````$loop->even````` | これがループの偶数反復であるかどうか。 |
| `````$loop->odd````` | これがループの奇数反復であるかどうか。 |
| `````$loop->depth````` | 現在のループのネストレベル。 |
| `````$loop->parent````` | ネストされたループ内にいる場合、親のループ変数。 |
<a name="conditional-classes"></a>
### 条件付きクラスとスタイル
`````@class`````ディレクティブは、CSSクラス文字列を条件付きでコンパイルします。このディレクティブは、追加したいクラスまたはクラスを含む配列のキーを持つ配列を受け入れ、値はブール式です。配列要素に数値キーがある場合、常にレンダリングされたクラスリストに含まれます:
``````blade
@php
$isActive = false;
$hasError = true;
@endphp
<span @class([
'p-4',
'font-bold' => $isActive,
'text-gray-500' => ! $isActive,
'bg-red' => $hasError,
])></span>
<span class="p-4 text-gray-500 bg-red"></span>
`
同様に、@style
ディレクティブを使用して、HTML要素にインラインCSSスタイルを条件付きで追加できます:
@php
$isActive = true;
@endphp
<span @style([
'background-color: red',
'font-weight: bold' => $isActive,
])></span>
<span style="background-color: red; font-weight: bold;"></span>
追加属性
便利のために、@checked
ディレクティブを使用して、特定のHTMLチェックボックス入力が「チェックされている」かどうかを簡単に示すことができます。このディレクティブは、提供された条件がtrue
に評価される場合、checked
をエコーします:
<input type="checkbox"
name="active"
value="active"
@checked(old('active', $user->active)) />
同様に、@selected
ディレクティブを使用して、特定の選択肢が「選択されている」べきかどうかを示すことができます:
<select name="version">
@foreach ($product->versions as $version)
<option value="{{ $version }}" @selected(old('version') == $version)>
{{ $version }}
</option>
@endforeach
</select>
さらに、@disabled
ディレクティブを使用して、特定の要素が「無効」であるべきかどうかを示すことができます:
<button type="submit" @disabled($errors->isNotEmpty())>Submit</button>
さらに、@readonly
ディレクティブを使用して、特定の要素が「読み取り専用」であるべきかどうかを示すことができます:
<input type="email"
name="email"
value=""
@readonly($user->isNotAdmin()) />
さらに、@required
ディレクティブを使用して、特定の要素が「必須」であるべきかどうかを示すことができます:
<input type="text"
name="title"
value="title"
@required($user->isAdmin()) />
サブビューの含め方
@include
ディレクティブを使用する自由がありますが、Blade コンポーネントは同様の機能を提供し、データや属性のバインディングなど、@include
ディレクティブに対していくつかの利点を提供します。
Bladeの@include
ディレクティブを使用すると、別のビューからBladeビューを含めることができます。親ビューで利用可能なすべての変数は、含まれるビューでも利用可能になります:
<div>
@include('shared.errors')
<form>
<!-- Form Contents -->
</form>
</div>
含まれるビューは親ビューで利用可能なすべてのデータを継承しますが、含まれるビューに利用可能にすべき追加データの配列を渡すこともできます:
@include('view.name', ['status' => 'complete'])
存在しないビューを@include
しようとすると、Laravelはエラーをスローします。存在するかもしれないビューを含めたい場合は、@includeIf
ディレクティブを使用するべきです:
@includeIf('view.name', ['status' => 'complete'])
特定のブール式がtrue
またはfalse
に評価される場合にビューを@include
したい場合は、@includeWhen
および@includeUnless
ディレクティブを使用できます:
@includeWhen($boolean, 'view.name', ['status' => 'complete'])
@includeUnless($boolean, 'view.name', ['status' => 'complete'])
指定されたビューの配列から最初に存在するビューを含めるには、includeFirst
ディレクティブを使用できます:
@includeFirst(['custom.admin', 'admin'], ['status' => 'complete'])
Bladeビュー内でDIR
およびFILE
定数を使用することは避けるべきです。これらはキャッシュされたコンパイル済みビューの場所を参照します。
コレクションのためのビューのレンダリング
Bladeの@each
ディレクティブを使用して、ループとインクルードを1行にまとめることができます:
@each('view.name', $jobs, 'job')
`````@each`````ディレクティブに第四引数を渡すこともできます。この引数は、指定された配列が空の場合にレンダリングされるビューを決定します。
``````blade
@each('view.name', $jobs, 'job', 'view.empty')
`
<a name="the-once-directive"></a>
### 一度だけのディレクティブ
`````@once`````ディレクティブを使用すると、レンダリングサイクルごとに一度だけ評価されるテンプレートの一部を定義できます。これは、[スタック](#stacks)を使用してページのヘッダーに特定のJavaScriptをプッシュするのに便利です。たとえば、ループ内で特定の[コンポーネント](#components)をレンダリングしている場合、コンポーネントが最初にレンダリングされるときだけJavaScriptをヘッダーにプッシュしたい場合があります:
``````blade
@once
@push('scripts')
<script>
// Your custom JavaScript...
</script>
@endpush
@endonce
`
``````blade
@pushOnce('scripts')
<script>
// Your custom JavaScript...
</script>
@endPushOnce
`
生のPHP
特定の状況では、PHPコードをビューに埋め込むことが便利です。Blade @php
ディレクティブを使用して、テンプレート内でプレーンなPHPブロックを実行できます:
@php
$counter = 1;
@endphp
また、クラスをインポートするためにPHPを使用するだけの場合は、@use
ディレクティブを使用できます:
@use('App\Models\Flight')
``````php
@use('App\Models\Flight', 'FlightModel')
`
コメント
Bladeは、ビュー内でコメントを定義することも許可します。ただし、HTMLコメントとは異なり、Bladeコメントはアプリケーションによって返されるHTMLには含まれません:
{{-- This comment will not be present in the rendered HTML --}}
コンポーネント
コンポーネントとスロットは、セクション、レイアウト、およびインクルードと同様の利点を提供しますが、コンポーネントとスロットのメンタルモデルが理解しやすいと感じる人もいます。コンポーネントを書くには、クラスベースのコンポーネントと匿名コンポーネントの2つのアプローチがあります。
クラスベースのコンポーネントを作成するには、make:component
Artisanコマンドを使用します。コンポーネントの使用方法を示すために、シンプルなAlert
コンポーネントを作成します。make:component
コマンドは、コンポーネントをapp/View/Components
ディレクトリに配置します:
php artisan make:component Alert
サブディレクトリ内にコンポーネントを作成することもできます:
``````shell
php artisan make:component Forms/Input
`
上記のコマンドは、Input
コンポーネントをapp/View/Components/Forms
ディレクトリに作成し、ビューはresources/views/components/forms
ディレクトリに配置されます。
匿名コンポーネント(クラスなしのBladeテンプレートのみのコンポーネント)を作成したい場合は、--view
フラグをmake:component
コマンドを呼び出すときに使用できます:
php artisan make:component forms.input --view
上記のコマンドは、resources/views/components/forms/input.blade.php
にBladeファイルを作成し、<x-forms.input />
を介してコンポーネントとしてレンダリングできます。
パッケージコンポーネントの手動登録
アプリケーション用にコンポーネントを書くとき、コンポーネントはapp/View/Components
ディレクトリおよびresources/views/components
ディレクトリ内で自動的に発見されます。
ただし、Bladeコンポーネントを利用するパッケージを構築している場合は、コンポーネントクラスとそのHTMLタグエイリアスを手動で登録する必要があります。通常、パッケージのサービスプロバイダーのboot
メソッドでコンポーネントを登録します:
use Illuminate\Support\Facades\Blade;
/**
* Bootstrap your package's services.
*/
public function boot(): void
{
Blade::component('package-alert', Alert::class);
}
コンポーネントが登録されると、そのタグエイリアスを使用してレンダリングできます:
<x-package-alert/>
また、componentNamespace
メソッドを使用して、慣例に従ってコンポーネントクラスを自動的にロードすることもできます。たとえば、Nightshade
パッケージには、Calendar
およびColorPicker
コンポーネントがPackage\Views\Components
名前空間内に存在する場合があります:
use Illuminate\Support\Facades\Blade;
/**
* Bootstrap your package's services.
*/
public function boot(): void
{
Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');
}
これにより、package-name::
構文を使用してベンダー名前空間によるパッケージコンポーネントの使用が可能になります:
<x-nightshade::calendar />
<x-nightshade::color-picker />
Bladeは、コンポーネント名をパスカルケースに変換することによって、このコンポーネントにリンクされたクラスを自動的に検出します。サブディレクトリも「ドット」表記を使用してサポートされています。
コンポーネントのレンダリング
コンポーネントを表示するには、Bladeテンプレートの1つ内でBladeコンポーネントタグを使用できます。Bladeコンポーネントタグは、x-
という文字列で始まり、コンポーネントクラスのケバブケース名が続きます:
<x-alert/>
<x-user-profile/>
コンポーネントクラスがapp/View/Components
ディレクトリ内でさらに深くネストされている場合、.
文字を使用してディレクトリのネストを示すことができます。たとえば、コンポーネントがapp/View/Components/Inputs/Button.php
にあると仮定すると、次のようにレンダリングできます:
<x-inputs.button/>
コンポーネントを条件付きでレンダリングしたい場合は、コンポーネントクラスにshouldRender
メソッドを定義できます。shouldRender
メソッドがfalse
を返す場合、コンポーネントはレンダリングされません:
use Illuminate\Support\Str;
/**
* Whether the component should be rendered
*/
public function shouldRender(): bool
{
return Str::length($this->message) > 0;
}
コンポーネントへのデータの渡し方
HTML属性を使用してBladeコンポーネントにデータを渡すことができます。ハードコーディングされたプリミティブ値は、シンプルなHTML属性文字列を使用してコンポーネントに渡すことができます。PHP式や変数は、:
文字をプレフィックスとして使用する属性を介してコンポーネントに渡すべきです:
<x-alert type="error" :message="$message"/>
コンポーネントのすべてのデータ属性は、そのクラスコンストラクタで定義する必要があります。コンポーネントのすべてのパブリックプロパティは、自動的にコンポーネントのビューで利用可能になります。コンポーネントのrender
メソッドからビューにデータを渡す必要はありません:
<?php
namespace App\View\Components;
use Illuminate\View\Component;
use Illuminate\View\View;
class Alert extends Component
{
/**
* Create the component instance.
*/
public function __construct(
public string $type,
public string $message,
) {}
/**
* Get the view / contents that represent the component.
*/
public function render(): View
{
return view('components.alert');
}
}
コンポーネントがレンダリングされると、変数名をエコーすることでコンポーネントのパブリック変数の内容を表示できます:
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>
ケース
コンポーネントコンストラクタ引数はcamelCase
を使用して指定する必要があり、kebab-case
はHTML属性で引数名を参照する際に使用する必要があります。たとえば、次のコンポーネントコンストラクタを考えてみましょう:
/**
* Create the component instance.
*/
public function __construct(
public string $alertType,
) {}
``````blade
<x-alert alert-type="danger" />
`
ショート属性構文
コンポーネントに属性を渡す際、ショート属性構文を使用することもできます。これは、属性名が対応する変数名と一致することが多いため、便利です:
{{-- Short attribute syntax... --}}
<x-profile :$userId :$name />
{{-- Is equivalent to... --}}
<x-profile :user-id="$userId" :name="$name" />
属性レンダリングのエスケープ
Alpine.jsなどの一部のJavaScriptフレームワークもコロンプレフィックス属性を使用しているため、::
(ダブルコロン)プレフィックスを使用してBladeに属性がPHP式ではないことを通知できます。たとえば、次のコンポーネントを考えてみましょう:
<x-button ::class="{ danger: isDeleting }">
Submit
</x-button>
次のHTMLはBladeによってレンダリングされます:
<button :class="{ danger: isDeleting }">
Submit
</button>
コンポーネントメソッド
コンポーネントテンプレートで利用可能なパブリック変数に加えて、コンポーネント上の任意のパブリックメソッドを呼び出すことができます。たとえば、isSelected
メソッドを持つコンポーネントを想像してみましょう:
/**
* Determine if the given option is the currently selected option.
*/
public function isSelected(string $option): bool
{
return $option === $this->selected;
}
このメソッドは、メソッド名に一致する変数を呼び出すことでコンポーネントテンプレートから実行できます:
<option {{ $isSelected($value) ? 'selected' : '' }} value="{{ $value }}">
{{ $label }}
</option>
コンポーネントクラス内の属性とスロットへのアクセス
Bladeコンポーネントは、クラスのレンダーメソッド内でコンポーネント名、属性、およびスロットにアクセスすることも許可します。ただし、このデータにアクセスするには、コンポーネントのrender
メソッドからクロージャを返す必要があります:
use Closure;
/**
* Get the view / contents that represent the component.
*/
public function render(): Closure
{
return function () {
return '<div {{ $attributes }}>Components content</div>';
};
}
コンポーネントのrender
メソッドから返されるクロージャは、唯一の引数として$data
配列を受け取ることもできます。この配列には、コンポーネントに関する情報を提供するいくつかの要素が含まれます:
return function (array $data) {
// $data['componentName'];
// $data['attributes'];
// $data['slot'];
return '<div {{ $attributes }}>Components content</div>';
}
`````componentName`````は、`````x-`````プレフィックスの後にHTMLタグで使用される名前と等しいです。したがって、`````<x-alert />`````の`````componentName`````は`````alert`````になります。`````attributes`````要素には、HTMLタグに存在したすべての属性が含まれます。`````slot`````要素は、コンポーネントのスロットの内容を持つ`````Illuminate\Support\HtmlString`````インスタンスです。
クロージャは文字列を返す必要があります。返された文字列が既存のビューに対応する場合、そのビューがレンダリングされます。そうでない場合、返された文字列はインラインBladeビューとして評価されます。
<a name="additional-dependencies"></a>
#### 追加依存関係
コンポーネントがLaravelの[サービスコンテナ](/read/laravel-11-x/89c648800d1f2464.md)から依存関係を必要とする場合、コンポーネントのデータ属性の前にリストすることで、自動的にコンテナによって注入されます:
``````php
use App\Services\AlertCreator;
/**
* Create the component instance.
*/
public function __construct(
public AlertCreator $creator,
public string $type,
public string $message,
) {}
`
属性/メソッドの非表示
コンポーネントテンプレートに変数として公開メソッドやプロパティが露出するのを防ぎたい場合は、コンポーネントの$except
配列プロパティに追加できます:
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Alert extends Component
{
/**
* The properties / methods that should not be exposed to the component template.
*
* @var array
*/
protected $except = ['type'];
/**
* Create the component instance.
*/
public function __construct(
public string $type,
) {}
}
コンポーネント属性
データ属性をコンポーネントに渡す方法をすでに検討しましたが、コンポーネントが機能するために必要なデータの一部ではない追加のHTML属性(class
など)を指定する必要がある場合もあります。通常、これらの追加属性はコンポーネントテンプレートのルート要素に渡すことを望みます。たとえば、alert
コンポーネントを次のようにレンダリングしたいとします:
<x-alert type="error" :message="$message" class="mt-4"/>
コンポーネントのコンストラクタの一部でないすべての属性は、自動的にコンポーネントの「属性バッグ」に追加されます。この属性バッグは、$attributes
変数を介してコンポーネントに自動的に提供されます。すべての属性は、この変数をエコーすることでコンポーネント内でレンダリングできます:
<div {{ $attributes }}>
<!-- Component content -->
</div>
コンポーネントタグ内で@env
のようなディレクティブを使用することは、現時点ではサポートされていません。たとえば、<x-alert :live="@env('production')"/>
はコンパイルされません。
デフォルト/マージされた属性
時には、属性のデフォルト値を指定したり、コンポーネントの属性に追加の値をマージしたりする必要があります。これを実現するために、属性バッグのmerge
メソッドを使用できます。このメソッドは、コンポーネントに常に適用されるデフォルトのCSSクラスのセットを定義するのに特に便利です:
<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">
<!-- Contents of the $message variable -->
</div>
条件付きでクラスをマージする
特定の条件がtrue
の場合、クラスをマージしたいことがあります。これは、class
メソッドを介して実現できます。このメソッドは、追加したいクラスまたはクラスを含む配列を受け入れ、値はブール式です。配列要素に数値キーがある場合、常にレンダリングされたクラスリストに含まれます:
<div {{ $attributes->class(['p-4', 'bg-red' => $hasError]) }}>
{{ $message }}
</div>
コンポーネントに他の属性をマージする必要がある場合、merge
メソッドをclass
メソッドにチェーンできます:
<button {{ $attributes->class(['p-4'])->merge(['type' => 'button']) }}>
{{ $slot }}
</button>
他のHTML要素に条件付きでクラスをコンパイルする必要がある場合、マージされた属性を受け取らない要素には、@class
ディレクティブを使用できます。
非クラス属性のマージ
``````blade
<button {{ $attributes->merge(['type' => 'button']) }}>
{{ $slot }}
</button>
`
カスタムtype
でボタンコンポーネントをレンダリングするには、コンポーネントを消費するときに指定できます。タイプが指定されていない場合、button
タイプが使用されます:
<x-button type="submit">
Submit
</x-button>
この例のbutton
コンポーネントのレンダリングHTMLは次のようになります:
<button type="submit">
Submit
</button>
``````blade
<div {{ $attributes->merge(['data-controller' => $attributes->prepends('profile-controller')]) }}>
{{ $slot }}
</div>
`
属性の取得とフィルタリング
属性をフィルタリングするには、filter
メソッドを使用できます。このメソッドはクロージャを受け入れ、属性を属性バッグに保持したい場合はtrue
を返す必要があります:
{{ $attributes->filter(fn (string $value, string $key) => $key == 'foo') }}
便利なことに、whereStartsWith
メソッドを使用して、指定された文字列で始まるすべての属性を取得できます:
{{ $attributes->whereStartsWith('wire:model') }}
逆に、whereDoesntStartWith
メソッドを使用して、指定された文字列で始まるすべての属性を除外できます:
{{ $attributes->whereDoesntStartWith('wire:model') }}
``````blade
{{ $attributes->whereStartsWith('wire:model')->first() }}
`
コンポーネントに属性が存在するかどうかを確認したい場合は、has
メソッドを使用できます。このメソッドは属性名を唯一の引数として受け取り、属性が存在するかどうかを示すブール値を返します:
@if ($attributes->has('class'))
<div>Class attribute is present</div>
@endif
``````blade
@if ($attributes->has(['name', 'class']))
<div>All of the attributes are present</div>
@endif
`
``````blade
@if ($attributes->hasAny(['href', ':href', 'v-bind:href']))
<div>One of the attributes is present</div>
@endif
`
特定の属性の値をget
メソッドを使用して取得できます:
{{ $attributes->get('class') }}
予約語
デフォルトでは、いくつかのキーワードはコンポーネントをレンダリングするためにブレードの内部で使用されるため、予約されています。以下のキーワードは、コンポーネント内で公開プロパティまたはメソッド名として定義できません:
スロット
コンポーネントに追加のコンテンツを渡す必要がある場合がよくあります。スロットは$slot
変数をエコーすることでレンダリングされます。この概念を探るために、alert
コンポーネントが次のマークアップを持っていると仮定しましょう:
<!-- /resources/views/components/alert.blade.php -->
<div class="alert alert-danger">
{{ $slot }}
</div>
``````blade
<x-alert>
<strong>Whoops!</strong> Something went wrong!
</x-alert>
`
時には、コンポーネントが異なる場所で複数の異なるスロットをレンダリングする必要がある場合があります。アラートコンポーネントを修正して「タイトル」スロットの注入を許可しましょう:
<!-- /resources/views/components/alert.blade.php -->
<span class="alert-title">{{ $title }}</span>
<div class="alert alert-danger">
{{ $slot }}
</div>
``````xml
<x-alert>
<x-slot:title>
Server Error
</x-slot>
<strong>Whoops!</strong> Something went wrong!
</x-alert>
`
スロットのisEmpty
メソッドを呼び出して、スロットにコンテンツが含まれているかどうかを確認できます:
<span class="alert-title">{{ $title }}</span>
<div class="alert alert-danger">
@if ($slot->isEmpty())
This is default content if the slot is empty.
@else
{{ $slot }}
@endif
</div>
さらに、hasActualContent
メソッドを使用して、スロットにHTMLコメントではない「実際の」コンテンツが含まれているかどうかを判断できます:
@if ($slot->hasActualContent())
The scope has non-comment content.
@endif
スコープ付きスロット
VueなどのJavaScriptフレームワークを使用したことがある場合、「スコープ付きスロット」に慣れているかもしれません。これは、スロット内でコンポーネントのデータやメソッドにアクセスできるようにします。Laravelでは、コンポーネントに公開メソッドやプロパティを定義し、$component
変数を介してスロット内でコンポーネントにアクセスすることで、同様の動作を実現できます。この例では、x-alert
コンポーネントがそのコンポーネントクラスにformatAlert
メソッドを定義していると仮定します:
<x-alert>
<x-slot:title>
{{ $component->formatAlert('Server Error') }}
</x-slot>
<strong>Whoops!</strong> Something went wrong!
</x-alert>
スロット属性
ブレードコンポーネントと同様に、CSSクラス名などの追加の属性をスロットに割り当てることができます:
<x-card class="shadow-sm">
<x-slot:heading class="font-bold">
Heading
</x-slot>
Content
<x-slot:footer class="text-sm">
Footer
</x-slot>
</x-card>
スロット属性と対話するには、スロットの変数のattributes
プロパティにアクセスできます。属性との対話方法についての詳細は、コンポーネント属性に関するドキュメントを参照してください:
@props([
'heading',
'footer',
])
<div {{ $attributes->class(['border']) }}>
<h1 {{ $heading->attributes->class(['text-lg']) }}>
{{ $heading }}
</h1>
{{ $slot }}
<footer {{ $footer->attributes->class(['text-gray-700']) }}>
{{ $footer }}
</footer>
</div>
インラインコンポーネントビュー
非常に小さなコンポーネントの場合、コンポーネントクラスとコンポーネントのビューテンプレートの両方を管理するのは面倒に感じるかもしれません。このため、render
メソッドからコンポーネントのマークアップを直接返すことができます:
/**
* Get the view / contents that represent the component.
*/
public function render(): string
{
return <<<'blade'
<div class="alert alert-danger">
{{ $slot }}
</div>
blade;
}
インラインビューコンポーネントの生成
インラインビューをレンダリングするコンポーネントを作成するには、inline
オプションを使用してmake:component
コマンドを実行します:
php artisan make:component Alert --inline
動的コンポーネント
時には、コンポーネントをレンダリングする必要がありますが、どのコンポーネントをレンダリングするかは実行時までわからない場合があります。この場合、Laravelの組み込みdynamic-component
コンポーネントを使用して、実行時の値や変数に基づいてコンポーネントをレンダリングできます:
// $componentName = "secondary-button";
<x-dynamic-component :component="$componentName" class="mt-4" />
コンポーネントの手動登録
コンポーネントの手動登録に関する以下のドキュメントは、ビューコンポーネントを含むLaravelパッケージを作成している人に主に適用されます。パッケージを作成していない場合、このコンポーネントドキュメントの部分はあなたに関連しないかもしれません。
アプリケーション用にコンポーネントを書くとき、コンポーネントはapp/View/Components
ディレクトリおよびresources/views/components
ディレクトリ内で自動的に発見されます。
ただし、ブレードコンポーネントを利用するパッケージを構築している場合や、非従来のディレクトリにコンポーネントを配置している場合は、Laravelがコンポーネントを見つける場所を知るために、コンポーネントクラスとそのHTMLタグエイリアスを手動で登録する必要があります。通常、パッケージのサービスプロバイダーのboot
メソッドでコンポーネントを登録します:
use Illuminate\Support\Facades\Blade;
use VendorPackage\View\Components\AlertComponent;
/**
* Bootstrap your package's services.
*/
public function boot(): void
{
Blade::component('package-alert', AlertComponent::class);
}
コンポーネントが登録されると、そのタグエイリアスを使用してレンダリングできます:
<x-package-alert/>
パッケージコンポーネントの自動ロード
また、componentNamespace
メソッドを使用して、慣例に従ってコンポーネントクラスを自動的にロードすることもできます。たとえば、Nightshade
パッケージには、Calendar
およびColorPicker
コンポーネントがPackage\Views\Components
名前空間内に存在する場合があります:
use Illuminate\Support\Facades\Blade;
/**
* Bootstrap your package's services.
*/
public function boot(): void
{
Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');
}
これにより、package-name::
構文を使用してベンダー名前空間によるパッケージコンポーネントの使用が可能になります:
<x-nightshade::calendar />
<x-nightshade::color-picker />
Bladeは、コンポーネント名をパスカルケースにすることで、このコンポーネントにリンクされたクラスを自動的に検出します。サブディレクトリも「ドット」表記を使用してサポートされています。
匿名コンポーネント
インラインコンポーネントと同様に、匿名コンポーネントは単一のファイルを介してコンポーネントを管理するメカニズムを提供します。ただし、匿名コンポーネントは単一のビューファイルを利用し、関連するクラスはありません。匿名コンポーネントを定義するには、resources/views/components
ディレクトリ内にブレードテンプレートを配置するだけです。たとえば、resources/views/components/alert.blade.php
でコンポーネントを定義したと仮定すると、次のようにレンダリングできます:
<x-alert/>
``````blade
<x-inputs.button/>
`
匿名インデックスコンポーネント
時には、コンポーネントが多くのブレードテンプレートで構成されている場合、特定のコンポーネントのテンプレートを単一のディレクトリ内にグループ化したい場合があります。たとえば、次のディレクトリ構造を持つ「アコーディオン」コンポーネントを想像してみてください:
/resources/views/components/accordion.blade.php
/resources/views/components/accordion/item.blade.php
このディレクトリ構造により、アコーディオンコンポーネントとそのアイテムを次のようにレンダリングできます:
<x-accordion>
<x-accordion.item>
...
</x-accordion.item>
</x-accordion>
ただし、x-accordion
を介してアコーディオンコンポーネントをレンダリングするために、「インデックス」アコーディオンコンポーネントテンプレートをresources/views/components
ディレクトリに配置する必要がありました。accordion
ディレクトリ内の他のアコーディオン関連テンプレートとネストするのではなく。
幸いなことに、ブレードでは、コンポーネントのテンプレートディレクトリ内にindex.blade.php
ファイルを配置できます。コンポーネントにindex.blade.php
テンプレートが存在する場合、それはコンポーネントの「ルート」ノードとしてレンダリングされます。したがって、上記の例で示したのと同じブレード構文を引き続き使用できますが、ディレクトリ構造を次のように調整します:
/resources/views/components/accordion/index.blade.php
/resources/views/components/accordion/item.blade.php
データプロパティ/属性
匿名コンポーネントには関連するクラスがないため、どのデータを変数としてコンポーネントに渡すべきか、どの属性をコンポーネントの属性バッグに配置すべきかを区別する方法があるかもしれません。
``````blade
<!-- /resources/views/components/alert.blade.php -->
@props(['type' => 'info', 'message'])
<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
{{ $message }}
</div>
`
上記のコンポーネント定義に基づいて、次のようにコンポーネントをレンダリングできます:
<x-alert type="error" :message="$message" class="mb-4"/>
親データへのアクセス
時には、子コンポーネント内で親コンポーネントからデータにアクセスしたい場合があります。この場合、@aware
ディレクティブを使用できます。たとえば、親<x-menu>
と子<x-menu.item>
で構成される複雑なメニューコンポーネントを構築していると仮定します:
<x-menu color="purple">
<x-menu.item>...</x-menu.item>
<x-menu.item>...</x-menu.item>
</x-menu>
``````blade
<!-- /resources/views/components/menu/index.blade.php -->
@props(['color' => 'gray'])
<ul {{ $attributes->merge(['class' => 'bg-'.$color.'-200']) }}>
{{ $slot }}
</ul>
`
``````blade
<!-- /resources/views/components/menu/item.blade.php -->
@aware(['color' => 'gray'])
<li {{ $attributes->merge(['class' => 'text-'.$color.'-800']) }}>
{{ $slot }}
</li>
`
<a name="anonymous-component-paths"></a>
### 匿名コンポーネントパス
前述のように、匿名コンポーネントは通常、`````resources/views/components`````ディレクトリ内にブレードテンプレートを配置することで定義されます。ただし、デフォルトのパスに加えて、他の匿名コンポーネントパスをLaravelに登録したい場合があります。
`````anonymousComponentPath`````メソッドは、匿名コンポーネントの場所への「パス」を最初の引数として受け取り、コンポーネントが配置されるべきオプションの「名前空間」を2番目の引数として受け取ります。通常、このメソッドは、アプリケーションの[サービスプロバイダー](/read/laravel-11-x/934b4900a19307fc.md)の`````boot`````メソッドから呼び出されるべきです:
``````php
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Blade::anonymousComponentPath(__DIR__.'/../components');
}
`
コンポーネントパスが、上記の例のように指定されたプレフィックスなしで登録されると、対応するプレフィックスなしでブレードコンポーネント内でレンダリングできます。たとえば、上記のパスにpanel.blade.php
コンポーネントが存在する場合、次のようにレンダリングできます:
<x-panel />
「名前空間」にプレフィックスを提供することがanonymousComponentPath
メソッドの2番目の引数としてできます:
Blade::anonymousComponentPath(__DIR__.'/../components', 'dashboard');
プレフィックスが提供されると、その「名前空間」内のコンポーネントは、コンポーネントがレンダリングされるときにコンポーネント名にコンポーネントの名前空間をプレフィックスとして付けることでレンダリングできます:
<x-dashboard::panel />
レイアウトの構築
コンポーネントを使用したレイアウト
ほとんどのWebアプリケーションは、さまざまなページで同じ一般的なレイアウトを維持します。作成するすべてのビューでレイアウトHTML全体を繰り返す必要がある場合、アプリケーションを維持するのは非常に面倒で困難です。幸いなことに、このレイアウトを単一のブレードコンポーネントとして定義し、アプリケーション全体で使用するのは便利です。
レイアウトコンポーネントの定義
たとえば、「todo」リストアプリケーションを構築していると仮定します。次のようなlayout
コンポーネントを定義するかもしれません:
<!-- resources/views/components/layout.blade.php -->
<html>
<head>
<title>{{ $title ?? 'Todo Manager' }}</title>
</head>
<body>
<h1>Todos</h1>
<hr/>
{{ $slot }}
</body>
</html>
レイアウトコンポーネントの適用
一度layout
コンポーネントが定義されると、コンポーネントを利用するブレードビューを作成できます。この例では、タスクリストを表示するシンプルなビューを定義します:
<!-- resources/views/tasks.blade.php -->
<x-layout>
@foreach ($tasks as $task)
<div>{{ $task }}</div>
@endforeach
</x-layout>
コンポーネントに注入されたコンテンツは、layout
コンポーネント内のデフォルト$slot
変数に供給されることを忘れないでください。注目すべき点は、layout
も提供されている場合、$title
スロットを尊重することです。そうでない場合、デフォルトのタイトルが表示されます。タスクリストビューから標準のスロット構文を使用してカスタムタイトルを注入できます。コンポーネントドキュメントで説明したように:
<!-- resources/views/tasks.blade.php -->
<x-layout>
<x-slot:title>
Custom Title
</x-slot>
@foreach ($tasks as $task)
<div>{{ $task }}</div>
@endforeach
</x-layout>
レイアウトとタスクリストビューを定義したので、ルートからtask
ビューを返すだけです:
use App\Models\Task;
Route::get('/tasks', function () {
return view('tasks', ['tasks' => Task::all()]);
});
テンプレート継承を使用したレイアウト
レイアウトの定義
レイアウトは「テンプレート継承」を介しても作成できます。これは、コンポーネントの導入前にアプリケーションを構築する主な方法でした。
始めるために、シンプルな例を見てみましょう。まず、ページレイアウトを調べます。ほとんどのWebアプリケーションは、さまざまなページで同じ一般的なレイアウトを維持するため、このレイアウトを単一のブレードビューとして定義するのが便利です:
<!-- resources/views/layouts/app.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>
このファイルには、典型的なHTMLマークアップが含まれています。ただし、@section
および@yield
ディレクティブに注意してください。@section
ディレクティブは、その名前が示すように、コンテンツのセクションを定義し、@yield
ディレクティブは、指定されたセクションの内容を表示するために使用されます。
アプリケーションのレイアウトを定義したので、レイアウトを継承する子ページを定義しましょう。
レイアウトの拡張
子ビューを定義する際は、@extends
ブレードディレクティブを使用して、子ビューが「継承」すべきレイアウトを指定します。ブレードレイアウトを拡張するビューは、@section
ディレクティブを使用してレイアウトのセクションにコンテンツを注入できます。上記の例で見たように、これらのセクションの内容は@yield
を使用してレイアウトに表示されます:
<!-- resources/views/child.blade.php -->
@extends('layouts.app')
@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
この例では、sidebar
セクションは、レイアウトのサイドバーにコンテンツを追加するために@parent
ディレクティブを利用しています(上書きするのではなく)。@parent
ディレクティブは、ビューがレンダリングされるときにレイアウトの内容に置き換えられます。
前の例とは対照的に、このsidebar
セクションは@endsection
で終わり、@show
ではありません。@endsection
ディレクティブはセクションを定義するだけで、@show
はセクションを定義し、即座にyieldします。
``````blade
@yield('content', 'Default content')
`
フォーム
CSRFフィールド
アプリケーションでHTMLフォームを定義するたびに、CSRF保護ミドルウェアがリクエストを検証できるように、フォームに隠しCSRFトークンフィールドを含める必要があります。@csrf
ブレードディレクティブを使用してトークンフィールドを生成できます:
<form method="POST" action="/profile">
@csrf
...
</form>
メソッドフィールド
HTMLフォームはPUT
、PATCH
、またはDELETE
リクエストを行うことができないため、これらのHTTP動詞を偽装するために隠し_method
フィールドを追加する必要があります。@method
ブレードディレクティブがこのフィールドを作成できます:
<form action="/foo/bar" method="POST">
@method('PUT')
...
</form>
バリデーションエラー
``````blade
<!-- /resources/views/auth.blade.php -->
<label for="email">Email address</label>
<input id="email"
type="email"
class="@error('email') is-invalid @else is-valid @enderror">
`
複数のフォームを含むページでバリデーションエラーメッセージを取得するために、@error
ディレクティブに特定のエラーバッグの名前を第二のパラメータとして渡すことができます:
<!-- /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
スタック
ブレードでは、名前付きスタックにプッシュして、他のビューやレイアウトのどこかでレンダリングできます。これは、子ビューで必要なJavaScriptライブラリを指定するのに特に便利です:
@push('scripts')
<script src="/example.js"></script>
@endpush
指定されたブール式がtrue
に評価される場合に@push
コンテンツをプッシュしたい場合は、@pushIf
ディレクティブを使用できます:
@pushIf($shouldPush, 'scripts')
<script src="/example.js"></script>
@endPushIf
スタックに必要なだけプッシュできます。スタックの完全な内容をレンダリングするには、@stack
ディレクティブにスタックの名前を渡します:
<head>
<!-- Head Contents -->
@stack('scripts')
</head>
スタックの先頭にコンテンツを追加したい場合は、@prepend
ディレクティブを使用する必要があります:
@push('scripts')
This will be second...
@endpush
// Later...
@prepend('scripts')
This will be first...
@endprepend
サービスインジェクション
``````blade
@inject('metrics', 'App\Services\MetricsService')
<div>
Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>
`
インラインブレードテンプレートのレンダリング
時には、生のブレードテンプレート文字列を有効なHTMLに変換する必要があります。これは、render
メソッドを使用してBlade
ファサードによって提供されます。render
メソッドは、ブレードテンプレート文字列と、テンプレートに提供するオプションのデータ配列を受け取ります:
use Illuminate\Support\Facades\Blade;
return Blade::render('Hello, {{ $name }}', ['name' => 'Julian Bashir']);
Laravelは、インラインブレードテンプレートをstorage/framework/views
ディレクトリに書き込むことによってレンダリングします。ブレードテンプレートをレンダリングした後にLaravelがこれらの一時ファイルを削除するようにしたい場合は、メソッドにdeleteCachedView
引数を提供できます:
return Blade::render(
'Hello, {{ $name }}',
['name' => 'Julian Bashir'],
deleteCachedView: true
);
ブレードフラグメントのレンダリング
Turboやhtmxなどのフロントエンドフレームワークを使用しているとき、HTTPレスポンス内でブレードテンプレートの一部だけを返す必要がある場合があります。ブレード「フラグメント」を使用すると、まさにそれが可能です。始めるには、ブレードテンプレートの一部を@fragment
および@endfragment
ディレクティブ内に配置します:
@fragment('user-list')
<ul>
@foreach ($users as $user)
<li>{{ $user->name }}</li>
@endforeach
</ul>
@endfragment
次に、このテンプレートを利用するビューをレンダリングするときに、fragment
メソッドを呼び出して、指定されたフラグメントのみを出力HTTPレスポンスに含めるように指定できます:
return view('dashboard', ['users' => $users])->fragment('user-list');
``````php
return view('dashboard', ['users' => $users])
->fragmentIf($request->hasHeader('HX-Request'), 'user-list');
`
``````php
view('dashboard', ['users' => $users])
->fragments(['user-list', 'comment-list']);
view('dashboard', ['users' => $users])
->fragmentsIf(
$request->hasHeader('HX-Request'),
['user-list', 'comment-list']
);
`
ブレードの拡張
ブレードでは、directive
メソッドを使用して独自のカスタムディレクティブを定義できます。ブレードコンパイラがカスタムディレクティブに遭遇すると、ディレクティブに含まれる式を持つコールバックが提供されます。
次の例では、@datetime($var)
ディレクティブを作成し、$var
のインスタンスである必要があります。DateTime
:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
// ...
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Blade::directive('datetime', function (string $expression) {
return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
});
}
}
この例では、ディレクティブに渡される式にformat
メソッドをチェーンします。したがって、このディレクティブによって生成される最終的なPHPは次のようになります:
<?php echo ($var)->format('m/d/Y H:i'); ?>
ブレードディレクティブのロジックを更新した後は、すべてのキャッシュされたブレードビューを削除する必要があります。キャッシュされたブレードビューは、view:clear
Artisanコマンドを使用して削除できます。
カスタムエコーハンドラ
ブレードを使用してオブジェクトを「エコー」しようとすると、オブジェクトのtoString
メソッドが呼び出されます。toString
メソッドは、PHPの組み込み「マジックメソッド」の1つです。ただし、時には、特定のクラスのtoString
メソッドを制御できない場合があります。たとえば、やり取りしているクラスがサードパーティライブラリに属している場合です。
このような場合、ブレードでは、その特定のタイプのオブジェクトに対してカスタムエコーハンドラを登録できます。これを実現するには、ブレードのstringable
メソッドを呼び出す必要があります。stringable
メソッドはクロージャを受け入れます。このクロージャは、レンダリングを担当するオブジェクトのタイプを型ヒントする必要があります。通常、stringable
メソッドは、アプリケーションのAppServiceProvider
クラスのboot
メソッド内で呼び出されるべきです:
use Illuminate\Support\Facades\Blade;
use Money\Money;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Blade::stringable(function (Money $money) {
return $money->formatTo('en_GB');
});
}
カスタムエコーハンドラが定義されると、ブレードテンプレート内でオブジェクトを単にエコーできます:
Cost: {{ $money }}
カスタムif文
カスタムディレクティブをプログラミングすることは、単純なカスタム条件文を定義する際に、時には必要以上に複雑になることがあります。そのため、ブレードは、クロージャを使用してカスタム条件ディレクティブを迅速に定義できるBlade::if
メソッドを提供します。たとえば、アプリケーションの構成されたデフォルト「ディスク」を確認するカスタム条件を定義してみましょう。boot
メソッドでこれを行うことができます:
use Illuminate\Support\Facades\Blade;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Blade::if('disk', function (string $value) {
return config('filesystems.default') === $value;
});
}
カスタム条件が定義されると、テンプレート内で使用できます:
@disk('local')
<!-- The application is using the local disk... -->
@elsedisk('s3')
<!-- The application is using the s3 disk... -->
@else
<!-- The application is using some other disk... -->
@enddisk
@unlessdisk('local')
<!-- The application is not using the local disk... -->
@enddisk