こんにちは!
PHPのLaravelやJavaScriptでWeb開発をしているフリラーンスエンジニアのファドと申します!
こちらの記事は応用Laravel教材の第2回目の記事になります。
その他の応用Laravel教材を学習したい方は下記リンクから直接教材へ飛ぶことができます。
-
応用Laravel
【応用Laravel教材①】タスク管理アプリを実装してLaravelをより深く知る!〜環境構築からログイン機能実装編〜
-
応用Laravel
【応用Laravel教材③】Laravelでタスク管理アプリ実装!〜プロジェクト一覧機能実装からログイン後のリダイレクト先変更編〜
-
応用Laravel
【応用Laravel教材④】Laravelでタスク管理アプリ実装!〜タスク一覧機能実装編〜
-
応用Laravel
【応用Laravel教材⑤】Laravelでタスク管理アプリ実装!〜プロジェクト追加機能実装からタスク追加機能実装編〜
-
応用Laravel
【応用Laravel教材⑥】Laravelでタスク管理アプリ実装!〜タスク編集機能実装編〜
各種テンプレート作成
次はビューの元になる見た目のテンプレートを作成してきましょう。
テンプレート作成
ターミナルで下記コマンドをtask-app
ディレクトリ上で実行してください。
$ touch resources/views/layouts/layout.blade.php
task-app/resources/views/layouts
ディレクトリにlayout.blade.php
が作成されるので、下記の通り編集してください。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>@yield('title', 'タスク管理')</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css" integrity="sha384-r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I" crossorigin="anonymous">
<!-- CSS -->
<link rel="stylesheet" href="{{ asset('css/style.css') }}">
</head>
<body>
<!-- ヘッダー -->
@include('layouts.header')
<!-- コンテンツ -->
<main>
@yield('content')
</main>
<!-- フッター -->
@include('layouts.footer')
<!-- Bootstrap -->
<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/5.0.0-alpha1/js/bootstrap.min.js" integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin="anonymous"></script>
</body>
</html>
Laravel教材の時と同じように、簡単あに見た目を整えるためにBootstrapをCDNで使用しています。
また、後ほど作成するCSSを読み込むための<link rel="stylesheet" href="{{ asset('css/style.css') }}">
という記述もしています。
こちらについては、CSS導入時に説明します。
タイトルやヘッダー、コンテンツ、フッターなどは@yield
や@include
を使用しているので、この後作成していきます。
ヘッダー作成
次に共通ヘッダーを作成します。
ターミナルで下記コマンドをtask-app
ディレクトリ上で実行してください。
$ touch resources/views/layouts/header.blade.php
task-app/resources/views/layouts
ディレクトリにheader.blade.php
が作成されるので、下記の通り編集してください。
<header>
<nav class="navbar navbar-expand-lg navbar-dark" style="background-color: #1f1f1f;">
<div class="container-fluid">
<a class="navbar-brand" href="#">タスク管理</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarNavAltMarkup">
<div class="navbar-nav">
@auth
<a class="mr-lg-3 my-lg-0 my-3 btn btn-sm btn-dark text-light nav-item nav-link" href="#">ユーザーA</a>
<form action="{{ route('logout') }}" method="POST">
@csrf
<button class="btn btn-sm btn-danger text-light nav-item nav-link w-100">ログアウト</button>
</form>
@else
<a class="mr-lg-3 my-lg-0 my-3 btn btn-sm btn-dark text-light nav-item nav-link" href="{{ route('login') }}">ログイン</a>
<a class="btn btn-sm btn-primary text-light nav-item nav-link" href="{{ route('register') }}">新規登録</a>
@endauth
</div>
</div>
</div>
</nav>
</header>
ヘッダーには必ず左上にアプリ名であるタスク管理
というリンクを設定しておきます。
また、右上には未ログインユーザーかログインユーザーかで出し分けるボタンを設置します。
未ログインの場合はログインボタン
と新規登録ボタン
を右上に表示します。
一方でログイン済みの場合はユーザー名
とログアウトボタン
を表示します。
Bladeテンプレートでは@auth
と記述することでログイン済みの時の処理を記述することができます。
@authで囲まれている部分は下記のようにユーザー名
とログアウトボタン
を記述しています。
@auth
<a class="mr-lg-3 my-lg-0 my-3 btn btn-sm btn-dark text-light nav-item nav-link" href="#">ユーザーA</a>
<form action="{{ route('logout') }}" method="POST">
@csrf
<button class="btn btn-sm btn-danger text-light nav-item nav-link w-100">ログアウト</button>
</form>
@else
ログアウトボタン
はPOST送信のためform要素
として処理しています。
formを使用する際は@csrf
を忘れないようにしましょう。
また、action属性
の属性値に{{ route('logout') }}
と記述されていますが、これはLaravel Breezeで導入した場合のログアウト用のルート名がlogout
だからです。
ちなみにLaravelでは現在設定されているルートをコマンドで確認することができます。
ターミナルで下記コマンドをtask-app
ディレクトリ上で実行してください。
$ ./vendor/bin/sail php artisan route:list
コマンドを実行すると下記のような実行結果が表示されます。
GET|HEAD / ............................................................................................................
POST _ignition/execute-solution ..... ignition.executeSolution › Spatie\LaravelIgnition › ExecuteSolutionController
GET|HEAD _ignition/health-check ................. ignition.healthCheck › Spatie\LaravelIgnition › HealthCheckController
POST _ignition/update-config .............. ignition.updateConfig › Spatie\LaravelIgnition › UpdateConfigController
GET|HEAD api/user .....................................................................................................
GET|HEAD confirm-password .................................. password.confirm › Auth\ConfirmablePasswordController@show
POST confirm-password .................................................... Auth\ConfirmablePasswordController@store
GET|HEAD dashboard .......................................................................................... dashboard
POST email/verification-notification ....... verification.send › Auth\EmailVerificationNotificationController@store
GET|HEAD forgot-password ................................... password.request › Auth\PasswordResetLinkController@create
POST forgot-password ...................................... password.email › Auth\PasswordResetLinkController@store
GET|HEAD login ..................................................... login › Auth\AuthenticatedSessionController@create
POST login .............................................................. Auth\AuthenticatedSessionController@store
POST logout .................................................. logout › Auth\AuthenticatedSessionController@destroy
GET|HEAD register ..................................................... register › Auth\RegisteredUserController@create
POST register ................................................................. Auth\RegisteredUserController@store
POST reset-password ............................................ password.update › Auth\NewPasswordController@store
GET|HEAD reset-password/{token} .................................... password.reset › Auth\NewPasswordController@create
GET|HEAD sanctum/csrf-cookie .............................................. Laravel\Sanctum › CsrfCookieController@show
GET|HEAD verify-email ........................... verification.notice › Auth\EmailVerificationPromptController@__invoke
GET|HEAD verify-email/{id}/{hash} ........................... verification.verify › Auth\VerifyEmailController@__invoke
これが現在ルーティングされているルート一覧です。
ログアウトに関するルーティングは下記の通りです。
POST logout .................................................. logout › Auth\AuthenticatedSessionController@destroy
この一文を読み解くと、POST通信でhttp://localhost//logout
というURLにアクセスでき、ルート名はlogout
で、アクセスがあるとAuth\AuthenticatedSessionController
というコントローラーのdestroyメソッド
が実行されるということです。
また、実行結果をよく見るとregister
やlogin
といった新規登録とログインのルーティングもされていることがわかります。
それらのルート名を使用して、未ログイン時の2つのボタンも作成することができます。
未ログイン時の記述は@else
以下の処理です。
@else
<a class="mr-lg-3 my-lg-0 my-3 btn btn-sm btn-dark text-light nav-item nav-link" href="{{ route('login') }}">ログイン</a>
<a class="btn btn-sm btn-primary text-light nav-item nav-link" href="{{ route('register') }}">新規登録</a>
@endauth
ログイン用のルート名はlogin
なので、{{ route('login') }}
となります。
また、新規登録用のルート名はregister
なので{{ route('register') }}
となります。
フッター作成
次に共通フッターを作成します。
ターミナルで下記コマンドをtask-app
ディレクトリ上で実行してください。
$ touch resources/views/layouts/footer.blade.php
task-app/resources/views/layouts
ディレクトリにfooter.blade.php
が作成されるので、下記の通り編集してください。
<footer class="footer fixed-bottom" style="background-color: #1f1f1f;">
<div class="container text-center">
<span class="text-light">©︎Laravel応用教材</span>
</div>
</footer>
フッターは特に難しいことはしていません。
トップページ作成
次にテンプレートが完成したのでトップページを作成していきましょう。
http://localhost/へアクセスされた場合に表示されるwelcome.blade.php
を変更していきましょう。
task-app/resources/views/welcome.blade.php
を下記の通り編集してください。
@extends('layouts.layout')
@section('title')
タスク管理
@endsection
@section('content')
<div class="top-page d-flex flex-column justify-content-center align-items-center ">
<div class="h1 text-center">
<h1 class="text-light">タスク管理</h1>
<h2 class="text-light">いつでもどこでも簡単に♪</h2>
</div>
<div class="d-flex">
@auth
<a href="#" class="btn btn-success">プロジェクト一覧</a>
@else
<a href="{{ route('register') }}" class="btn btn-success">まずは無料で登録する</a>
@endauth
</div>
</div>
@endsection
ヘッダーと同じように@auth
を使用して、ログイン時と未ログインの時のボタン出し分けを行っています。
ログイン時はプロジェクト一覧へ遷移できるボタンを表示し、未ログインの時は新規登録画面へ遷移するためのボタンを表示するようにしています。
次に、独自のCSSで背景などを指定したいので、CSSファイルを作成します。
LaravelでCSSを使用するにはいくつか方法がありますが、まずは一番簡単に実装できる方法で実装します。
task-app/public
ディレクトリにcss
フォルダを作成し、その中にstyle.css
を作成してください。
コマンドでもVSCode上で作成してもどちらでもOKです。
コマンドで作成する場合は、ターミナルで下記コマンドをtask-app
ディレクトリ上で実行してください。
$ mkdir public/css && touch public/css/style.css
作成したtask-app/public/css/style.css
を下記の通り編集してください。
.top-page {
background-image: url('../images/test.jpg');
background-color:rgba(0, 0, 0, .6);
background-blend-mode:darken;
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed;
min-height: calc(100vh - 80px);
}
CSSで背景に画像を指定していますが、画像がまだないので写真を用意して設定していきます。
皆さんが持っている画像でも大丈夫ですが、https://unsplash.com/photos/cckf4TsHAuwからダウンロードしていただいてもOKです。
※画像URLが開けない場合はこちらから好きな写真を選んでダウンロードしてください。
Laravelで画像を表示させるためにtask-app/public
ディレクトリにimages
フォルダを作成します。
さっそくpublic
ディレクトリにimages
フォルダを作成しましょう。
コマンドでもVSCode上で作成してもどちらでもOKです。
コマンドで作成する場合は、ターミナルで下記コマンドをtask-app
ディレクトリ上で実行してください。
$ mkdir public/images
作成したtask-app/public/images
ディレクトリに画像を入れてください。
画像の名前はCSSで指定した通り、test.jpg
としています。
これでトップページを表示することができるようになりました。
http://localhost/にアクセスして、下記画像のようになっていればOKです!
認証画面編集
次に、新規登録画面やログイン画面の見た目を変更していきましょう。
Laravel Breezeで認証機能を実装した場合、自動的にtask-app/resources/views
ディレクトリにauth
ディレクトリが作成され、その中に認証用のBladeファイル
がいくつか作成されています。
新規登録画面
まず、新規登録画面はtask-app/resources/views/auth/register.blade.php
を変更することで、オリジナルの新規登録画面を作成することができます。
register.blade.php
を下記の通り編集してください。
@extends('layouts.layout')
@section('title')
新規登録
@endsection
@section('content')
<div class="container mt-4">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header text-center">新規登録</div>
<div class="card-body">
<form method="POST" action="{{ route('register') }}">
@csrf
<div class="form-group d-flex flex-column flex-md-row">
<label for="name" class="col-md-4 col-form-label text-md-right">ユーザー名:</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group d-flex flex-column flex-md-row mt-3">
<label for="email" class="col-md-4 col-form-label text-md-right">メールアドレス:</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group d-flex flex-column flex-md-row mt-3">
<label for="password" class="col-md-4 col-form-label text-md-right">パスワード:</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group d-flex flex-column flex-md-row mt-3">
<label for="password_confirmation" class="col-md-4 col-form-label text-md-right">パスワード確認:</label>
<div class="col-md-6">
<input id="password_confirmation" type="password" class="form-control @error('password_confirmation') is-invalid @enderror" name="password_confirmation" required autocomplete="new-password">
@error('password_confirmation')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group d-flex mt-3 mb-0">
<div class="col-md-10 col-12 d-flex justify-content-end">
<button type="submit" class="btn btn-primary">登録</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
編集が完了したら、http://localhost/registerへアクセスし、下記の通り画面が表示されればOKです。
それでは実装内容について2つのポイントを説明します。
まず1つ目は、formでPOST送信をしているということです。action属性
にはroute('register')
を記述していますが、これは以前ルーティング一覧をコマンドで確認した時に新規登録用のルート名がregister
であったためです。
念の為、もう一度ルーティング一覧を確認できるコマンドを復習しておきましょう。
$ ./vendor/bin/sail php artisan route:list
心配な方はもう一度新規登録のルート名がregister
なのか確認しておくと良いでしょう。
2つ目にパスワード一致のバリデーション機能についてです。
Laravelでは、confirmedルール
というバリデーションルールが実装されています。
このルールはname属性がある属性値(仮にpassword
とします)の入力値とある属性値+confirmation
という属性値(今回の場合はpassword_confirmation
)の入力値が一致することを検証します。
よく使う場面として、パスワードを入力させた後に確認としてもう一度パスワードを入力させる時のバリデーションとして使用します。
今回もパスワードの確認用inputにはpassword_confirmation
というname属性
にしています。
ログイン画面
次にログイン画面の編集を行っていきます。
ログイン画面はtask-app/resources/views/auth/login.blade.php
を変更することで、オリジナルのログイン画面を作成することができます。
login.blade.php
を下記の通り編集してください。
@extends('layouts.layout')
@section('title')
ログイン
@endsection
@section('content')
<div class="container mt-4">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header text-center">ログイン</div>
<div class="card-body">
<form method="POST" action="{{ route('login') }}">
@csrf
<div class="form-group d-flex flex-column flex-md-row">
<label for="email" class="col-md-4 col-form-label text-md-right">メールアドレス:</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group d-flex flex-column flex-md-row mt-3">
<label for="password" class="col-md-4 col-form-label text-md-right">パスワード:</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group d-flex mt-3 mb-0">
<div class="col-md-10 col-12 d-flex justify-content-end">
<button type="submit" class="btn btn-primary">ログイン</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
編集が完了したら、http://localhost/loginへアクセスし、下記の通り画面が表示されればOKです。
ログイン画面は特に難しいことはありません。
新規登録画面と同じようにformでPOST送信をしています。
action属性
にはroute('login')
を記述していますが、Laravel Breezeで認証機能を実装した場合のログインのルート名がlogin
だからです。
もちろん$ ./vendor/bin/sail php artisan route:list
で確認できます。
バリデーションメッセージの日本語化
これで新規登録とログイン機能は完成しましたが、新規登録時のバリデーションメッセージの一部が下記画像の通り、日本語化されていないので設定していきます。
ちなみに、新規登録機能のコントローラーはtask-app/app/Http/Controllers/Auth/RegisterdUserController.php
です。
ユーザー情報登録用のメソッドstore
は下記のようになっています。
/**
* Handle an incoming registration request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request)
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
event(new Registered($user));
Auth::login($user);
return redirect(RouteServiceProvider::HOME);
}
バリデーションに関するコードは$request->validate()
で囲まれた部分です。
記述方法はフォームリクエストで指定した方法と同じです。
このようにバリデーションはコントローラーで指定することもできます。
では、さっそく日本語化していきましょう。
task-app/resources/lang/ja/validation.php
を下記の通り編集してください。
// --- 以上省略 ---
/*
|--------------------------------------------------------------------------
| カスタムバリデーション属性名
|--------------------------------------------------------------------------
|
| 以下の言語行は、例えば"email"の代わりに「メールアドレス」のように、
| 読み手にフレンドリーな表現でプレースホルダーを置き換えるために指定する
| 言語行です。これはメッセージをよりきれいに表示するために役に立ちます。
|
*/
'attributes' => [
'name' => 'ユーザー名',
'email' => 'メールアドレス',
'password' => 'パスワード',
],
validation.php
は、以前日本語ファイルをダウンロードした際にダウンロードされたファイルです。
そのファイルの一番下にattributes => [];
となっているので、その中に翻訳した値を入力すればOKです。
もう一度新規登録画面でバリデーションに引っかかるように入力してみると、下記画像のようになります。
これで日本語化はOKです。
次の教材
次の教材は下記から簡単に飛ぶことができます!
引き続きプログラミングを楽しんでいきましょう!
プログラミング学習サポートについて
「独学で挫折した。。。」
「一人でのプログラミング学習がしんどい。。。」
「未経験からエンジニア転職をしたいけど何をしたら良いかわからない。。。」
このような悩みをお持ちの方向けに、本教材作成者のファドがMENTAという学習サイトにてあなたのプログラミング学習とエンジニア転職を徹底サポートいたします!
サポート価格はなんと1日あたりたったの約300円!
教材で分からない箇所のサポートはもちろんのこと、本サイトで公開しているすべての課題の解答も公開しております。
また、MENTAで学習を終わらせていただいた方限定で懇意にしていただいている企業さんを紹介することもあります!
なお、サポート内容の詳細は下記の通りです。
- 目標設定
- マインドセット
- オリジナル教材見放題
- オリジナル課題見放題
- オリジナル課題の解答見放題
- 課題コードレビュー
- 教材への無制限質問
- 課題への無制限質問
- ポートフォリオ作成アドバイス
- 褒めのコーチング
いくつかのプランを用意させていただいておりますので、下記より一度ご覧ください!
コメント