💡

Laravel 新コンポーネントを使って、<form>タグ周りをすっきりさせる

2021/04/28に公開

何をしたいか

Laravel 新コンポーネント(匿名コンポーネント)を使って、form周りをすっきりさせてみます。
何がどうなるかと言うと、例えば、DELETEメソッドの場合のお決まりの

<form method="POST" action="...">
    @csrf
    @method('DELETE')

    ...
</form>

が、以下のように書けるようになります。

<x-form method="delete" action="...">
    ...
</x-form>

元ネタ(オリジナル)は、Laracastsの有料動画より。
https://laracasts.com/series/blade-component-cookbook/episodes/3
https://github.com/laracasts/Blade-Component-Examples/blob/8e2f2405ff14bfa8a7c37ea684bca9a89d8ba0f8/resources/views/components/form.blade.php

元ネタの以下の点などを改善したものになります。

  • GETの時も、_token が表示されている
  • メソッド名を大文字で書かないといけない
  • </form>の閉じ忘れ

早速作成

resources/views/components/form.blade.php のファイルを作り、以下のように記述します。

@props([
    'method' => 'POST'
])
@php
    $method = strtoupper($method);
@endphp

<form {{ $attributes->merge(['method' => $method === 'GET' ? 'GET' : 'POST']) }}>
    @if ($method !== 'GET')
        @csrf
    @endif

    @if ($method !== 'GET' && $method !== 'POST')
        @method($method)
    @endif

    {{ $slot }}
</form>

method を指定しない時は、デフォルトでPOSTとなります。(そもそも、GETの時にこのコンポーネントを使うメリットはありません)
また、メソッド名は小文字で書いても大文字に統一して出力します。

以下、呼出例と出力結果です。
(実際の出力は、インデントや改行等はこの通りになりませんが、見やすく整形しています)

呼出例

<x-form>
    指定無し(デフォルトPOST</x-form>

<x-form method="GET">
    GETで指定
</x-form>

<x-form method="POST">
    POSTで指定
</x-form>

<x-form method="DELETE">
    DELETEで指定
</x-form>

<x-form method="delete">
    deleteを小文字で指定
</x-form>

<x-form method="POST" action="/photos">
    POSTで指定、action付き
</x-form>

出力結果

<form method="POST">
    <input type="hidden" name="_token" value="n1ynoGZAiy8z1WEjzXNPVZqUPu0w56D8UvaIMFNH">    

    指定無し(デフォルトPOST</form>

<form method="GET">

    GETで指定
</form>

<form method="POST">
    <input type="hidden" name="_token" value="n1ynoGZAiy8z1WEjzXNPVZqUPu0w56D8UvaIMFNH">    

    POSTで指定
</form>

<form method="POST">
    <input type="hidden" name="_token" value="n1ynoGZAiy8z1WEjzXNPVZqUPu0w56D8UvaIMFNH">    
    <input type="hidden" name="_method" value="DELETE">    

    DELETEで指定
</form>

<form method="POST">
    <input type="hidden" name="_token" value="n1ynoGZAiy8z1WEjzXNPVZqUPu0w56D8UvaIMFNH">    
    <input type="hidden" name="_method" value="DELETE">    

    deleteを小文字で指定
</form>

<form method="POST" action="/photos">
    <input type="hidden" name="_token" value="n1ynoGZAiy8z1WEjzXNPVZqUPu0w56D8UvaIMFNH">    

    POSTで指定、action付き
</form>

結論

小技ではありますが、<form>タグ周りが少しすっきりしました。
ありがとう、匿名コンポーネント!

(実際の出力結果はインデント等乱れますが、そこは目をつむる事にします…)

Discussion