【Laravel】掲示板を作成する(3)一覧画面、詳細画面の作成
Laravelによる掲示板の作成、第3回です。
今回は「一覧画面の作成」と「詳細画面の作成」についてポストしたいと思います。
(第1回)1.各種設定
(第1回)2.マイグレーションでDBを作成する
(第2回)3.Eloquent機能を使いモデルのリレーションを設定する
(第2回)4.LaravelのSeed機能とFakerを使ってDBにテストデータを登録する
(今回)5.一覧画面の作成
(今回)6.詳細画面の作成
5.一覧画面の作成
まずは一覧画面を作成します。
コントローラーの作成
以下のコマンドを発行して、コントローラーファイルを生成します。
実行すると app\Http\Controllers\PostsController.php
が作成されます。
1 |
$ php artisan make:controller PostsController |
ルーティングの設定
編集ファイル:routes\web.php
開発版の接続先URLは http://localhost:8000/bbs/ となるよう設定。
1 2 |
# 追記 Route::get('bbs', 'PostsController@index'); |
Postsコントローラーを編集
編集ファイル:app\Http\Controllers\PostsController.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Post; // ←★忘れず追記 class PostsController extends Controller { public function index() { $posts = Post::orderBy('created_at', 'desc')->get(); return view('bbs.index', ['posts' => $posts]); } } |
投稿を作成日時の降順で取得し index.blade にデータを渡してビューを生成する内容です。
Laravelのローカルサーバーを起動するのを忘れずに。
1 |
$ php artisan serve |
ビューの作成
以前作成した「star」ページ用のレイアウトファイルをコピーして bbslayout.blade.php
を作成。Bootstrapを使えるようヘッダにCDNのリンクを記述します。
各ビューファイルは以下の様に設置作成します。
resources/views/layout/bbslayout.blade.php
# ヘッダ、フッター
resources/views/layout/bbsheader.blade.php
resources/views/layout/bbsfooter.blade.php
# 一覧用
resources/views/bbs/index.blade.php
レイアウト
編集ファイル:resources/views/layout/bbslayout.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<DOCTYPE HTML> <html lang="ja"> <head> <meta charset="UTF-8"> <title>@yield('title')|magicmissile.info</title> <meta name="description" itemprop="description" content="@yield('description')"> <meta name="keywords" itemprop="keywords" content="@yield('keywords')"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script> <!-- Custom styles for this template --> <link href="/css/bbs/sticky-footer.css" rel="stylesheet"> @yield('pageCss') </head> <body> @yield('header') <div class="container"> @yield('content') </div><!--//container--> @yield('footer') </body> </html> |
ヘッダ
編集ファイル:resources/views/layout/bbsheader.blade.php
1 2 3 4 5 6 7 |
@section('header') <header class="navbar navbar-dark bg-dark"> <div class="container"> <a class="navbar-brand" href="{{ url('/bbs/') }}">LaravelPjt BBS</a> </div> </header> @endsection |
フッタ
編集ファイル:resources/views/layout/bbsfooter.blade.php
1 2 3 4 5 6 7 |
@section('footer') <footer class="footer"> <div class="container"> <p class="text-center text-muted">LaravelPjt BBS System by toogie.</p> </div> </footer> @endsection |
フッタ用CSSを作成
編集ファイル:public\css\bbs\sticky-footer.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/* Sticky footer styles -------------------------------------------------- */ html { position: relative; min-height: 100%; } body { /* Margin bottom by footer height */ margin-bottom: 100px; } .footer { position: absolute; bottom: 0; width: 100%; /* Set the fixed height of the footer here */ height: 60px; background-color: #cdcdcd; } /* Custom page CSS -------------------------------------------------- */ .container .text-muted { margin: 20px 0; } |
一覧画面
編集ファイル:resources/views/bbs/index.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
@extends('layout.bbslayout') @section('title', 'LaravelPjt BBS 投稿の一覧ページ') @section('keywords', 'キーワード1,キーワード2,キーワード3') @section('description', '投稿一覧ページの説明文') @section('pageCss') <link href="/css/bbs/style.css" rel="stylesheet"> @endsection @include('layout.bbsheader') @section('content') <div class="table-responsive"> <table class="table table-hover"> <thead> <tr> <th>ID</th> <th>カテゴリ</th> <th>作成日時</th> <th>名前</th> <th>件名</th> <th>メッセージ</th> <th>処理</th> </tr> </thead> <tbody id="tbl"> @foreach ($posts as $post) <tr> <td>{{ $post->id }}</td> <td>{{ $post->category->name }}</td> <td>{{ $post->created_at->format('Y.m.d') }}</td> <td>{{ $post->name }}</td> <td>{{ $post->subject }}</td> <td>{!! nl2br(e(Str::limit($post->message, 100))) !!} @if ($post->comments->count() >= 1) <p><span class="badge badge-primary">コメント:{{ $post->comments->count() }}件</span></p> @endif </td> <td class="text-nowrap"> <p><a href="" class="btn btn-primary btn-sm">詳細</a></p> <p><a href="" class="btn btn-info btn-sm">編集</a></p> <p><a href="" class="btn btn-danger btn-sm">削除</a></p> </td> </tr> @endforeach </tbody> </table> </div> @endsection @include('layout.bbsfooter') |
foreachでデータをぐるぐる回すのが基本形。
$post->***
の形式で、表示させたい項目を指定します。
「カテゴリ」はモデルにてリレーション設定が行われているので、{{ $post->category->name }}
で取得(表示)可能です。
メッセージは改行に対応しつつ80文字で省略されるようにしており、コメント数は{{ $post->comments->count() }}
で取得できるようです。
このあたりの関数の仕様一覧が見たいところ。
一覧画面キャプチャ
ここまでの内容を実行させると、以下のように50件全件を表示しています。
Bootstrapを使用しているので、レスポンシブに対応。相変わらずボタンの色が少々やかましいのがそれっぽいですね。
掲示板というか管理画面感がありすぎたので、あとで『KENT-WEB』風を目指してみることにしますが、ひとまずはこのまま進めることとします。
6.詳細画面の作成
では次に投稿の「詳細画面」を実装します。
ルーティングの追加
routes/web.php
を開き、showメソッドにルーティングが通るよう設定します。
1 |
Route::resource('bbs', 'PostsController', ['only' => ['index', 'show']]); |
get
ではなく resource
を使うこととします。
第三引数に only を使うと、ホワイトリストとしてメソッドを指定できます。
Route::resourceについては以下を参照。
https://qiita.com/sympe/items/9297f41d5f7a9d91aa11
Postsコントローラーを編集
showアクションを作成します。
編集ファイル:app\Http\Controllers\PostsController.php
1 2 3 4 5 6 7 8 9 10 11 |
/** * 詳細 */ public function show(Request $request, $id) { $post = Post::findOrFail($id); return view('bbs.show', [ 'post' => $post, ]); } |
詳細画面ビューの作成
編集ファイル:resources\views\bbs\show.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
@extends('layout.bbslayout') @section('title', 'LaravelPjt BBS 投稿の詳細ページ') @section('keywords', 'キーワード1,キーワード2,キーワード3') @section('description', '投稿詳細ページの説明文') @section('pageCss') <link href="/css/bbs/style.css" rel="stylesheet"> @endsection @include('layout.bbsheader') @section('content') <div class="container mt-4"> <div class="border p-4"> <!-- 件名 --> <h1 class="h4 mb-4"> {{ $post->subject }} </h1> <!-- 投稿情報 --> <div class="summary"> <p><span>{{ $post->name }}</span> / <time>{{ $post->updated_at->format('Y.m.d H:i') }}</time> / {{ $post->category->name }} / {{ $post->id }}</p> </div> <!-- 本文 --> <p class="mb-5"> {!! nl2br(e($post->message)) !!} </p> <section> <h2 class="h5 mb-4"> コメント </h2> @forelse($post->comments as $comment) <div class="border-top p-4"> <time class="text-secondary"> {{ $comment->name }} / {{ $comment->created_at->format('Y.m.d H:i') }} / {{ $comment->id }} </time> <p class="mt-2"> {!! nl2br(e($comment->comment)) !!} </p> </div> @empty <p>コメントはまだありません。</p> @endforelse </section> </div> </div> @endsection @include('layout.bbsfooter') |
一覧画面の「詳細ボタン(リンク)」を編集
1 |
<p><a href="{{ action('PostsController@show', $post->id) }}" class="btn btn-primary btn-sm">詳細</a></p> |
これで、http://127.0.0.1:8000/bbs/1 というようなURLで詳細が開きます。(なんだか気持ち悪いですねw)
リンク作成に関しては下記URLを参照。
https://qiita.com/hththt/items/38906ba3f46ead6bba25
詳細ページキャプチャ
一覧ページにページ送り(ページネーション)を追加
現状の投稿一覧だと投稿が増えていくとスクロールが若干大変なので、ページ送りをつけてみます。
PostsController
のindex
メソッド内にて、投稿リストを取得する処理を以下のように変更します。
1 2 3 4 5 |
$posts = Post::orderBy('created_at', 'desc')->get(); ↓↓↓↓↓ 以下に変更 ↓↓↓↓↓ $posts = Post::orderBy('created_at', 'desc')->paginate(10); |
次に一覧画面用のビューの任意の位置(今回は投稿リストの下の方)にページ送り用のブロックを追記。
編集ファイル: resources/views/posts/index.blade.php
1 2 3 |
<div class="d-flex justify-content-center mb-5"> {{ $posts->links() }} </div> |
ページングされた一覧画面のキャプチャ
恐ろしく簡単にページ送りが出来てしまった。。。
CakePHPではなかなか苦労したところなんですけどねぇ。Laravel恐るべし。
というところで第3回目はここまでとします。
次回は投稿作成とコメント投稿についての予定です。