Blade Templates
Table of Contents
Introduction
Blade は、 Laravel に含まれているシンプルでありながら強力なテンプレートエンジンです。一部の PHP テンプレートエンジンとは異なり、 Blade はテンプレート内でプレーンな PHP の code を使用することを制限しません。事実、すべての Blade templates はプレーンな PHP の code にコンパイルされ、それらが変更されるまでキャッシュされます。これは、 Blade があなたの application にほとんどオーバーヘッドを加えないことを意味します。 Blade のテンプレートファイルは.blade.php拡張子を使用し、通常は resources/views ディレクトリに保存されます。
Blade views は、グローバルviewヘルパーを使用して、routes またはコントローラーから返すことができます。もちろん、viewsに関するドキュメントで述べられているように、viewヘルパーの第二引数を使用して Blade view に data を渡すことができます:
Route::get('/', function () {
return view('greeting', ['name' => 'Finn']);
});
Livewire で Blade を超充電する
Blade templates を次のレベルに引き上げて、簡単に build できるダイナミックなインターフェースを作成したいですか? Laravel Livewire をご覧ください。Livewire を使用すると、通常は React や Vue のようなフロントエンドフレームワークを介してのみ可能であったダイナミックな機能を付加した Blade コンポーネントを作成できます。これは複雑さ、クライアント側のレンダリング、または多くの JavaScript フレームワークの build ステップなしで、現代的で反応の良いフロントエンドを構築する素晴らしいアプローチを提供します。
Displaying Data
あなたは、データをカーリーブラケツで囲むことにより、 Blade views に渡された data を表示することができます。例えば、以下のような route があるとします:
Route::get('/', function () {
return view('welcome', ['name' => 'Samantha']);
});
次のようにname変数の内容を表示することができます:
Hello, {{ $name }}.
NOTE
Blade の
{{}}エコーステートメントは、XSS 攻撃を防ぐために自動的に PHP のhtmlspecialchars関数を通過します。
変数に渡された内容を表示することに限定されていません。 view 。 PHP 関数の結果をエコーすることも可能です。実際、任意の PHP の code を Blade のエコー statement 内に配置することができます。
The current UNIX timestamp is {{ time() }}.
HTML エンティティエンコーディング
default では、Blade(および Laravel のe関数)は HTML エンティティを二重にエンコードします。二重エンコードを無効にしたい場合は、AppServiceProviderのboot method からBlade::withoutDoubleEncoding method を呼び出してください:
<?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();
}
}
エスケープされていない Data を表示する
default として、{{ }}の Blade 文は、XSS 攻撃を防ぐために PHP のhtmlspecialchars関数を自動的に通過します。あなたが data をエスケープさせたくない場合は、以下の構文を使用することができます:
Hello, {!! $name !!}.
WARNING
application の users から提供される content をエコーする際には非常に注意が必要です。通常、users が提供した data を表示する際に XSS 攻撃を防ぐために、エスケープされたダブルカーリーブレースの構文を使用する必要があります。
Blade と JavaScript フレームワーク
多くの「 JavaScript 」フレームワークも「波括弧」を使用して、特定の式がブラウザに表示されるべきことを示すため、@記号を使用して「 Blade 」レンダリングエンジンに式をそのままにしておくべきであることを知らせることができます。たとえば:
<h1>Laravel</h1>
Hello, @{{ name }}.
この例では、@記号は Blade によって削除されますが、{{ name }}式は Blade エンジンによって変更されず、JavaScript フレームワークで rendering することが可能になります。
@記号はまた、 Blade ディレクティブをエスケープするためにも使用できます:
{{-- Blade template --}}
@@if()
<!-- HTML output -->
@if()
JSON のレンダリング
時には、 array を view に渡し、それを JSON として rendering して、 JavaScript variables を初期化するつもりで渡すことがあります。例えば:
<script>
var app = <?php echo json_encode($array); ?>;
</script>
しかし、手動でjson_encodeを呼び出す代わりに、Illuminate\Support\Js::from method ディレクティブを使用することができます。from method は、PHP のjson_encode関数と同じ引数を受け付けます。しかし、結果として得られる JSON が HTML の引用符内に正しくエスケープされることを保証します。from method は、与えられた object または array を正当な JavaScript オブジェクトに変換するJSON.parse JavaScriptstatement の string を返します。
<script>
var app = {{ Illuminate\Support\Js::from($array) }};
</script>
最新版の Laravel application スケルトンには、Js facade が含まれており、これによりあなたの Blade テンプレート内でこの機能に便利にアクセスすることができます:
<script>
var app = {{ Js::from($array) }};
</script>
WARNING
Js::frommethod は、既存の variables を JSON として render するためにのみ使用すべきです。 Blade テンプレートは正規表現に基づいており、複雑な表現をディレクティブに渡そうとすると予期しない失敗を引き起こす可能性があります。
@verbatim ディレクティブ
もしテンプレートの大部分に JavaScript 変数を表示しているなら、@verbatimディレクティブで HTML をラップすることで、 Blade の各エコー statement に@シンボルを接頭辞として追加する必要がなくなります。
@verbatim
<div class="container">
Hello, {{ name }}.
</div>
@endverbatim
Blade Directives
テンプレート継承と data の表示に加えて、 Blade は条件文やループなど、一般的な PHP 制御構造のための便利なショートカットも提供しています。これらのショートカットは、とてもすっきりとした簡潔な方法で PHP 制御構造を操作することを可能にし、それでいて PHP の類似機能にも親しいままです。
If 文
あなたは @if、@elseif、@else、そして @endif のディレクティブを使用して if 文を構築することができます。これらのディレクティブはその PHP の対応部分と全く同じように機能します:
@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
Authentication ディレクティブ
@authおよび@guestディレクティブは、現在の user が認証されているのか、またはゲストなのかを素早く判断するために使用できます。
@auth
// The user is authenticated...
@endauth
@guest
// The user is not authenticated...
@endguest
必要に応じて、@auth と @guest ディレクティブを使用する際に確認すべき authentication ガードを指定できます:
@auth('admin')
// The user is authenticated...
@endauth
@guest('admin')
// The user is not authenticated...
@endguest
Environment ディレクティブ
@productionディレクティブを使用して、 application が production environment で実行されているかどうかを確認できます。
@production
// Production specific content...
@endproduction
または、@envディレクティブを使用して、 application が特定の environment で実行されているかどうかを判断することもできます。
@env('staging')
// The application is running in "staging"...
@endenv
@env(['staging', 'production'])
// The application is running in "staging" or "production"...
@endenv
セクションディレクティブ
@hasSectionディレクティブを使用して、テンプレート継承セクションに content があるかどうかを判断することができます:
@hasSection('navigation')
<div class="pull-right">
@yield('navigation')
</div>
<div class="clearfix"></div>
@endif
セクションに content が存在しないかどうかを判断するために、sectionMissingディレクティブを使用することができます:
@sectionMissing('navigation')
<div class="pull-right">
@include('default-navigation')
</div>
@endif
Session ディレクティブ
@sessionディレクティブは、session value が存在するかどうかを判断するために使用できます。 session value が存在する場合、@sessionおよび@endsessionディレクティブ内のテンプレートの内容が評価されます。@sessionディレクティブの内容内で、$value変数を echo することで session value を表示できます。
@session('status')
<div class="p-4 bg-green-100">
{{ $value }}
</div>
@endsession
スイッチステートメント
@switch、@case、@break、@default、@endswitchディレクティブを使用して、Switch 文を作成することができます:
@switch($i)
@case(1)
First case...
@break
@case(2)
Second case...
@break
@default
Default case...
@endswitch
Loops
条件文に加えて、 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
NOTE
foreachループを反復処理している間、ループ変数を使用して、ループの最初の反復または最後の反復かどうかなど、ループに関する貴重な情報を得ることができます。
ループを使用する際にも、現在の反復をスキップしたり、ループを終了させたりすることができます。これには、@continueおよび@breakディレクティブを使用します:
@foreach ($users as $user)
@if ($user->type == 1)
@continue
@endif
<li>{{ $user->name }}</li>
@if ($user->number == 5)
@break
@endif
@endforeach
また、ディレクティブの declaration 内に続行または中断条件を含めることもできます:
@foreach ($users as $user)
@continue($user->type == 1)
<li>{{ $user->name }}</li>
@break($user->number == 5)
@endforeach
ループ変数
foreachループを繰り返す間、$loop変数はループ内で利用可能になります。この変数は、現在のループインデックスや、これがループの最初の反復または最後の反復であるかどうかなど、いくつかの有用な情報にアクセスすることを提供します:
@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
あなたがネストされたループの中にいる場合、parentプロパティを通じて親ループの$loop変数にアクセスすることができます:
@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変数には、他にもさまざまな便利なプロパティが含まれています。
| プロパティ | 説明 |
|---|---|
$loop->index | 現在のループの繰り返しのインデックス(0 から始まる)。 |
$loop->iteration | 現在のループの反復(1 から始まります)。 |
$loop->remaining | ループの残りの繰り返し回数。 |
$loop->count | イテレートされている array 内のアイテムの総数。 |
$loop->first | これがループの最初の反復であるかどうか。 |
$loop->last | これがループの最後の反復であるかどうか。 |
$loop->even | これがループを通した偶数回目の反復であるかどうか。 |
$loop->odd | これがループでの奇数回の繰り返しであるかどうか。 |
$loop->depth | 現在のループのネストレベル。 |
$loop->parent | ネストしたループ内にある場合、親のループ変数。 |
条件付きクラス&スタイル
@classディレクティブは条件付きで CSS クラス string をコンパイルします。このディレクティブは、arraykey が追加したい class を含む array のクラスを受け入れます。一方、value はブール式です。array 要素が数 valuekey を持っている場合、それは常に rendering された class リストに含まれます。
@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ディレクティブは、条件付きでインラインの CSS スタイルを HTML 要素に追加するために使用することができます:
@php
$isActive = true;
@endphp
<span @style([
'background-color: red',
'font-weight: bold' => $isActive,
])></span>
<span style="background-color: red; font-weight: bold;"></span>
追加の Attributes
便宜上、@checkedディレクティブを使用して、指定された HTML チェックボックス input が"checked"であるかどうかを簡単に示すことができます。このディレクティブは、提供された条件がtrueと評価される場合にcheckedをエコーします:
<input type="checkbox"
name="active"
value="active"
@checked(old('active', $user->active)) />
同様に、@selected ディレクティブは、特定の selectoption が "selected"であるべきかを示すために使用できます。
<select name="version">
@foreach ($product->versions as $version)
<option value="{{ $version }}" @selected(old('version') == $version)>
{{ $version }}
</option>
@endforeach
</select>
さらに、@disabled ディレクティブは、特定の要素が "disabled" であるべきかどうかを示すために使用できます。
<button type="submit" @disabled($errors->isNotEmpty())>Submit</button>
さらに、@readonly ディレクティブは特定の要素が "readonly" であるべきかどうかを示すために使用することができます。
<input type="email"
name="email"
value="email@laravel.com"
@readonly($user->isNotAdmin()) />
さらに、@requiredディレクティブは、特定の要素が"required"であるべきかどうかを示すために使用することができます。
<input type="text"
name="title"
value="title"
@required($user->isAdmin()) />
サブビューの含め方
NOTE
あなたは自由に
@includeディレクティブを使うことができますが、 Blade componentsは同様の機能を提供し、 data や attribute のバインディングなど、@includeディレクティブよりもいくつかの利点を提供します。
Blade の @include ディレクティブを使用すると、他の view から Blade view を含めることができます。親の view で利用可能なすべての変数は、含まれる view でも利用可能になります:
<div>
@include('shared.errors')
<form>
<!-- Form Contents -->
</form>
</div>
含まれる view は、親の view で利用可能なすべての data を継承しますが、含まれる view で利用可能にすべき追加の data の array も渡すことができます:
@include('view.name', ['status' => 'complete'])
存在しない view を @includeしようと attempt と、 Laravel は error を throw します。存在してもしなくても良い view を含めたい場合は、@includeIf ディレクティブを使用すべきです:
@includeIf('view.name', ['status' => 'complete'])
指定した boolean 式がtrueまたはfalseに評価された場合に view を@includeしたい場合は、@includeWhenおよび@includeUnlessディレクティブを使用できます:
@includeWhen($boolean, 'view.name', ['status' => 'complete'])
@includeUnless($boolean, 'view.name', ['status' => 'complete'])
与えられた array の views から存在する最初の view を含めるには、includeFirstディレクティブを使用できます:
@includeFirst(['custom.admin', 'admin'], ['status' => 'complete'])
WARNING
あなたの Blade views で
__DIR__や__FILE__定数を使用することは避けるべきです。なぜなら、それらはキャッシュされ、コンパイルされた view の場所を参照するからです。
Collections のための Views の rendering
Blade の @each ディレクティブを用いて、ループと includes を一行で組み合わせることができます:
@each('view.name', $jobs, 'job')
@eachディレクティブの最初の引数は、 array または collection の各要素に対して render する view です。二番目の引数は、繰り返し処理したい array または collection で、三番目の引数は、 view 内の現在の繰り返しに割り当てられる変数名です。例えば、jobsという array を繰り返し処理している場合、通常は各 job をjob変数として view 内でアクセスしたいでしょう。現在の繰り返し用の array キーは、 view 内のkey変数として利用可能になります。
@eachディレクティブには第四引数も渡すことができます。この引数は、与えられた array が空の場合にレンダリングされる view を決定します。
@each('view.name', $jobs, 'job', 'view.empty')
WARNING
@eachによって描画された Views は親の view から変数を継承しません。子の view がこれらの変数を必要とする場合、代わりに@foreachおよび@includeディレクティブを使用するべきです。
@once ディレクティブ
@once ディレクティブは、レンダリングサイクルごとに一度だけ評価されるテンプレートの一部を定義することを可能にします。これは、特定の JavaScript の一部をページの header にスタックを使ってプッシュする際に有用かもしれません。例えば、あるcomponentをループ内でレンダリングしている場合、その component が最初にレンダリングされた時だけ JavaScript を header にプッシュしたいかもしれません。
@once
@push('scripts')
<script>
// Your custom JavaScript...
</script>
@endpush
@endonce
@onceディレクティブは、しばしば@pushや@prependディレクティブと組み合わせて使用されるため、便宜上@pushOnceおよび@prependOnceディレクティブが利用可能です。
@pushOnce('scripts')
<script>
// Your custom JavaScript...
</script>
@endPushOnce
ローコード PHP
一部の状況では、PHP の code を views に組み込むと便利です。 テンプレート内の通常の PHP ブロックを実行するために、 Blade の @php ディレクティブを使用できます。
@php
$counter = 1;
@endphp
または、PHP を使って class をインポートするだけの場合、@useディレクティブを使用することもできます:
@use('App\Models\Flight')
二つ目の引数は、@useディレクティブに提供され、インポートされた class にエイリアスを付けるために使用できます。
@use('App\Models\Flight', 'FlightModel')
Comments
Blade はまた、 views の中に comments を定義することを可能にします。しかし、 HTML comments とは違い、 Blade comments はあなたの application が返す HTML には含まれません。
{{-- This comment will not be present in the rendered HTML --}}
Components
コンポーネントとスロットは、セクション、レイアウト、インクルードと同様の利点を提供しますが、一部の人々はコンポーネントとスロットの model が理解しやすいと感じるかもしれません。コンポーネントの書き方には二つのアプローチがあります。 class ベースのコンポーネントと匿名コンポーネントです。
class ベースの component を作成するには、make:component Artisan command を使用できます。 component の使用方法を示すために、シンプルなAlert component を作成します。make:component command は、component をapp/View/Componentsディレクトリに配置します。
php artisan make:component Alert
make:component command はまた、component のための view テンプレートも作成します。view は resources/views/components ディレクトリに配置されます。ご自身の application 用のコンポーネントを作成する際、コンポーネントは自動的に app/View/Components ディレクトリと resources/views/components ディレクトリ内で発見されますので、通常、さらなる component の 登録は 必要ありません。
また、サブディレクトリ内にコンポーネントを作成することもできます:
php artisan make:component Forms/Input
上記の command は、app/View/Components/FormsディレクトリにInputの component を作成し、 view はresources/views/components/formsディレクトリに配置されます。
匿名の component ( class がなく、 Blade テンプレートのみの component )を作成したい場合、make:component command を呼び出すときに、--viewフラグを使用することができます。
php artisan make:component forms.input --view
上記の command は、resources/views/components/forms/input.blade.phpに Blade ファイルを作成します。これは<x-forms.input />を使用して component としてレンダリングできます。
パッケージコンポーネントの手動登録
あなた自身の application のコンポーネントを作成する際、コンポーネントは自動的にapp/View/Componentsディレクトリとresources/views/componentsディレクトリ内で見つけられます。
しかし、 Blade コンポーネントを利用するパッケージを構築している場合、手動で component class とその HTML タグエイリアスを register する必要があります。通常、 boot method でパッケージの service provider にコンポーネントを register すべきです。
use Illuminate\Support\Facades\Blade;
/**
* Bootstrap your package's services.
*/
public function boot(): void
{
Blade::component('package-alert', Alert::class);
}
あなたの component が登録されたら、そのタグエイリアスを使用してレンダリングすることができます:
<x-package-alert/>
あるいは、componentNamespace method を使用して、規約により component classes を自動的に読み込むこともできます。例えば、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::の構文を使用して、パッケージの components をそのベンダー名前空間で使用することができます。
<x-nightshade::calendar />
<x-nightshade::color-picker />
Blade は、" component "の名前をパスカルケースにすることで、この" component "にリンクされた" class "を自動的に検出します。また、"dot"表記を使用してサブディレクトリもサポートしています。
コンポーネントのレンダリング
component を表示するには、 Blade component タグをあなたの Blade templates のいずれか内部で使うことができます。 Blade component tags は、 string x- で始まり、その後に component class のケバブケース名が続きます:
<x-alert/>
<x-user-profile/>
component class がapp/View/Componentsディレクトリ内のより深い階層にネストされている場合、ディレクトリのネストを示すために.文字を使用することができます。例えば、 component がapp/View/Components/Inputs/Button.phpに位置していると仮定すると、以下のように render することができます。
<x-inputs.button/>
component class を条件付きでレンダーしたい場合は、 component class 上にshouldRender method を定義することができます。shouldRender method がfalseを返すと、 component は render ing されません。
use Illuminate\Support\Str;
/**
* Whether the component should be rendered
*/
public function shouldRender(): bool
{
return Str::length($this->message) > 0;
}
コンポーネントに Data を渡す
:文字を接頭辞として使用した attributes を通じて、 component に PHP の式と変数を渡すべきです。固定化された原始的な values は、 HTML attribute の文字列を使用して component に渡すことができます。 data を HTML attributes を使用して Blade コンポーネントに渡すことができます。
<x-alert type="error" :message="$message"/>
すべての component の data attributes は、その component の class コンストラクタで定義する必要があります。component 上のすべての public プロパティは、自動的にその component の view で使用できるようになります。component のrender method から data を view に渡す必要はありません。
<?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');
}
}
あなたの component がレンダリングされたとき、コンポーネントの public 変数の内容を変数名を使ってエコーして表示することができます。
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>
Casing
Component コンストラクタの引数は camelCase を使用して指定すべきであり、kebab-case はあなたの HTML attributes 内で引数名を参照するときに使用すべきです。例えば、以下の component コンストラクタがあるとします:
/**
* Create the component instance.
*/
public function __construct(
public string $alertType,
) {}
$alertType引数は、以下のように component に提供されるかもしれません:
<x-alert alert-type="danger" />
短い Attribute Syntax
component に属性を渡すとき、ショート属性のシンタックスを使用することもできます。これはしばしば便利です。なぜなら属性の名前は頻繁にそれに対応する variable 名と一致するからです:
{{-- Short attribute syntax... --}}
<x-profile :$userId :$name />
{{-- Is equivalent to... --}}
<x-profile :user-id="$userId" :name="$name" />
Attribute レンダリングからの脱出
一部の JavaScript フレームワーク、例えば Alpine.js はコロンで始まる attributes を使用するため、ダブルコロン(::)接頭辞を使って Blade にその attribute が PHP の式でないことを通知することができます。たとえば、次のような component があるとします:
<x-button ::class="{ danger: isDeleting }">
Submit
</x-button>
次の HTML は Blade によってレンダリングされます:
<button :class="{ danger: isDeleting }">
Submit
</button>
Component メソッド
公開 variables が component テンプレートで使用可能であるだけでなく、component のすべての公開 method も呼び出すことができます。例えば、isSelected method を持つ component を想像してみてください。
/**
* Determine if the given option is the currently selected option.
*/
public function isSelected(string $option): bool
{
return $option === $this->selected;
}
この method は、 method の名前と一致する変数を呼び出すことにより、 component テンプレートから実行することができます:
<option {{ $isSelected($value) ? 'selected' : '' }} value="{{ $value }}">
{{ $label }}
</option>
Component クラス内の Attributes とスロットへのアクセス
Blade component は、class の rendering method 内で component 名、属性、およびスロットにアクセスすることも可能です。ただし、この data にアクセスするためには、render method からクロージャを返すべきです。このクロージャは、引数として$data array を受け取ります。この array には、component に関する情報を提供するいくつかの要素が含まれています。
use Closure;
/**
* Get the view / contents that represent the component.
*/
public function render(): Closure
{
return function (array $data) {
// $data['componentName'];
// $data['attributes'];
// $data['slot'];
return '<div>Components content</div>';
};
}
componentNameはx-プレフィックスの後に HTML タグで使用された名前と等しいです。したがって、<x-alert />のcomponentNameはalertになります。attributes要素は、 HTML タグに存在したすべての attributes を含んでいます。slot要素は、コンポーネントのスロットの内容を持つIlluminate\Support\HtmlStringインスタンスです。
クロージャは string を返すべきです。返された string が既存の view に対応している場合、その view がレンダリングされます。それ以外の場合、返された string はインラインの Blade view として評価されます。
追加の依存関係
もし、あなたの component が Laravel のservice containerから依存性を必要とする場合、それらを component の data attributes の前にリストにしておけば、自動的にコンテナに注入されます:
use App\Services\AlertCreator;
/**
* Create the component instance.
*/
public function __construct(
public AlertCreator $creator,
public string $type,
public string $message,
) {}
Attributes / メソッドを隠す
もし、一部の public メソッドやプロパティが、 component テンプレートに変数として公開されるのを防ぎたい場合、それらを component 上の $except array プロパティに追加することができます:
<?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,
) {}
}
Component Attributes
すでに data attributes を component に渡す方法を検討してきました。しかし、時折、classのような、component の機能に必要な data required の一部ではない追加の HTML attributes を指定する必要があります。通常、これらの追加の attributes を component テンプレートの root 要素に渡したいと考えるでしょう。例えば、alertの component を以下のように render したいと想像してみてください。
<x-alert type="error" :message="$message" class="mt-4"/>
component のコンストラクタの一部でないすべての"属性"は、自動的にその component の"属性バッグ"に追加されます。この"属性"バッグは、$attributesvariables を介して component に自動的に利用可能になります。すべての"属性"は、この variables をエコーすることによって"component"内で rendering することができます:
<div {{ $attributes }}>
<!-- Component content -->
</div>
WARNING
@env のような指令を component tags 内で使用することは現時点ではサポートされていません。例えば、<x-alert :live="@env('production')" />はコンパイルされません。
Default / 結合された Attributes
時々、属性に対して default 値を指定したり、コンポーネントの一部の属性に追加の values を結合する必要があるかもしれません。これを実現するためには、merge method を使用して属性バッグを使用することができます。この method は、常に component に適用されるべき一連の defaultCSSclasses を定義するのに特に便利です。
<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
{{ $message }}
</div>
もし、この component がこのように利用されると仮定した場合:
<x-alert type="error" :message="$message" class="mb-4"/>
最終的にレンダリングされた HTML は、以下のように component に表示されます:
<div class="alert alert-error mb-4">
<!-- Contents of the $message variable -->
</div>
条件付きで Merge クラスを結合する
時折、ある条件が true の場合に merge という class を結合したいと思うかもしれません。これは、class method を介して達成することができます。この method は、 array の key に追加したい class または class を含む class の array を受け入れ、 value は boolean 式です。もし array の要素が数 value の key を持っている場合、それは常に rendering された class のリストに含まれるでしょう。
<div {{ $attributes->class(['p-4', 'bg-red' => $hasError]) }}>
{{ $message }}
</div>
あなたが他の 属性 を あなたの component に 結合 する必要がある場合、merge method を class method にチェーンさせることができます。`
<button {{ $attributes->class(['p-4'])->merge(['type' => 'button']) }}>
{{ $slot }}
</button>
NOTE
他の HTML elements に対して条件付きでクラスをコンパイルする必要があり、それらがマージされた attributes を受け取るべきでない場合、
@classdirectiveを使用することができます。
非クラス Attribute のマージ
class attributes ではない attributes を結合するとき、merge method に提供される values は、 attribute の"default の" values と見なされます。しかし、class attribute とは異なり、これらの attributes は注入された attribute values とは結合されません。代わりに、それらは上書きされます。例えば、button component の実装は次のようになる可能性があります:
<button {{ $attributes->merge(['type' => 'button']) }}>
{{ $slot }}
</button>
button component を custom のtypeで render ing するには、 component を使用する際に指定することができます。 もし type が指定されていない場合、buttonの type が使用されます。
<x-button type="submit">
Submit
</x-button>
この例では、button component のレンダリングされた HTML は次のようになるでしょう:
<button type="submit">
Submit
</button>
class以外の attribute にその default value と注入された values を結合させたい場合は、prepends method を使用することができます。この例では、data-controller attribute は常にprofile-controllerで始まり、追加で注入されたdata-controller values はこの default value の後に配置されます:
<div {{ $attributes->merge(['data-controller' => $attributes->prepends('profile-controller')]) }}>
{{ $slot }}
</div>
Attributes の取得とフィルタリング
filter method を使用して attributes をフィルタリングすることができます。この method はクロージャを受け入れ、attribute を attribute バッグに保持したい場合はtrueを返すべきです:
{{ $attributes->filter(fn (string $value, string $key) => $key == 'foo') }}
便宜上、特定の string で始まるすべての attributes の keys を取得するために、whereStartsWith method を使用することができます。
{{ $attributes->whereStartsWith('wire:model') }}
それに対して、whereDoesntStartWith method は、特定の string で始まる全ての attributes の keys を除外するために使用することができます:
{{ $attributes->whereDoesntStartWith('wire:model') }}
first method を使用すると、指定した attribute バッグの最初の attribute を render することができます。
{{ $attributes->whereStartsWith('wire:model')->first() }}
component 上の attribute が存在するかどうかを確認したい場合は、has method を使用できます。この method は attribute の名前を唯一の引数として受け取り、 attribute が存在するかどうかを示す boolean を返します:
@if ($attributes->has('class'))
<div>Class attribute is present</div>
@endif
has method に array が渡されると、この method は与えられたすべての attributes が component 上に存在するかどうかを判断します。
@if ($attributes->has(['name', 'class']))
<div>All of the attributes are present</div>
@endif
hasAny method は、与えられた attributes のいずれかが component に存在するかどうかを判断するために使用できます。
@if ($attributes->hasAny(['href', ':href', 'v-bind:href']))
<div>One of the attributes is present</div>
@endif
get method を使用して、特定の属性の value を取得することができます:
{{ $attributes->get('class') }}
予約語
default として、いくつかの key ワードは Blade の内部使用のために予約されており、component を render ing するために使用されます。以下の key ワードは、component 内で public プロパティまたは method 名として定義することはできません:
datarenderresolveViewshouldRenderviewwithAttributeswithName
Slots
あなたはしばしば追加の content を slots 経由であなたの Component に渡す必要があります。 component のスロットは$slot変数をエコーすることでレンダリングされます。この概念を探求するために、alert component が次のマークアップを持っていると想像してみましょう:
<!-- /resources/views/components/alert.blade.php -->
<div class="alert alert-danger">
{{ $slot }}
</div>
私たちはslotに content を渡すことができ、 component に content を注入することにより行います:
<x-alert>
<strong>Whoops!</strong> Something went wrong!
</x-alert>
時には component が褒められた render が、その component 内の他の場所に、さまざまな手段を必要とすることがあります。私たちの alert component を、"title" スロットの挿入を可能にするように変更しましょう:
<!-- /resources/views/components/alert.blade.php -->
<span class="alert-title">{{ $title }}</span>
<div class="alert alert-danger">
{{ $slot }}
</div>
x-slotタグを使用して名前付きスロットの content を定義することができます。明示的なx-slotタグ内にないすべての content は、$slot変数の中の component に渡されます。
<x-alert>
<x-slot:title>
Server Error
</x-slot>
<strong>Whoops!</strong> Something went wrong!
</x-alert>
スロットが content を含んでいるかどうかを判断するために、スロットの isEmpty method を呼び出すことができます:
<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 method は、スロットが HTML comment ではない "実際の" content を含んでいるかどうかを判断するために使用することができます:
@if ($slot->hasActualContent())
The scope has non-comment content.
@endif
スコープ付きスロット
Vue のような JavaScript フレームワークを使用したことがあれば、"scoped slots"という概念に精通しているかもしれません。これにより、スロット内で data や component からのメソッドにアクセスできます。同様の動作は、 Laravel で public なメソッドやプロパティを component に定義し、$component変数を経由してスロット内で component にアクセスすることで実現できます。この例では、x-alert component に public なformatAlert method が component class 上に定義されていると仮定します:
<x-alert>
<x-slot:title>
{{ $component->formatAlert('Server Error') }}
</x-slot>
<strong>Whoops!</strong> Something went wrong!
</x-alert>
スロット Attributes
Blade component と同様に、CSS class 名などのスロットに追加の属性を割り当てることができます:
<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 とやり取りするには、スロットの変数のattributesプロパティにアクセスすることが可能です。 attributes とどのようにやり取りするかについての詳細は、component 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>
インライン Component Views
非常に小さなコンポーネントでは、 component class とコンポーネントの view テンプレートの両方を管理するのが煩雑に感じるかもしれません。このため、render method から直接コンポーネントのマークアップを返すことができます:
/**
* Get the view / contents that represent the component.
*/
public function render(): string
{
return <<<'blade'
<div class="alert alert-danger">
{{ $slot }}
</div>
blade;
}
インライン View コンポーネントの生成
make:component command を実行する際に、インラインの view を rendering する component を作成する場合は、inlineoption を使用することができます。
php artisan make:component Alert --inline
ダイナミックコンポーネント
時には、 render する component を選ばなければならない場合がありますが、それがどの component であるべきかは、 runtime まで分からないかもしれません。このような状況では、Laravel の組み込みdynamic-component component を使用して、 runtime value または変数に基づいて component を render することができます:
// $componentName = "secondary-button";
<x-dynamic-component :component="$componentName" class="mt-4" />
コンポーネントの手動登録
WARNING
次のコンポーネントの手動登録に関する文書は、主に Laravel パッケージを記述していて、そのパッケージに view コンポーネントが含まれている人々に適用されます。パッケージを作成していない場合、この component 文書の一部はあなたには関連性がないかもしれません。
自身の application 向けのコンポーネントを作成する際、コンポーネントは自動的に app/View/Components ディレクトリおよび resources/views/components ディレクトリ内で発見されます。
しかし、 Blade コンポーネントを使用するパッケージを作成している、または非標準のディレクトリにコンポーネントを配置している場合は、 Laravel が component の場所を知るために、 component class とその HTML タグエイリアスを手動で register する必要があります。通常、パッケージの service provider の boot method でコンポーネントを register するべきです:
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);
}
あなたの component が登録されたら、そのタグのエイリアスを使用してレンダリングできます:
<x-package-alert/>
パッケージコンポーネントの自動ロード
あるいは、componentNamespace method を使用して、 component classes を慣例により自動的に読み込むこともできます。例えば、Nightshadeパッケージには、Package\Views\Components名前空間内に存在するCalendarとColorPickerのコンポーネントがあるかもしれません:
use Illuminate\Support\Facades\Blade;
/**
* Bootstrap your package's services.
*/
public function boot(): void
{
Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');
}
これにより、package-name::の syntax を使用して、その vendor 名前空間でパッケージコンポーネントを使用することができます。
<x-nightshade::calendar />
<x-nightshade::color-picker />
Blade は"pascal-case"を使用して component の名前を自動的に検出し、それがこの component にリンクされている class を認識します。サブディレクトリーも dot 表記を使用してサポートされます。
Anonymous Components
インラインコンポーネントと同様に、匿名コンポーネントは、 component を single ファイルを通じて管理するためのメカニズムを提供します。ただし、匿名コンポーネントは single view ファイルを利用し、関連する class はありません。匿名の component を定義するには、resources/views/componentsディレクトリ内に Blade テンプレートを配置するだけでよいです。例えば、resources/views/components/alert.blade.php で component を定義した場合、それを次のように簡単に render できます:
<x-alert/>
componentsディレクトリ内に深くネストされた component があることを示すために.文字を使用できます。例えば、 component がresources/views/components/inputs/button.blade.phpで定義されていると仮定すると、次のように render できます。
<x-inputs.button/>
匿名インデックスコンポーネント
時々、component が多くの Blade templates で構成されている場合、特定の component のテンプレートを single ディレクトリ内にグループ化することを望むかもしれません。例えば、次のディレクトリ構造を持つ"accordion"の component を想像してみてください:
/resources/views/components/accordion.blade.php
/resources/views/components/accordion/item.blade.php
このディレクトリ構造により、 render アコーディオンの component とそのアイテムを次のように表示することができます:
<x-accordion>
<x-accordion.item>
...
</x-accordion.item>
</x-accordion>
しかし、x-accordion を介してアコーディオンの「 component 」を「 render ing」するためには、"index" アコーディオンの「 component 」テンプレートを他のアコーディオン関連テンプレートと一緒に accordion ディレクトリに配置するのではなく、resources/views/components ディレクトリに配置せざるを得ませんでした。
ありがたいことに、 Blade は index.blade.php ファイルをコンポーネントのテンプレートディレクトリ内に配置することを許可しています。index.blade.phpテンプレートが component 用に存在している場合、それは component の "root" ノードとしてレンダリングされます。したがって、上記の例で与えられた同じ Blade syntax を引き続き使用できますが、ディレクトリの構造を以下のように調整します。
/resources/views/components/accordion/index.blade.php
/resources/views/components/accordion/item.blade.php
Data プロパティ / Attributes
匿名のコンポーネントは、class が関連付けられていないため、どの data を変数として component に渡すべきか、どの attributes をコンポーネントのattribute bagに配置すべきかをどのように区別するか疑問に思うかもしれません。
あなたは@propsディレクティブを使って、どの attributes を datavariables として扱うべきか指定できます。これは、component の Blade テンプレートの頂部に配置します。その他すべての attributes は、component の attribute バッグを経由して利用可能になります。datavariables に default value を設定したい場合は、variables の名前を arraykey として、default value を array value として指定できます。
<!-- /resources/views/components/alert.blade.php -->
@props(['type' => 'info', 'message'])
<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
{{ $message }}
</div>
上記の component の定義を考慮に入れると、 component は次のように render することができます。
<x-alert type="error" :message="$message" class="mb-4"/>
親の Data へのアクセス
時々、子の component の中から親の component からの data にアクセスしたいかもしれません。そのような場合、@awareディレクティブを使用することができます。例えば、親の<x-menu>と子の<x-menu.item>から成る複雑なメニューの component を作成していると想像してみてください。
<x-menu color="purple">
<x-menu.item>...</x-menu.item>
<x-menu.item>...</x-menu.item>
</x-menu>
<x-menu> component は、次のような実装があるかもしれません:
<!-- /resources/views/components/menu/index.blade.php -->
@props(['color' => 'gray'])
<ul {{ $attributes->merge(['class' => 'bg-'.$color.'-200']) }}>
{{ $slot }}
</ul>
colorプロップは親(<x-menu>)にだけ渡されたため、<x-menu.item>内で利用することはできません。しかし、@awareディレクティブを使用すれば、<x-menu.item>内でも利用することができます:
<!-- /resources/views/components/menu/item.blade.php -->
@aware(['color' => 'gray'])
<li {{ $attributes->merge(['class' => 'text-'.$color.'-800']) }}>
{{ $slot }}
</li>
WARNING
@awareディレクティブは、親の component に HTML attributes 経由で明示的に渡されていない親の data にアクセスできません。親の component に明示的に渡されていない Default@propsvalues には、@awareディレクティブからアクセスできません。
匿名の Component パス
前述の通り、匿名のコンポーネントは通常、resources/views/componentsディレクトリ内に Blade テンプレートを配置することにより定義されます。しかし、たまに、 default path に加えて、他の匿名の component パスを Laravel に register したいこともあるかもしれません。
anonymousComponentPath method は、その最初の引数として匿名の component の場所への "path" を受け入れ、コンポーネントが配置されるべき "namespace" を option で第二引数として受け入れます。通常、この method はあなたの application の service providers の一つの boot method から呼び出されるべきです。
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Blade::anonymousComponentPath(__DIR__.'/../components');
}
上記の例のように、特定の接頭辞なしで component パスが登録されると、それらは対応する接頭辞なしで Blade コンポーネントにもレンダリングされる場合があります。例えば、panel.blade.php component が上で登録された path に存在する場合、次のようにレンダリングされるかもしれません。
<x-panel />
接頭辞「namespaces」は、anonymousComponentPath method の第二引数として提供することができます。
Blade::anonymousComponentPath(__DIR__.'/../components', 'dashboard');
プレフィックスが提供された場合、その"namespace"内の component は、component が rendering されるときに、その component の名前空間にプレフィックスを追加することで rendering される場合があります:
<x-dashboard::panel />
Building Layouts
コンポーネントを使用したレイアウト
ほとんどの web アプリケーションは、さまざまなページで同じ一般的な layout を維持しています。すべての layout HTML を私たちが作成するすべての view で繰り返さなければならない場合、私たちの application を維持するのは非常に面倒で難しいことでしょう。幸いなことに、この layout を single のBlade componentとして定義し、それを私たちの application 全体で使用することは便利です。
Layout Component の定義
例えば、 "todo"リストの application を構築していると想像してみてください。以下のように見えるlayoutの component を定義するかもしれません:
<!-- resources/views/components/layout.blade.php -->
<html>
<head>
<title>{{ $title ?? 'Todo Manager' }}</title>
</head>
<body>
<h1>Todos</h1>
<hr/>
{{ $slot }}
</body>
</html>
Layout Component の適用
layoutの component が定義されたら、その component を使用する Blade view を作成できます。この例では、タスクリストを表示するシンプルな view を定義します。
<!-- resources/views/tasks.blade.php -->
<x-layout>
@foreach ($tasks as $task)
{{ $task }}
@endforeach
</x-layout>
覚えておいてください、 content は component に注入され、 default の $slot変数に供給されます。これが私たちのlayoutの component になります。お気づきかもしれませんが、もし提供される場合、私たちのlayoutは$titleスロットも考慮します。そうでなければ、 default のタイトルが表示されます。タスクリストの view から custom のタイトルを注入することができます。これは、 component のドキュメンテーションで説明されている通常の syntax を使用します。
<!-- resources/views/tasks.blade.php -->
<x-layout>
<x-slot:title>
Custom Title
</x-slot>
@foreach ($tasks as $task)
{{ $task }}
@endforeach
</x-layout>
私たちが layout やタスクリストの views を定義したので、あとは route からtaskの view を返すだけになります。
use App\Models\Task;
Route::get('/tasks', function () {
return view('tasks', ['tasks' => Task::all()]);
});
テンプレート継承を使用したレイアウト
Layout の定義
レイアウトは「template inheritance」を通じて作成することも可能です。これはcomponentsの導入以前にアプリケーションを構築するための「 primary 」な方法でした。
始めるために、簡単な例を見てみましょう。まず、 layout と呼ばれるページを検討します。ほとんどの web アプリケーションは各種のページで一般的な layout を維持しているので、この layout を single Blade view として定義することは便利です:
<!-- 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ディレクティブは、その名前が示す通り、 content のセクションを定義します。一方、@yieldディレクティブは指定されたセクションの内容を表示するために使用されます。
私たちはすでに application のための layout を定義しました。それでは、この layout を継承する子ページを定義しましょう。
Layout を拡張する
子の view を定義する際には、@extends Blade ディレクティブを使用して、その子の view がどの layout を"継承"するべきかを指定します。 Blade layout を拡張する Views は、@section ディレクティブを使用して、レイアウトのセクションに content を挿入することができます。前述の例で見たように、これらのセクションの内容は、@yieldを使用して layout に表示されます。
<!-- 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 ディレクティブを使用して、 content をレイアウトのサイドバーに append しています(上書きするのではなく)。@@parent ディレクティブは、 view がレンダリングされるときに、 layout の content に置き換えられます。
NOTE
前の例とは異なり、この
sidebarセクションは@showではなく@endsectionで終了します。@endsectionディレクティブはセクションを定義するだけであり、@showはセクションを定義し、即座にそのセクションを使用します。
@yield ディレクティブは、二つ目のパラメータとして default default value も受け入れます。この value は、yield されているセクションが定義されていない場合に rendering されます:
@yield('content', 'Default content')
Forms
CSRF フィールド
あなたが application 内で HTML フォームを定義する際には、常にフォームに hidden CSRF token フィールドを含めるべきです。これにより、CSRF protection middleware が request を validate できます。@csrf Blade ディレクティブを使用して token フィールドを生成することができます。
<form method="POST" action="/profile">
@csrf
...
</form>
Method フィールド
PUT、PATCH、またはDELETEリクエストを HTML フォームが作成できないため、 HTTP 動詞を偽装するための hidden _methodフィールドを追加する必要があります。@method Blade ディレクティブはこのフィールドを作成してくれます。
<form action="/foo/bar" method="POST">
@method('PUT')
...
</form>
Validation Errors
@errorディレクティブは、特定の attribute に対してvalidation error messagesが存在するかどうかを素早く確認するために使用することができます。@errorディレクティブ内で、$message変数を echo することで、 error メッセージを表示することができます。
<!-- /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ディレクティブは "if" statement にコンパイルされるため、@elseディレクティブを使用して、 attribute に error がない場合に render content することができます:
<!-- /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">
複数のフォームが含まれるページ上の validation error メッセージを取得するために、@errorディレクティブの第二パラメータとして特定の 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
Stacks
Blade では、名前付き stacks にプッシュして、他の view や layout の別の場所で rendering することができます。これは、子 views に必要な JavaScriptlibraries を指定する場合に特に便利です。
@push('scripts')
<script src="/example.js"></script>
@endpush
もし特定の boolean 式がtrueに評価された場合に、 content を@pushしたい場合は、@pushIfディレクティブを使用することができます:
@pushIf($shouldPush, 'scripts')
<script src="/example.js"></script>
@endPushIf
必要な回数だけ stack にプッシュすることができます。完全な stack の内容を render するには、@stack ディレクティブに stack の名前を渡してください。
<head>
<!-- Head Contents -->
@stack('scripts')
</head>
もしあなたが stack の始まりに content を追加したい場合は、@prependディレクティブを使用するべきです:
@push('scripts')
This will be second...
@endpush
// Later...
@prepend('scripts')
This will be first...
@endprepend
Service Injection
@injectディレクティブは、 Laravel のservice containerから service を取得するために使用することができます。 @injectへ渡される最初の引数は、 service が配置される変数の名前であり、二番目の引数は解決したい service の class 名またはインターフェース名です:
@inject('metrics', 'App\Services\MetricsService')
<div>
Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>
Rendering Inline Blade Templates
時々、生の Blade テンプレート string を正当な HTML に transform する必要があるかもしれません。これは、Blade facade が提供する render method を使うことで達成できます。 render method は、 Blade テンプレート string と、テンプレートに提供するオプションの array data を受け入れます。
use Illuminate\Support\Facades\Blade;
return Blade::render('Hello, {{ $name }}', ['name' => 'Julian Bashir']);
Laravel は、storage/framework/viewsディレクトリに書き込むことで、インラインの Blade テンプレートを rendering します。 Blade テンプレートの rendering が終わった後に、これらの一時ファイルを削除したい場合は、deleteCachedView引数を method に提供できます。
return Blade::render(
'Hello, {{ $name }}',
['name' => 'Julian Bashir'],
deleteCachedView: true
);
Rendering Blade Fragments
Turbo や htmx などのフロントエンドフレームワークを使用する際に、時々、 Blade テンプレートの一部だけを HTTP response 内で返す必要があるかもしれません。 Blade "Fragments"は、まさにそれを可能にします。始めるためには、@fragment および @endfragment ディレクティブ内に Blade テンプレートの一部を配置します:
@fragment('user-list')
<ul>
@foreach ($users as $user)
<li>{{ $user->name }}</li>
@endforeach
</ul>
@endfragment
次に、このテンプレートを利用した view をレンダリングする際には、fragment method を呼び出して、指定した fragment のみが送信される HTTP response に含まれるよう指定することができます。
return view('dashboard', ['users' => $users])->fragment('user-list');
fragmentIf method は、与えられた条件に基づいて view の fragment を条件付きで返すことを可能にします。それ以外の場合、 view 全体が返されます。
return view('dashboard', ['users' => $users])
->fragmentIf($request->hasHeader('HX-Request'), 'user-list');
fragmentsとfragmentsIfメソッドは、複数の view フラグメントを response で返すことを可能にします。フラグメントは連結されます:
view('dashboard', ['users' => $users])
->fragments(['user-list', 'comment-list']);
view('dashboard', ['users' => $users])
->fragmentsIf(
$request->hasHeader('HX-Request'),
['user-list', 'comment-list']
);
Extending Blade
Blade では、directive method を使用して自分自身の custom ディレクティブを定義することができます。 Blade compiler が custom ディレクティブに遭遇すると、ディレクティブが含む表現を使って提供されたコールバックを呼び出します。
次の例は、与えられた$varをフォーマットする@datetime($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 method は指令に渡されるあらゆる表現に連鎖します。従って、この例では、この指令によって最終的に生成される PHP は以下の通りになります:
<?php echo ($var)->format('m/d/Y H:i'); ?>
WARNING
Blade ディレクティブのロジックを更新した後、すべての cache された Blade views を delete する必要があります。cache された Blade views は、
view:clearArtisan command を使用して削除できます。
Custom エコーハンドラー
echo を使って object を Blade で表示しようと attempt すると、object の__toString method が呼び出されます。__toString method は PHP の組み込み magic methods のひとつです。しかしながら、時々、特定の class の__toString method についてコントロールができない場合があります、例えば、あなたが対話している class がサードパーティの library に属している場合などです。
これらのケースでは、Blade では、特定の type の object のための custom なエコー handler を register することができます。これを達成するには、Blade の stringable method を呼び出す必要があります。stringable method はクロージャを受け入れます。このクロージャは、rendering を担当する object の type を type ヒントするべきです。典 type 的には、stringable method は、application の AppServiceProvider class の boot method の中で呼び出されるべきです:
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');
});
}
あなたの custom echo handler が定義されたら、あなたの Blade テンプレートで単純に object をエコーすることができます:
Cost: {{ $money }}
Custom If 文
custom ディレクティブをプログラミングすることは、単純な custom 条件文を定義するときに必要以上に複雑になることがあります。そのため、 Blade はBlade::if method を提供しており、これを使うとクロージャを使って custom 条件ディレクティブを素早く定義できます。例えば、 default disk が application 用に設定されているかどうかをチェックする custom 条件を定義してみましょう。これはboot method であるAppServiceProviderの中で行うことができます。
use Illuminate\Support\Facades\Blade;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Blade::if('disk', function (string $value) {
return config('filesystems.default') === $value;
});
}
一度 custom 条件が定義されると、テンプレート内でそれを使用することができます:
@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