Laravel 8.45 の Blade::stringable(Custom Echo Handlers)を試す
はじめに
(追記)リリース当初の 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