【Laravelチュートリアル】 STEP5 レイアウトをしてみよう
これまで、MVCの理解を進めてきました。基本的にLaravelのRoute、Controler、Viewはバックエンド開発と言ってサーバー側と開発になります。
今回のレイアウトはフロントエンド開発を学びます。CSSやJavascriptを利用して見やすい画面を作ってみましょう。
1.Viteを利用する
近年の開発では、CSSやJavasciptなどはVite
やwebpack
を利用して開発していきます。Laravel10では、Vite
を利用しています。
Vite
は、非常に高速な開発環境を提供してくれる、コードを本番用に構築する最新のフロントエンド・ビルド・ツールです。Laravelでアプリケーションを構築する場合、通常、Viteを使用してアプリケーションのCSSとJavaScriptファイルを本番環境用のアセットへ構築することになります。package.jsonを一応貼っておきます。
// package.json
{
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"axios": "^1.6.4",
"laravel-vite-plugin": "^1.0.0",
"vite": "^5.0.0"
}
}
Laravel標準の機能をインストールします。
npm install
Viteではない場合は、vite.config.jsを作成してください。
// project/vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel([
'resources/css/app.css',
'resources/js/app.js',
]),
],
});
2.基本になるパッケージをインストールする
レイアウトを1から作成すると時間と労力が必要になります。そこで、CSSやJavascriptを提供してくれるパッケージを利用していきます。
今回は、bootstrap5
を利用します。
npm install bootstrap@5.3.0
npm install lodash
インストールが終わったらViteを実行してみます。※開発モードで実行します。
インストールされたか確認しましょう。
// project/package.json
{
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"axios": "^1.6.4",
"laravel-vite-plugin": "^1.0.0",
"vite": "^5.0.0"
},
"dependencies": {
"bootstrap": "^5.3.0",
"lodash": "^4.17.21"
}
}
dependenciesにbootstrap
とlodash
が追加されているのを確認してください。
# 開発モード
npm run dev
# 実働用にアセットをバンドルし、バージョン付けする
npm run build
実行できたら以下のように表示されます。
root@537ae07b9b21:/var/workspace/project# npm run dev
> dev
> vite
VITE v5.0.12 ready in 140 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
LARAVEL v10.40.0 plugin v1.0.1
➜ APP_URL: http://localhost
開発モードでは、変更したら瞬時に再ビルドしてくれます。
3.テンプレートを用意しよう
4章までは、HTMLを利用してきましたが正しいHTMLの形ではありません。まず、画面のベースとなるテンプレートを作成し、継承する形で画面を作成していきます。
これはLaravel
のBlade
の機能になり、必須の技術になります。
<!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>{{ config('app.name') }}</title>
{{-- ここは、画面に表示されません --}}
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
{{-- ここから画面に表示されます。 --}}
<header class="navbar">
<div class="container-fluid">
<h1 class="navbar-brand">{{ config('app.name') }}</h1>
</div>
</header>
<div>
<main>
<div class="container">
@yield('content')
</div>
</main>
<footer>
<p>© 2024 laravelチュートリアル</p>
</footer>
</div>
</body>
</html>
head
は、HTMLの情報を記述したり、cssやjsなど外部ファイルを記述する場所です。ここに表示するものはWeb画面では表示されません。body
は、Webブラウザに表示されるコンテンツを記述する。body要素の内容がWebブラウザのメインの画面に表示される内容です。@yield
は継承先で変更する場所に設置します。@vite
は、CSSやJavascriptを呼び出すことができます。Viteを利用するとビルドの際にファイル名はランダム名になってしまうためこれを利用します。ホーム画面を変更してみましょう。
// resources/css/app.css
@import "bootstrap/dist/css/bootstrap";
header {
background-color: #F05340;
color: #6C6C6C;
}
main {
min-height: 90vh;
background-color: #e9e9e9;
}
// resources/views/welcome.blade.php
@extends('layouts.app')
@section('content')
Hello World!
@endsection
http://localhost:8000/アクセスしてみましょう。4.投稿画面もレイアウト作成しよう
// resources/views/post/index.blade.php
@extends('layouts.app')
@section('content')
<h1>Hello Post Page!</h1>
<div class="mb-3">
<a href="{{ route('post.create') }}" class="btn btn-primary">新規作成</a>
</div>
<table class="table" border="1">
<thead>
<tr>
<td>ID</td>
<td>タイトル</td>
<td>作成日</td>
<td></td>
</tr>
</thead>
<tbody>
{{-- posts配列をループして、投稿記事の情報を表示 --}}
@foreach ($posts as $post)
<tr>
<td><a href="{{ route('post.edit', ['id' => $post->id]) }}">{{ $post->id }}</a></td>
<td>{{ $post->title }}</td>
<td>{{ $post->created_at }}</td>
<td>
<a href="{{ route('post.edit', ['id' => $post->id]) }}" class="btn btn-primary">編集</a>
<a href="{{ route('post.destroy', ['id' => $post->id]) }}" class="btn btn-secondary">削除</a>
</td>
</tr>
@endforeach
</tbody>
</table>
@endsection
ボタンの色もカスタマイズしてみよう
// resources/css/app.css
// ...
.btn-primary {
background-color: #F05340;
border-color: #F05340;
}
.btn-primary:hover {
background-color: #d3493a;
border-color: #d3493a;
}
// resources/views/post/edit.blade.php
@extends('layouts.app')
@section('content')
<h1>{{ $post->title }} 編集</h1>
<form action="{{ route('post.edit', ['id' => $post->id]) }}" method="post">
@csrf
<div class="mb-3">
<label class="form-label">タイトル</label>
<input type="text" name="title" value="{{ old('title', $post->title) }}" class="form-control">
@error('title')
<div>{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label class="form-label">記事</label>
<textarea name="content" class="form-control">{{ old('content', $post->content) }}</textarea>
@error('content')
<div>{{ $message }}</div>
@enderror
</div>
<button type="submit" class="btn btn-primary">更新</button>
</form>
@endsection
// resources/views/post/create.blade.php
@extends('layouts.app')
@section('content')
<h1>投稿新規作成</h1>
<form action="{{ route('post.create') }}" method="post">
@csrf
<div class="mb-3">
<label class="form-label">タイトル</label>
<input type="text" name="title" value="{{ old('title') }}" class="form-control">
@error('title')
<div>{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label class="form-label">記事</label>
<textarea name="content" class="form-control">{{ old('content') }}</textarea>
@error('content')
<div>{{ $message }}</div>
@enderror
</div>
<button type="submit" class="btn btn-primary">作成</button>
</form>
@endsection
5.TOPページを作成しよう
HomeControllerを作成します。
php artisan make:controller HomeController
// routes/web.php
<?php
use App\Http\Controllers\HomeController;
// ...
Route::get('/', [HomeController::class, 'welcome'])->name('welcome');
// app/Http/Controllers/HomeController.php
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class HomeController extends Controller
{
/**
* welcome page
*
* @param Request $request
*/
public function welcome(Request $request)
{
$pagination = Post::paginate();
return view('welcome', [
'pagination' => $pagination
]);
}
}
@extends('layouts.app')
@section('content')
<h1>Hello Post Page!</h1>
<div class="mb-3">
<a href="{{ route('post.create') }}" class="btn btn-primary">新規作成</a>
</div>
<table class="table" border="1">
<thead>
<tr>
<td>ID</td>
<td>タイトル</td>
<td>作成日</td>
<td></td>
</tr>
</thead>
<tbody>
{{-- posts配列をループして、投稿記事の情報を表示 --}}
@foreach ($posts as $post)
<tr>
<td><a href="{{ route('post.edit', ['id' => $post->id]) }}">{{ $post->id }}</a></td>
<td>{{ $post->title }}</td>
<td>{{ $post->created_at }}</td>
<td>
<a href="{{ route('post.edit', ['id' => $post->id]) }}" class="btn btn-primary">編集</a>
<a href="{{ route('post.destroy', ['id' => $post->id]) }}" class="btn btn-secondary">削除</a>
</td>
</tr>
@endforeach
</tbody>
</table>
@endsection
paginate
を利用すると、20件ずつ投稿を表示することができます。paginate(1)
など引数に何件ずつ表示するかを設定できます。Topページのレイアウトを作成します。
paginationのレイアウトを指定します。今回は、bootstrapを利用するので宣言します。
// app/Providers/AppServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Pagination\Paginator;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Paginator::useBootstrapFive();
Paginator::useBootstrapFour();
}
}
6.まとめ
今回は、レイアウト整えてより見やすいページを作成してみました。
だいたいの開発ではベースとなるレイアウトを決めて、カスタマイズをし独自のレイアウトに変更。今回はbootstrap
をベースにレイアウトを調整しました。
現代のフロントエンド開発では、Viteなどビルドツールを利用して開発します。cssとJavascriptで利用するためデザイナー志望でも利用しなければならない技術になってきています。
これでWeb開発の基本を学ぶことができました。次章からは応用に入っていきますが、これまでの内容を理解すれば問題ありません。
Webエンジニアを目指して頑張っていきましょう!\(^o^)/