ラボ > Laravel、Lumen:基本、views関連、エラー関連

laravel8 サイト構築の初期手順(チートシート)

artisanにFacades、Blade、エラーページの設定…いろいろと覚えておかないと使えないので初期の手順をまとめておく

作成日:2023-07-03, 更新日:2023-11-06

基本

▼私の環境
WIN+Docker+Ubuntuでlaravelを使うための作業メモ

作業前に確認

  • config/app.php
    • timezone: 「UTC」→「Asia/Tokyo」
    • 言語関連: 「en」→「ja」、「en_US」→「ja_jp」

やりたいこと

ひとまずログインページを作る
※ログイン後や認証は作らない。あくまで基本型の作成メモ + ログイン機能実装する前の下準備も追加

  • 画面の雛形
  • エラーページ(401, 403, 404, 419, 429, 500, 503)

artisanコマンド

artisanコマンドは頻繁に使うのでubuntuのコンソールでは基本的にカレントを作業対象に移しておく

artisanファイルの場所

/home/ユーザーディレクトリ/プロジェクトディレクトリ

※設定次第で色々と変わるだろうから、適宜、脳内変換が必要

artisanコマンド

sailってヤツなので下記のようなコマンド

$ ./vendor/bin/sail php artisan 〇〇〇

※sailじゃないなら「php artisan 〇〇〇」でいけるハズ

関連項目

Bladeのメモ

ビューは「Blade」ってヤツになるらしい

  • Blade Templates - 「@yield」とかを使う
  • Blade Components - 「@yield」とかは使わない。「app/View/Components」を使う

以前、調べたときの記憶がうっすらと残っているが…「Blade Templates」は古い、「Blade Components」が新しいってコトだったはず

画面の雛形

方法は色々とあるっぽいけど…色々と覚えるのが面倒なので「Blade Components」ってヤツを使う方針で進める

▼目標

  • 「<html><head>~</head><body>〇〇〇</body></html>」の「〇〇〇」以外を雛形にしたい
  • ページごとにタイトルを変えたい / 「タグ: title」に値を渡したい
  • ページ内の一部を雛形にしたい(※サブメニューや頻繁に使うコンテンツなど)

▼ファイル名

  • layout/common.blade.php - 「<html><head>~</head><body>〇〇〇</body></html>」の「〇〇〇」以外の雛形
  • login.blade.php - ログインページ
  • form/common.blade.php - ログインフォームのformタグの枠を雛形にしたい

▼手順

  1. 大元の雛形を作成
  2. 各ページを作る(ログインページの作成)
  3. ルーティングの設定
  4. 各ページで読み込む雛形の中で雛形を使う(formタグを雛形にしたい)

大元の雛形を作成

▼メモ

  • 「app/View/Components」「resources/views/components」のそれぞれが必要
  • 「resources/views/components」の下に「layout/common.blade.php」を作ってもらいたい

▼やること

  1. artisanコマンドで作成 + ファイルの確認
  2. 雛形の作成
  3. 各ページから渡してもらう値・変数の設定をしておく

artisanコマンドで作成 + ファイルの確認

▼Laravelは大文字スタートが好きっぽいんで大文字スタートにしておく

$ ./vendor/bin/sail php artisan make:component Layout/Common

▼作られるファイル(「app/View/Components」を作ったと言われるけど「resources/views/components」の方も作られている)

  • app/View/Components/Layout/Common.php
  • resources/views/components/layout/common.blade.php

雛形の作成

  • ページタイトルは各ページから受取りたい
  • csrfは基本、ajaxで投げるので全ページ共通でセット(※いずれページごとに対応するかもしれない)
  • bodyタグ内はひとまず各ページの内容をマルっと出力

▼resources/views/components/layout/common.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" content="{{ csrf_token() }}">

        <title>{{ $header['title'] }}</title>
        <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    </head>

    <body>
        {{ $slot }}
    </body>
</html>

