ここまでの作業でコメントの一覧表示や個別表示,投稿,編集などの基本的な機能が完成しました.各機能のビュー(index.blade.php や show.blade.php)の内容はその多くが共通しています.特にページのデザインなどに関する部分をレイアウト化(テンプレート化)しておくと,システム全体でビューのデザインを変更したいときに1つのファイルを編集するだけでできるようになります.これからの作業は小さなシステムの開発時には必要性は感じられないかもしれません.若干面倒な作業になるかもしれませんが,規模の大きなシステムを開発するときには開発の初期段階でレイアウト化を行なっておくと後々にその有り難みを感じられることでしょう.
まず,resources/view/layouts ディレクトリを作成します.これまでに作成した index.blade.php や show.blade.php などのファイル群で共通する部分を定義したレイアウトファイル default.blade.php を作成したディレクトリに設置します.通常のHTMLファイルの雛形と異なる部分は5行目と9行目の @
で始まる部分だけです.この default.blade.php が共通のレイアウトを定義した親のビューという位置付けになります.
resources/views/layouts/default.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>@yield('title')</title>
</head>
<body>
<div class="container">
@yield('content')
</div>
</body>
</html>
続いて今作成した共通レイアウトの親ビューを使用するように resources/views/comments/index.blade.php を修正します.1行目の @extends('layouts.default')
によって,layouts ディレクトリに設置された default.blade.php がレイアウトとして使用されます.3行目の @section('title', 'コメントの一覧')
によって,title
セクションが定義され,title セクションの内容 コメントの一覧
が共通レイアウトの @yield('title')
の部分に埋め込まれます.また,5行目から41行目が content
セクションとして定義されたので,共通レイアウトの9行目にある @yield('content')
の部分に埋め込まれることになります.なお,content
セクションの内容は以前の index.blade.php の <body> 〜 </body>
内部のコードをそのままコピーするだけで構いません.
resources/views/comments/index.blade.php
@extends('layouts.default')
@section('title', 'コメントの一覧')
@section('content')
<h1>コメント一覧</h1>
<ul>
@foreach ($comments as $comment)
<li>
<a href="{{ route('comments.show', ['comment_id' => $comment->id]) }}">
{{ $comment->title }}
</a>
</li>
@endforeach
</ul>
<h1>コメント投稿</h1>
<div>
<form method="post" action="{{ route('comments.store') }}">
@csrf
<p>
<label for="title">Title: </label>
<input type="text" name="title" id="title" value="{{ old('title') }}">
@if ($errors->has('title'))
<span class="error">{{ $errors->first('title') }}</span>
@endif
</p>
<p>
<label for="body">Body: </label>
<textarea name="body" id="body" rows="4" cols="50">{{ old('body') }}</textarea>
@if ($errors->has('body'))
<span class="error">{{ $errors->first('body') }}</span>
@endif
</p>
<p>
<input type="submit" value="投稿">
</p>
</form>
</div>
@endsection
折角なので,show.blade.php と edit.blade.php もレイアウト化しておきます.
resources/views/comments/show.blade.php
@extends('layouts.default')
@section('title', 'コメント')
@section('content')
<h1>コメント</h1>
<dl>
<dt>ID:</dt>
<dd>{{ $comment->id }}</dd>
<dt>Title:</dt>
<dd>{{ $comment->title }}</dd>
<dt>Body:</dt>
<dd>{{ $comment->body }}</dd>
</dl>
<p>
<a href="{{ route('comments.edit', ['comment_id' => $comment->id]) }}">
[編集]
</a>
</p>
<div>
<form action="{{ route('comments.destroy', ['comment_id' => $comment->id]) }}" method="post">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">コメントの削除</button>
</form>
</div>
@endsection
resources/views/comments/edit.blade.php
@extends('layouts.default')
@section('title', 'コメント編集')
@section('content')
<h1>コメント編集</h1>
<div>
<form method="post" action="{{ route('comments.update') }}" enctype='multipart/form-data'>
@csrf
@method('PATCH')
<input type="hidden" name="comment_id" value="{{ $comment->id }}">
<p>
<label for="title">Title: </label>
<input type="text" name="title" id="title" value="{{ $comment->title }}{{ old('title') }}">
@if ($errors->has('title'))
<span class="error">{{ $errors->first('title') }}</span>
@endif
</p>
<p>
<label for="body">Body: </label>
<textarea name="body" id="body" rows="4" cols="50">{{ $comment->body }}{{ old('body') }}</textarea>
@if ($errors->has('body'))
<span class="error">{{ $errors->first('body') }}</span>
@endif
</p>
<p>
<input type="submit" value="更新">
</p>
</form>
</div>
@endsection
大幅な修正を施したので,自動テストを実行して正しく表示できるかも確認しておくと良いでしょう.
vagrant@ubuntu2204 comment_app $ history | grep test ⏎ 183 ls tests/ 184 ls tests/Feature/ 185 ls tests/Unit/ 186 php artisan make:test CommentsControllerTest 187 ls tests/Feature/ 188 php artisan make:test CommentsControllerTest --unit 189 ls tests/Unit/ 190 git add tests/Feature/CommentsControllerTest.php 191 git commit -m'php artisan make:test CommentsControllerTest' 194 git commit -m'php artisan make:test CommentsControllerTest --unit' 196 php artisan test tests/Feature/ExampleTest.php 197 php artisan test 202 php artisan test --coverage-html /var/www/html/cv_reports/comment_app 219 history | grep test 220 php artisan test --coverage-html /var/www/html/cv_reports/comment_app 222 git add tests/* 224 git commit -m'test' 229 php artisan test --coverage-html /var/www/html/cv_reports/comment_app 231 php artisan test --coverage-html /var/www/html/cv_reports/comment_app 236 php artisan test --coverage-html /var/www/html/cv_reports/comment_app 237 php artisan test 239 php artisan test --coverage-html /var/www/html/cv_reports/comment_app 241 php artisan test --coverage-html /var/www/html/cv_reports/comment_app 243 php artisan test --coverage-html /var/www/html/cv_reports/comment_app 244 history | grep test vagrant@ubuntu2204 comment_app $ !243 ⏎ php artisan test --coverage-html /var/www/html/cv_reports/comment_app PASS Tests\Unit\CommentsControllerTest ✓ example 0.03s PASS Tests\Unit\ExampleTest ✓ that true is true 0.01s PASS Tests\Feature\CommentsControllerTest ✓ comments index 0.25s ✓ comments show 3 0.03s ✓ comments edit 3 0.03s PASS Tests\Feature\ExampleTest ✓ the application returns a successful response 0.04s ✓ the application returns a 404 error response 0.03s Tests: 7 passed (7 assertions) Duration: 0.49s vagrant@ubuntu2204 comment_app $