環境
- Laravel 8.6
- PHP 8.0
- Bootstrap 5.1
5.1 構造を追加する
5.1.1 ナビゲーション
ルーティングの修正
/routes/web.php
Route::get('/', [StaticPagesController::class, 'home'])->name('home');
共通ビューを修正
/resources/views/layouts/application.blade.php
<!DOCTYPE html>
<html>
<head>
<title>{{ full_title($__env->yieldContent('title')) }}</title>
<meta name="csrf-token" content="{{ csrf_token() }}">
<script data-turbolinks-track="reload" src="{{ mix('/js/app.js') }}"></script>
<link media="all" type="text/css" rel="stylesheet" data-turbolinks-track="reload" href="{{ mix('/css/app.css') }}">
</head>
<body>
<header class="navbar fixed-top navbar-dark p-0">
<div class="container">
{{ link_to_route('home', "sample app", ["id" => "logo"]) }}
<nav>
<ul class="nav navbar-nav">
<li>{{ link_to_route("home", "Home") }}</li>
<li>{{ link_to_route("home", "Help") }}</li>
<li>{{ link_to_route("home", "Log in") }}</li>
</ul>
</nav>
</div>
</header>
<div class="container">
@yield('content')
</div>
</body>
</html>
homeのビューを修正
/resources/views/static_pages/home.blade.php
@extends('layouts.application')
@section('content')
<div class="center bg-light p-5 my-4 rounded">
<h1>Welcome to the Sample App</h1>
<h2>
This is the home page for the
<a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
sample application.
</h2>
{{ link_to_route("home", "Sign up now!", [], ["class" => "btn btn-lg btn-primary", "role" => "button"]) }}
</div>
<a href="http://rubyonrails.org/"><img src="{{ asset('/img/rails.png') }}" alt="Rails logo"></a>
@endsection
5.1.2 BootstrapとカスタムCSS
nodemoduleをインストール
sail npm install
CSSとJSをコンパイル
以降CSSとJSを修正した場合に実行
sail npm run prod
5.1.3 パーシャル(partial)
ビューを修正
/resources/views/layouts/application.blade.php
<!DOCTYPE html>
<html>
<head>
<title>{{ full_title($__env->yieldContent('title')) }}</title>
<meta name="csrf-token" content="{{ csrf_token() }}">
<script data-turbolinks-track="reload" src="{{ mix('/js/app.js') }}"></script>
<link media="all" type="text/css" rel="stylesheet" data-turbolinks-track="reload" href="{{ mix('/css/app.css') }}">
</head>
<body>
@include('layouts.header')
<div class="container">
@yield('content')
</div>
@include('layouts.footer')
</body>
</html>
/resources/views/layouts/header.blade.php
<header>
<nav class="navbar navbar-expand fixed-top navbar-dark bg-dark">
<div class="container">
{{ link_to_route('home', "sample app", [], ["id" => "logo", "class" => "navbar-brand"]) }}
<ul class="navbar-nav">
<li class="nav-item">{{ link_to_route("home", "Home", [], ["class" => "nav-link"]) }}</li>
<li class="nav-item">{{ link_to_route("home", "Help", [], ["class" => "nav-link"]) }}</li>
<li class="nav-item">{{ link_to_route("home", "Log in", [], ["class" => "nav-link"]) }}</li>
</ul>
</div>
</nav>
</header>
/resources/views/layouts/footer.blade.php
<footer class="footer">
<nav class="navbar navbar-expand-lg">
<div class="container">
<small>
The <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
by <a href="http://www.michaelhartl.com/">Michael Hartl</a>
</small>
<ul class="navbar-nav">
<li class="nav-item">{{ link_to_route("home", "About", [], ["class" => "nav-link"]) }}</li>
<li class="nav-item">{{ link_to_route("home", "Contact", [], ["class" => "nav-link"]) }}</li>
<li class="nav-item"><a href="http://news.railstutorial.org/" class="nav-link">News</a></li>
</ul>
</div>
</nav>
</footer>
/resources/sass/app.scss
// Fonts
@import url('https://fonts.googleapis.com/css?family=Nunito');
// Variables
// @import 'variables';
// Bootstrap
@import '~bootstrap/scss/bootstrap';
/* universal */
body {
padding-top: 60px;
}
section {
overflow: auto;
}
textarea {
resize: vertical;
}
.center {
text-align: center;
}
.center h1 {
margin-bottom: 10px;
}
/* typography */
h1, h2, h3, h4, h5, h6 {
line-height: 1;
}
h1 {
font-size: 3em;
letter-spacing: -2px;
margin-bottom: 30px;
text-align: center;
}
h2 {
font-size: 1.2em;
letter-spacing: -1px;
margin-bottom: 30px;
text-align: center;
font-weight: normal;
color: #777;
}
p {
font-size: 1.1em;
line-height: 1.7em;
}
/* header */
# logo {
float: left;
margin-right: 10px;
font-size: 1.7em;
color: #fff;
text-transform: uppercase;
letter-spacing: -1px;
padding-top: 9px;
font-weight: bold;
}
# logo:hover {
color: #fff;
text-decoration: none;
}
/* footer */
footer {
margin-top: 45px;
padding-top: 5px;
border-top: 1px solid #eaeaea;
color: #777;
}
footer .nav-link {
color: #555;
}
footer .nav-link:hover {
color: #222;
}
footer small {
float: left;
}
footer ul {
float: right;
list-style: none;
}
footer ul li {
float: left;
margin-left: 15px;
}
演習
/resources/views/layouts/application.blade.php
<!DOCTYPE html>
<html>
<head>
<title>{{ full_title($__env->yieldContent('title')) }}</title>
@include('layouts.rails_default')
</head>
<body>
@include('layouts.header')
<div class="container">
@yield('content')
</div>
@include('layouts.footer')
</body>
</html>
/resources/views/layouts/rails_default.blade.php
<meta name="csrf-token" content="{{ csrf_token() }}">
<script data-turbolinks-track="reload" src="{{ mix('/js/app.js') }}"></script>
<link media="all" type="text/css" rel="stylesheet" data-turbolinks-track="reload" href="{{ mix('/css/app.css') }}">
5.2 Sassとアセットパイプライン
5.2.1 アセットパイプライン
5.2.2 素晴らしい構文を備えたスタイルシート
5.3 レイアウトのリンク
5.3.1 Contactページ
5.3.2 RailsのルートURL
ルーティングの修正
/routes/web.php
Route::get('/', [StaticPagesController::class, 'home'])->name('home');
Route::get('about', [StaticPagesController::class, 'about'])->name('about');
Route::get('help', [StaticPagesController::class, 'help'])->name('help');
Route::get('contact', [StaticPagesController::class, 'contact'])->name('contact');
テスト修正
/tests/Unit/StaticPagesControllerTest.php
public function testGetRoot()
{
$response = $this->get('/');
$response->assertStatus(200);
$dom = $this->dom($response->content());
$this->assertSame($this->base_title, $dom->filter("title")->text());
}
public function testGetAbout()
{
$response = $this->get(route('about'));
$response->assertStatus(200);
$dom = $this->dom($response->content());
$this->assertSame("About | {$this->base_title}", $dom->filter("title")->text());
}
public function testGetHelp()
{
$response = $this->get(route('help'));
$response->assertStatus(200);
$dom = $this->dom($response->content());
$this->assertSame("Help | {$this->base_title}", $dom->filter("title")->text());
}
public function testGetContact()
{
$response = $this->get(route('contact'));
$response->assertStatus(200);
$dom = $this->dom($response->content());
$this->assertSame("Contact | {$this->base_title}", $dom->filter("title")->text());
}
5.3.3 名前付きルート
headerのリンクを修正
/resources/views/layouts/header.blade.php
<header>
<nav class="navbar navbar-expand fixed-top navbar-dark bg-dark p-0">
<div class="container">
{{ link_to_route('home', "sample app", [], ["id" => "logo", "class" => "navbar-brand"]) }}
<ul class="navbar-nav">
<li class="nav-item">{{ link_to_route("home", "Home", [], ["class" => "nav-link"]) }}</li>
<li class="nav-item">{{ link_to_route("help", "Help", [], ["class" => "nav-link"]) }}</li>
<li class="nav-item">{{ link_to_route("home", "Log in", [], ["class" => "nav-link"]) }}</li>
</ul>
</div>
</nav>
</header>
footerのリンクを修正
/resources/views/layouts/footer.blade.php
<footer class="footer">
<small>
The <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
by <a href="http://www.michaelhartl.com/">Michael Hartl</a>
</small>
<nav>
<ul>
<li>{{ Html::linkRoute("about", "About") }}</li>
<li>{{ Html::linkRoute("contact", "Contact") }}</li>
<li><a href="http://news.railstutorial.org/">News</a></li>
</ul>
</nav>
</footer>
5.3.4 リンクのテスト
テストの作成
sail artisan make:test SiteLayoutTest
テストの中身
/tests/Feature/SiteLayoutTest.php
class SiteLayoutTest extends TestCase
{
public function testLayoutLinks()
{
$response = $this->get('/');
$response->assertViewIs("static_pages.home");
$dom = $this->dom($response->content());
$this->assertSame(url("/"), $dom->filter('a:contains("sample app")')->attr("href"));
$this->assertSame(url("/"), $dom->filter('a:contains("Home")')->attr("href"));
$this->assertSame(route("help"), $dom->filter('a:contains("Help")')->attr("href"));
$this->assertSame(route("about"), $dom->filter('a:contains("About")')->attr("href"));
$this->assertSame(route("contact"), $dom->filter('a:contains("Contact")')->attr("href"));
}
}
演習
テスト追加
/tests/Feature/SiteLayoutTest.php
class SiteLayoutTest extends TestCase
{
public function testLayoutLinks()
{
$response = $this->get("/");
$response->assertViewIs("static_pages.home");
$dom = $this->dom($response->content());
$this->assertSame(url("/"), $dom->filter('a:contains("sample app")')->attr("href"));
$this->assertSame(url("/"), $dom->filter('a:contains("Home")')->attr("href"));
$this->assertSame(route("help"), $dom->filter('a:contains("Help")')->attr("href"));
$this->assertSame(route("about"), $dom->filter('a:contains("About")')->attr("href"));
$this->assertSame(route("contact"), $dom->filter('a:contains("Contact")')->attr("href"));
$response = $this->get("contact");
$response->assertViewIs("static_pages.contact");
}
}
5.4 ユーザー登録
5.4.1 Usersコントロール
Usersコントローラーを作成
sail artisan make:controller UsersController --resource
/app/Http/Controllers/UsersController.php
class UsersController extends Controller
{
public function create()
{
return view('users.create');
}
}
5.4.2 ユーザー登録用URL
ユーザー登録ページ作成
/routes/web.php
Route::get('signup', [UsersController::class, 'create'])->name('signup');
/resources/views/users/create.blade.php
@extends('layouts.application')
@section('title', 'Sign up')
@section('content')
<h1>Sign up</h1>
<p>This will be a signup page for new users.</p>
@endsection
/tests/Unit/UsersControllerTest.php
class UsersControllerTest extends TestCase
{
public function testGetCreate()
{
$responce = $this->get(route('signup'));
$responce->assertStatus(200);
}
}
5.5 最後に
参考
https://getbootstrap.jp/docs/5.0/components/navbar/
https://getbootstrap.jp/docs/5.0/components/buttons/