こんにちは。
ITエンジニアの濱辺(ハマベ)です。
前回に引き続き、お気に入りの動画を共有できる、SNSのようなアプリを作っていきます。
前回は、DB周りをやりました。
第3回は、主に、新規登録機能周りを作成していきます。
↓第2回はこちら
LaravelでYoutubeのお気に入りCuration(まとめ)アプリを作る【第2回】
↓こちらの画面定義書のものを作っていきます。
Youtube-Curation 画面定義所 (googleスプレッドシート)
トップページを作る
まずはrouterを作成します。
routerの作成とは、このURLにアクセスしたら、このページを表示してね、という決まり事を決めることです。
router/web.php
に下記を記述します。
Route::get('/', function () {
return view('welcome');
});
これは、ホームディレクトリにアクセスされたら、welcomeというページを表示してね。
という指令になります。
共通部分を切り分けて作成する
当ページ最初の方のリンクから見ることができる、画面定義書を確認すると分かるかと思いますが、全てのページで共通して存在する部分があります。
そこをいちいち全てのページに記述していくのは効率が悪く、修正があった際の手間も増えます。
なので、共通部分は、部品として使いまわせるように切り分けて作成します。
resources/views/layouts/app.blade.php
を新規作成しましょう。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>YouTubeまとめ×SNS</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
@include('commons.header')
<div class="container">
@include('commons.error_messages')
@yield('content')
</div>
@include('commons.footer')
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script defer src="https://use.fontawesome.com/releases/v5.7.2/js/all.js"></script>
</body>
</html>
このコードは全てのページに反映されます。
@includeは、他のviewを呼び出してあてはめる指示をするコードです。
例えば@include('commons.header')
の部分は、今後commons/header.blade.php
を作成してコードを記述すれば、そのコードがそのまま当てはまって見た目として表示されるわけです。
こうして部品かすることで、管理しやすく、修正に強い設計ができます。フレームワークの長所の一つです。
view:エラーメッセージ作成
エラーメッセージを表示させるファイルを作っていきます。
views/commons/error_messages.blade.php
を新規作成しましょう。
@if (count($errors) > 0)
<ul class="alert alert-danger">
@foreach ($errors->all() as $error)
<li class="ml-4">{{ $error }}</li>
@endforeach
</ul>
@endif
ざっくり言うと、もしもエラーがあるなら、$errorを表示しろという指示を出しています。
これが先程のapp.blade.php
内の@include('commons.error_messages')
にあてがわれるわけです。
ヘッダーとフッターを作成
先程作ったcommonsフォルダの中に、header.blade.php
,footer.blade.php
を作成しましょう。
<header class="mb-5">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="/">YouTube-Curation</a>
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#nav-bar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="nav-bar">
<ul class="navbar-nav mr-auto"></ul>
<ul class="navbar-nav">
<li class="nav-item"><a href="" class="nav-link">新規ユーザ登録</a></li>
<li class="nav-item"><a href="" class="nav-link">ログイン</a></li>
</ul>
</div>
</nav>
</header>
<footer class="mt-5">
<nav class="navbar navbar-light bg-light justify-content-center">
<div class="navbar-brand m-0">© QuestAcademia, All rights reserved.</div>
</nav>
</footer>
welcome.blade.phpを改変
welcome.blade.phpは最初からコードが記述されていますが、全て削除して書き換えます。
@extends('layouts.app')
@section('content')
<div class="center jumbotron bg-warning">
<div class="text-center text-white">
<h1>YouTubeまとめ × SNS</h1>
</div>
</div>
@endsection
この状態で、http://127.0.0.1:8080/にアクセスすると、下記画像と同じものが表示されます。
新規登録機能を実装
さて、トップページの最低限の見た目が出来たので、いよいよ機能実装をしていきます。
MVCのC、Controllerを使用するのですが、新規登録のためのコントローラは、Laravelに標準で備わっています。
app/Http/Controllers/Auth/RegisterController.php
が該当のファイルです。
とりあえず、このファイルは一旦置いて、先にrouterを作っていきましょう。
web.php
を開き、最下部に下記を追加しましょう。
// ユーザ登録
Route::get('signup', 'Auth\RegisterController@showRegistrationForm')->name('signup');
Route::post('signup', 'Auth\RegisterController@register')->name('signup.post');
->name() という記述により、ルーティングに命名して後で呼び出しやすくしています。
コントローラの実装
RegisterController.php
を開きましょう。
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
~ 略
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
}
上記ファイルのうち、protected $redirectTo = RouteServiceProvider::HOME;
行のみ、下記に変更しましょう。
protected $redirectTo = '/';
さて、controllerにはほぼ何もしていないですが、すでに正常に新規登録機能が動作するようになっています。
それは、「トレイト」と呼ばれる機能のおかげです。
先ほどweb.php
に記述した、下記をみてください。
Route::get('signup', 'Auth\RegisterController@showRegistrationForm')->name('signup');
Route::post('signup', 'Auth\RegisterController@register')->name('signup.post');
Auth/RegisterController
の、showRegistrationForm
,register
アクションを呼ぶ記述になっていますが、そんなアクションはどこにも記述されていません。ではなぜ、正常に動作するのか、それは、「トレイト」ざっくりいうと、どこかの誰かが作ったアクションを使用している、からです。
今回使用しているアクションの元コードは以下で確認できます。
https://github.com/laravel/framework/blob/6.x/src/Illuminate/Foundation/Auth/RegistersUsers.php
その他、処理を行うにはゲストユーザでなくてはならない, 新規登録したらトップページに戻る, **255文字以上入力できない(バリデーション)**などの処理が書かれているのですが、細かい説明は省きます。
LaravelCollective 導入
新規登録の処理は実装したので、登録画面のviewを作成します。
view作成にLaravelCollective
というライブラリを使用するので、先にインストールしましょう。
# composer require "laravelcollective/html":"6.*"
↓ここで一旦、RegistersUsers
を見てみましょう。
https://github.com/laravel/framework/blob/6.x/src/Illuminate/Foundation/Auth/RegistersUsers.php
この中のshowRegistrationForm
のコードを見てみましょう。
return view('auth.register');
これは、Auth/register.blade.php
ファイルを表示する、という処理です。
しかし、そんなファイルは存在しないため、新規作成しましょう。
resources/views/auth/register.blade.php
を作成。
@extends('layouts.app')
@section('content')
<div class="center jumbotron bg-warning">
<div class="text-center text-white">
<h1>YouTubeまとめ × SNS</h1>
</div>
</div>
<div class="text-center">
<h3 class="login_title text-left d-inline-block mt-5">新規ユーザー登録</h3>
</div>
<div class="row mt-5 mb-5">
<div class="col-sm-6 offset-sm-3">
{!! Form::open(['route' => 'signup.post']) !!}
<div class="form-group">
{!! Form::label('name', '名前') !!}
{!! Form::text('name', old('name'), ['class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::label('email', 'メールアドレス') !!}
{!! Form::email('email', old('email'), ['class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::label('password', 'パスワード') !!}
{!! Form::password('password', ['class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::label('password_confirmation', 'パスワード確認') !!}
{!! Form::password('password_confirmation', ['class' => 'form-control']) !!}
</div>
{!! Form::submit('新規登録', ['class' => 'btn btn-primary mt-2']) !!}
{!! Form::close() !!}
</div>
</div>
@endsection
{!! !!} は、LaravelCollectiveのコードです。
トップページから新規登録画面へのリンクを追加
LaravelCollectiveのlink_to_route
という関数を使ってページ推移を実装します。
<ul class="nav navbar-nav navbar-right">
<li class="nav-item">{!! link_to_route('signup', '新規ユーザ登録', [], ['class' => 'nav-link']) !!}</li>
<li class="nav-item"><a href="" class="nav-link">ログイン</a></li>
</ul>
これで、トップ画面上部の新規ユーザ登録
クリックで、新規登録ページに推移できるようになりました。
ちなみに、新規登録画面は以下の画像のようになっているはずです。(上部が見切れていますが😅)
新規ユーザ登録をやってみよう
作成した入力フォームを使用して、新規登録します。
登録後、画面推移が上手くいかない場合は、app/Http/middleware/RedirectIfAuthenticated.php
の該当行を変更しましょう。
return redirect(RouteServiceProvider::HOME);
↓
return redirect('/'); //これに変更
新規登録できたら、tinkerよりユーザ一覧をみてみましょう。
use App\User
User::all()
登録したユーザ情報が表示されれば、無事に登録機能が実装できています。
現時点では、ログアウト機能がありませんので、php artisan migrate:refresh
などで、ユーザを削除し、強制ログアウトしておきましょう。
その後、新規登録画面に入りなおしましょう。
バリデーションの動作確認
入力フォームを例えば、以下のような状態で登録しようとした時、しっかりエラーが出るか確認しましょう。
- 名前 → 空欄のとき
- Eメール → 空欄のとき
- パスワード → 8文字未満の時
- パスワード確認 → パスワード欄とパスワード確認欄の内容が不一致のとき
画像のようなエラーメッセージが出ればOKです。
無事、ユーザ登録機能が実装できました!
第3回おわり
ここまで出来れば、あとは似たようなことの繰り返しで出来るはずです。
一緒に頑張っていきましょう!
第4回は、ログイン&動画登録を実装していきます😄
↓第4回はこちら
LaravelでYoutubeのお気に入りCuration(まとめ)アプリを作る【第4回: ログイン&動画登録の実装】