見出し画像

Laravel 学習記録 #018 view Bladeテンプレートを試して学ぶ

LaravelのBladeテンプレートについて学習したものをまとめてます。
レイアウトの分割とBladeコンポーネントについてです。

部品の共通化を試す

・ディレクティブを使用したレイアウトの分割
・Bladeコンポーネントを使用した分割
の2パターンです。

ディレクティブを使用したレイアウトの分割

親テンプレートの作成
子テンプレートの作成
フォームを部品として作成
をやっていきます。

親テンプレートの作成
parent.blade.phpを作成します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>親テンプレート</title>
</head>
<body>
    <header>
        <h2>共通ヘッダー</h2>
    </header>

    {{-- ここにコンテンツを挿入 --}}
    @yield('content')

    <footer>
        <h2>共通フッター</h2>
    </footer>
</body>
</html>

親テンプレートにはヘッダー、フッターを用意しています。
@yieldディレクティブで挿入するセクション名を決めておきます。
今回の例では@yield('content')の位置に、子テンプレートで指定の内容が組み込まれます。

ヘッダー、フッターを外部ファイルに切り出すことも可能です。
その場合、header.blade.php、footer.blade.phpなどを作成し
組み込みしたい箇所で、@includeディレクティブを使用すればOKです。

header.blade.php

<header>
    <h2>共通ヘッダー</h2>
</header>

footer.blade.php

<footer>
    <h2>共通フッター</h2>
</footer>

parent.blade.php

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>親テンプレート</title>
</head>
<body>
    {{-- ヘッダー挿入 --}}
    @include('header')

    {{-- ここにコンテンツを挿入 --}}
    @yield('content')

    {{-- フッターー挿入 --}}
    @include('footer')
</body>
</html>


子テンプレートの作成
child.blade.phpを作成します。

{{-- 親レイアウトを継承 --}}
@extends('parent')

{{-- @yieldで指定した箇所へ組み込み --}}
@section('content')

<h2>コンテンツ</h2>

@endsection

子のテンプレートでは
@extendsディレクティブで、使用するファイルを継承します。
継承した親テンプレートの@yield('content')に組み込みを行うため
@sectionディレクティブでcontentを指定しています。

コントローラーやルートからのview呼び出しは、子のファイルを指定です。
今回はweb.phpで直接呼んでます。

Route::get('/view', function () {
    return view('child');
});


フォームを部品として作成
各画面で同じようなフォームがあるんだよなって時に、そのパーツも共通化したいので、formを例にします。すごくテキトーです。
form.blade.phpを作成

<form action="" method="post">

    <label>input</label>
    <input type="text" id="item1">

    <br>

    <label>radio</label>
    <input type="radio" name="radio" id="">
    <input type="radio" name="radio" id="">

    <br>

    <label>select</label>
    <select name="item3" id="">
        <option value="">value1</option>
        <option value="">value2</option>
        <option value="">value3</option>
    </select>

    <br>
    <input type="submit" value="送信">
</form>

これをchild.blade.phpで呼びます。

{{-- 親レイアウトを継承 --}}
@extends('parent')

{{-- @yieldで指定した箇所へ組み込み --}}
@section('content')

<h2>コンテンツ</h2>
{{-- form組み込み --}}
@include('form')

@endsection

これで、画面にはformが表示されます。
ただ、どこに組み込んでも同じformで良ければいいのですが、
valueやラベルが固定だったりでとてもじゃないが実務では使えそうではありません。実際は、画面ごとにnameが違ったり、actionも違ったり色々変えたいですよね。
なので、ここを変数を使って動的に指定できるようにします。

form.blade.php
ページごとに変更したい部分を変数にしておきます。

<form action="{{ $formAction }}" method="{{ $formMethod }}">

    <label>{{ $label1 }}</label>
    <input type="text" id="{{ $id1 }}" name="{{ $name1 }}" value="{{ $value1 ?? '' }}">

    <br>

    <label>{{ $label2 }}</label>
    <input type="radio" name="{{ $radioName }}" id="{{ $radioId1 }}">
    <input type="radio" name="{{ $radioName }}" id="{{ $radioId2 }}">

    <br>

    <label>{{ $label3 }}</label>
    <select name="{{ $selectName }}" id="{{ $selectId }}">
        <option value="{{ $optionValue1 }}">{{ $optionText1 }}</option>
        <option value="{{ $optionValue2 }}">{{ $optionText2 }}</option>
        <option value="{{ $optionValue3 }}">{{ $optionText3 }}</option>
    </select>

    <br>
    <input type="submit" value="{{ $submitText }}">

</form>


child.blade.php
@includeディレクティブの第二引数に連想配列で、変数名=>値でセットします。

