🖇️

Laravel 8.45 の Blade::stringable(Custom Echo Handlers)を試す

2021/06/04に公開約1,800字

はじめに

(追記)リリース当初の 8.45.x には、この機能にバグがあります。必ず8.46以降を使って下さい。

Laravel 8.45 で追加された Custom Echo Handlers という機能を試してみました。
これを使うと何がいいかと言うと、例えば、何かの登録日を Blade で出力する際、日付のみで時間までは出力したくない時とかはフォーマットをして、

{{ $user->created_at->format('Y.m.d') }}

みたいにやっていた所が、予め表示設定をしておくと、

{{ $user->created_at }}

だけで済むという感じになります。

上記は、Carbon を使った例ですが、言い換えると、とあるクラスの __toString() メソッドを上書きできない場合、代わりに Blade の機能を使って、どのように文字列として出力させるかを設定できる、という感じになります。

参考:本家ドキュメント
参考:GitHub [8.x] Adds class handling for Blade echo statements #37478

設定方法

AppServiceProvider の boot 内とかで、以下のようにやります。

use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Blade;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Blade::stringable(function (Carbon $object) {
            return $object->format('Y.m.d');
        });

        // PHP7.4以降であれば、アロー関数(矢印関数)を使ってシンプルに書ける
        // Blade::stringable(fn(Carbon $object) => $object->format('Y.m.d'));
    }

Blade::stringable に指定するクロージャーが受け取る引数には、タイプヒントをしてやります。これでOKです。
((注)「Carbon\Carbon」ではなく、「Illuminate\Support\Carbon」の方をインポートしています)

注意事項や制限事項は?

以下、思い付く注意事項等です。

(1)(例によって?)キャッシュに気をつけましょう

一度画面を表示して Blade のキャッシュが出来た後に、Blade::stringable を仕掛けても、キャッシュがある為反映されません。
ですので、その場合は、Blade のキャッシュをクリアして下さい。

(2) 出力する時は、単発で出力する事

つまりこういう事です。

{{ $user->created_at }}
{{ $user->created_at . 'です' }}

上の出力は期待通り、「2021.06.04」のように出力されますが、
下は、「2021-06-04 14:03:21です」のように出力されます。
Laravel の機能が使われる前に、Carbon の __toString() が使われて、文字列結合されてしまうからです。

(3) 他

Carbon の場合は、元の Carbon\Carbon とそれを継承した Illuminate\Support\Carbon がありますので、やや注意しましょう。

また、言うまでも無いかも知れませんが、Blade::stringable というだけあって、Bladeで出力する時に適用されます。

雑感

ちょっと嬉しい機能ですね。

間違い等ありましたらコメント下さい。

Discussion

ログインするとコメントできます