※「$slot」が各ページの内容をマルっと出力。
※「$header['title']」は今後のコトを考慮して配列にしている
※ajaxじゃなく、form送信させるならformタグの中に「@csrf」を置く。無いと419エラー(419 Page Expired)になる(Laravel8 formのCSRFとajax時のCSRF

各ページから渡してもらう値・変数の設定をしておく

今回の場合だと、「$header」だけ設定が必要

▼app/View/Components/Layout/Common.php

<?php

~ 略 ~

class Common extends Component
{
    public $header; // ビューから雛形に渡す変数の設定

    ~ 略 ~
    public function __construct($header)
    {
        $this->header = $header;
    }

~ 以下、略 ~

各ページを作る(ログインページの作成)

▼メモ

  • ひとまずログインページを作りたい
  • URLは「https://example.com/login」にしたい

▼やること

  1. コントローラー作成
  2. ビュー作成 + 雛形を読み込ませる
  3. ルーティング設定
  4. 各ページで読み込む雛形の中で雛形を使う(formタグを雛形にしたい)

コントローラー作成

▼「第1階層にファイルが多い」っての好きじゃないので…適当なフォルダの下に置く

$ ./vendor/bin/sail php artisan make:controller Main/LoginController

▼作られるファイル

  • app/Http/Controllers/Main/LoginController.php

▼app/Http/Controllers/Main/LoginController.php

<?php

~ 略 ~
use Illuminate\Http\Request;

// 追加
use Exception;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class LoginController extends Controller
{
    public function __construct() {}

    public function index(Request $request){

        // ===============================
        $viewData = array( // ビューに渡す値たち
            'header' => array(
                'title' => 'ログイン',
            ),
        );
        return view('Main/login/index', $viewData); // 「ビュー:resources\views\〇〇〇\index.php」を呼び出す
    }
}

ビュー作成 + 雛形を読み込ませる

artisanコマンドがあるかは知らないけど…面倒なので手動で作成

▼「main/login/index.blade.php」を手動で用意

<x-layout.common :header="$header">
    <h1>ログイン</h1>
    <form mehtod="post" action="#">
        <input type="text" name="mail" value="" />
        <input type="password" name="pwd" value="" />
        <button type="submit">ログイン</button>
    </form>
</x-layout.common>

※「resources/views/components/layout/common.blade.php」を読み込ませるので「x-layout.common」とする

ルーティングの設定

「app/Http/Middleware/Authenticate.php」も絡むので必要に応じて対応が必要

▼routes/web.php

<?php

~ 略 ~

// ログイン必須ページ: ログインしていないとき
Route::middleware('guest')->group(function () {
    Route::get('/login', [Controllers\Main\LoginController::class, 'index'])->name('login'); // 「name('login')」がログインしていないときの飛ばし先: 「app/Http/Middleware/Authenticate.php」の「redirectTo()」の「return route('login');」と紐づく
});

~ 以下、略 ~

ログイン前後の飛ばし先

  • ログイン前の飛ばし先の指定 - 上記の「name('login')」と「app/Http/Middleware/Authenticate.php」の「redirectTo()」の「return route('login');」
  • ログイン後の飛ばし先の指定 - 「app/Providers/RouteServiceProvider.php」の「public const HOME = '/home';」

各ページで読み込む雛形の中で雛形を使う(formタグを雛形にしたい)

formタグとボタンは基本、フォームで使うので雛形にしたい

▼やること

  1. formタグの雛形作成: form/common.blade.php
  2. 雛形に渡す各値の設定: formタグの各属性、ボタンたち
  3. 「main/login/index.blade.php」の修正

formタグの雛形作成: form/common.blade.php

$ ./vendor/bin/sail php artisan make:component Form/Common

※「app/View/Components」「resources/views/components」の下にそれぞれファイルが作られる

雛形に渡す各値の設定: formタグの各属性、ボタンたち

  • 「formタグの各属性」は各ビューで直書き指定
  • ボタンを渡したい

▼app/View/Components/Form/Common.php

<?php

~ 略 ~

class Common extends Component
{
    public $btn_many; // ビューから雛形に渡す変数の設定

    /**
     * Create a new component instance.
     */
    public function __construct($btn_many)
    {
        $this->btn_many = $btn_many;
    }

~ 以下、略 ~

▼resources/views/components/form/common.blade.php

<form method="post" {{ $attributes }}>
    {{ $slot }}
    <?php echo implode("\n", $btnMany); /* ボタンをマルっと出力 */ ?>
</form>

「main/login/index.blade.php」の修正

<x-layout.common :header="$header">
    <h1>ログイン</h1>
    <x-layout.form :btnMany="$btn_many" action="#">
        <input type="text" name="mail" value="" />
        <input type="password" name="pwd" value="" />
    </x-layout.form>
</x-layout.common>

※「:btn_many」ではなく「:btnMany」にしているのは「_」を使うとエラーになるから。理由は知らない
※「:」の無い「action="#"」は雛形が「$attributes」としてマルっと取得し、出力してくれる

関連項目

エラーページ(401, 403, 404, 419, 429, 500, 503)

▼やりたいこと

  • エラーページのデザインを好き勝手したい
  • 400エラーもほしい

▼やること

  • エラーページを用意
  • レイアウト変更

エラーページを用意

$ ./vendor/bin/sail php artisan vendor:publish --tag=laravel-errors

→「resources/views/errors/xxx.blade.php」が色々と作られる

400エラーのページをつくる

用意されているのは「401, 403, 404, 419, 429, 500, 503」。
適当なファイルを複製して「400」をつくる

▼「401.blade.php」を複製して「400.blade.php」を作り、中身を修正

@extends('errors::minimal')

@section('title', __('Bad Request'))
@section('code', '400')
@section('message', __('Bad Request'))

確認

▼適当なコントローラーに記載して、アクセス

abort(400);

レイアウト変更: 1(おそらく一般的なやりかた)

おそらく一般的なやりかた…をベースにレイアウト変更

「@extends('errors::minimal')」を「@extends('errors::layout')」に変更するのが良さげっぽいらしいけど…面倒なので変更しない

現状だと「title」「code」「message」しか使えないので変更

▼「400.blade.php」に追加(※「summary」を追加)

~ 略 ~
@section('message', __('Bad Request'))
@section('summary', __('そのリクエストはダメです'))

▼「minimal.blade.php」に追加(※「summary」を追加)

~ 略 ~
<div class="ml-4 text-lg text-gray-500 uppercase tracking-wider">
    @yield('message')
    @yield('summary')
</div>

レイアウト変更: 2(一般的じゃないやり方かもしれない。自己判断で。)

ベースになるHTMLの雛形を用意しているのでそれを使いたい…
現状は「@yield」とかを使う「Blade Templates」ってヤツでエラーページを表示しているので強引に「@yield」とかは使わない「Blade Components」に変更

▼「400.blade.php」を修正(※401、402…他同様。403はmessageが少し異なるので適当に何かする)

<?php
    $title = 'Bad Request';
    $code = '400';
    $message = $code . ' ' . $title;
?>
@extends('errors::minimal')

▼「403.blade.php」のmessageの例

$message = $code . ' ' . (($exception->getMessage())? $exception->getMessage(): 'Forbidden');

▼「minimal.blade.php」を修正

<?php
    $header = array(
        'title' => $title,
    );

    switch ( $code ) {
        case 401:
            $flg_toLogin = true;
        break;

        default:
            $flg_toLogin = false;
        break;
    }

?><x-layout.common :header="$header">
    <h1><?php echo $title; ?></h1>
    <div>
        <?php echo $message; ?>

        <?php if($flg_toLogin):/* 401エラーのときはログインページへのリンクをつけたい */ ?>
            <a href="#">ログインページ</a>
        <?php endif; ?>
    </div>
</x-layout.common>

関連項目