{{-- 親レイアウトを継承 --}}
@extends('parent')

{{-- @yieldで指定した箇所へ組み込み --}}
@section('content')

<h2>コンテンツ</h2>
{{-- form組み込み --}}
    @include('form', [
        'formMethod' => 'post',
        'formAction' => '',

        'label1' => 'Input',
        'id1' => 'item1',
        'name1' => 'item1',
        
        'label2' => 'Radio',
        'radioName' => 'radio',
        'radioId1' => 'radio1',
        'radioId2' => 'radio2',
        
        'label3' => 'Select',
        'selectName' => 'item3',
        'selectId' => 'select1',
        'optionValue1' => 'value1',
        'optionText1' => 'Option 1',
        'optionValue2' => 'value2',
        'optionText2' => 'Option 2',
        'optionValue3' => 'value3',
        'optionText3' => 'Option 3',
        
        'submitText' => '送信',
    ])


@endsection

これで、同じformを利用しつつ
値やラベルを各画面ごとに変更することができました。

input,select,buttonなどをさらに分割した方がより使いやすいかもですね。


Bladeコンポーネントを使用した分割

同じく
親テンプレートの作成
子テンプレートの作成
フォームを部品として作成
をやっていきます。

親テンプレートの作成
bladeコンポーネントの場合は、resources/views配下にcomponentsディレクトリを作成し、その配下に配置する必要があります。

parent.blade.phpを作成します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>親テンプレート</title>
</head>
<body>
    <header>
        <h2>共通ヘッダー</h2>
    </header>

    {{-- ここにコンテンツを挿入 --}}
    {{ $slot }}

    <footer>
        <h2>共通フッター</h2>
    </footer>
</body>
</html>

{{ $slot }} とした部分にコンテンツを挿入できるようになります。


子テンプレートの作成
child.blade.phpを作成します。

<x-parent>
    <h2>コンテンツ</h2>
</x-parent>

x-ファイル名をタグとすることで、コンポーネントを呼び出せます。
このタグ内の記述がコンポーネントの$slot内に挿入されます。


フォームを部品として作成
ページごとに値を変更できるようにコンポーネントにします。
ディレクティブの確認で分割したやつと同じファイルをcomponentsディレクトリに配置します。
form.blade.php

<form action="{{ $formAction }}" method="{{ $formMethod }}">

    <label>{{ $label1 }}</label>
    <input type="text" id="{{ $id1 }}" name="{{ $name1 }}" value="{{ $value1 ?? '' }}">

    <br>

    <label>{{ $label2 }}</label>
    <input type="radio" name="{{ $radioName }}" id="{{ $radioId1 }}">
    <input type="radio" name="{{ $radioName }}" id="{{ $radioId2 }}">

    <br>

    <label>{{ $label3 }}</label>
    <select name="{{ $selectName }}" id="{{ $selectId }}">
        <option value="{{ $optionValue1 }}">{{ $optionText1 }}</option>
        <option value="{{ $optionValue2 }}">{{ $optionText2 }}</option>
        <option value="{{ $optionValue3 }}">{{ $optionText3 }}</option>
    </select>

    <br>
    <input type="submit" value="{{ $submitText }}">

</form>

child.blade.phpで呼び出します。

<x-parent>
    <h2>コンテンツ</h2>
    <x-form>
        <x-slot:formAction></x-slot>
        <x-slot:formMethod>post</x-slot>

        <x-slot:label1>Input</x-slot>
        <x-slot:id1>item1</x-slot>
        <x-slot:name1>item1</x-slot>

        <x-slot:label2>Radio</x-slot>
        <x-slot:radioName>radio</x-slot>
        <x-slot:radioId1>radio1</x-slot>
        <x-slot:radioId2>radio2</x-slot>

        <x-slot:label3>Select</x-slot>
        <x-slot:selectName>item3</x-slot>
        <x-slot:selectId>select1</x-slot>
        <x-slot:optionValue1>value1</x-slot>
        <x-slot:optionText1>Option 1</x-slot>
        <x-slot:optionValue2>value2</x-slot>
        <x-slot:optionText2>Option 2</x-slot>
        <x-slot:optionValue3>value3</x-slot>
        <x-slot:optionText3>Option 3</x-slot>

        <x-slot:submitText>送信</x-slot>
    </x-form>
</x-parent>

x-formタグでcomponents/form.blade.phpを呼び出します。
$slotの代わりの変数名に値を設定するには
<x-slot:変数名>とします。


これで、とりあえず、子のビューからコンポーネントごとに値を設定できます。
今回は確認のためにざっくりでしたが、
せっかくコンポーネントにするなら、もっと細かいパーツにして使っていきましょう。

この記事が気に入ったらサポートをしてみませんか?