2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AdminLTE3をLaravelにzipで導入して認証機能を実装するやり方

Posted at

前書き

laravelにAdminLTEを導入する時は通常はLaravel-AdminLTEをcomposer requireすると思うが、諸事情でgithubからzipダウンロードして導入することになった。その際に認証機能の導入でlaravel/uilaravel-adminlteとの融合に苦労したのでまとめておく。

tl;dr

  • zipダウンロードしてview書き換えるのは結構大変
  • なので別でlaravel/ui+laravel-adminlteを導入したプロジェクトを作る
  • そしてview部分だけコピペで導入するという裏技的な対処で切り抜けた。

開発環境

  • docker-compose
    • php-fpm
    • nginx
    • mysql
  • laravel7

やり方

参考のために、laravel/uiとlaravel-adminlteのプロジェクトを作る

参考にするために、普通にcomposer requireとartisanコマンドで実装するプロジェクトを作成します。
laravel/ui+laravel-adminlteでの認証機能の導入は他の記事を参考にしてください。
認証機能が実装できたら次に進みます。

AdminLTEをzipで導入

それでは本題のプロジェクトの作業に取り掛かります。
githubからzipダウンロードします。
解凍したら/AdminLTE-3.0.5/dist/配下のファイルと/AdminLTE-3.0.5/pluginsフォルダをlaravelの/public/配下にコピーします。

$ cp -r /AdminLTE-3.0.5/dist/* public/vendor/AdminLTE/3.0.5/
$ cp -r /AdminLTE-3.0.5/plugins/* public/vendor/AdminLTE/3.0.5/

laravel/uiインストール

laravel/uiをインストールしますが、叩くコマンドが違います。

$ composer require laravel/ui
$ php artisan ui:auth //デフォルトでbootstrapで作成する

公式のやり方だとphp artisan ui bootstrap --authしてnpm run dev/public/app.css/public/app.jsを作るように書いてますが、artisanコマンドのヘルプに沿った上のやり方だとなぜかnpm run devを求められない。

ビューを書き換え

ここが一番苦労した。
laravel/ui+laravel-adminlteのプロジェクトのコードからview部分だけを導入する
headタグ内のスタイルシート、javascriptの引用先や@extendsの参照先などに気を付けて書き換える。

/resouces/views/auth/login.blade.php
@extends('auth.auth-page', ['auth_type' => 'login'])

@section('adminlte_css_pre')
    <link rel="stylesheet" href="{{ asset('vendor/icheck-bootstrap/icheck-bootstrap.min.css') }}">
@stop

@php( $login_url = View::getSection('login_url') ?? config('adminlte.login_url', 'login') )
@php( $register_url = View::getSection('register_url') ?? config('adminlte.register_url', 'register') )
@php( $password_reset_url = View::getSection('password_reset_url') ?? config('adminlte.password_reset_url', 'password/reset') )

@if (config('adminlte.use_route_url', false))
    @php( $login_url = $login_url ? route($login_url) : '' )
    @php( $register_url = $register_url ? route($register_url) : '' )
    @php( $password_reset_url = $password_reset_url ? route($password_reset_url) : '' )
@else
    @php( $login_url = $login_url ? url($login_url) : '' )
    @php( $register_url = $register_url ? url($register_url) : '' )
    @php( $password_reset_url = $password_reset_url ? url($password_reset_url) : '' )
@endif

@section('auth_header', __('ログイン'))

@section('auth_body')
    <form action="{{ $login_url }}" method="post">
        {{ csrf_field() }}

        {{-- Email field --}}
        <div class="input-group mb-3">
            <input type="email" name="email" class="form-control {{ $errors->has('email') ? 'is-invalid' : '' }}"
                   value="{{ old('email') }}" placeholder="メールアドレス" autofocus>
            <div class="input-group-append">
                <div class="input-group-text">
                    <span class="fas fa-envelope"></span>
                </div>
            </div>
            @if($errors->has('email'))
                <div class="invalid-feedback">
                    <strong>{{ $errors->first('email') }}</strong>
                </div>
            @endif
        </div>

        {{-- Password field --}}
        <div class="input-group mb-3">
            <input type="password" name="password" class="form-control {{ $errors->has('password') ? 'is-invalid' : '' }}"
                   placeholder="パスワード">
            <div class="input-group-append">
                <div class="input-group-text">
                    <span class="fas fa-lock"></span>
                </div>
            </div>
            @if($errors->has('password'))
                <div class="invalid-feedback">
                    <strong>{{ $errors->first('password') }}</strong>
                </div>
            @endif
        </div>

        {{-- Login field --}}
        <div class="row">
            <div class="col-7">
                <div class="icheck-primary">
                    <input type="checkbox" name="remember" id="remember">
                    <label for="remember">ログイン状態を記憶する</label>
                </div>
            </div>
            <div class="col-5">
                <button type=submit class="btn btn-block btn-flat btn-primary">
                    <span class="fas fa-sign-in-alt"></span>
                    ログイン
                </button>
            </div>
        </div>

    </form>
@stop

@section('auth_footer')
    {{-- Password reset link --}}
    @if($password_reset_url)
        <p class="my-0">
            <a href="{{ $password_reset_url }}">
                パスワードをお忘れの方
            </a>
        </p>
    @endif

    {{-- Register link --}} //登録機能は提供しないのでコメントアウト
    {{-- @if($register_url)
        <p class="my-0">
            <a href="{{ $register_url }}">
                {{ __('adminlte::adminlte.register_a_new_membership') }}
            </a>
        </p>
    @endif --}}
@stop

/resources/views/auth/auth-page.blade.php
{{-- 認証画面レイアウト --}}

@extends('layout.master')

@php( $dashboard_url = View::getSection('dashboard_url') ?? '/' )

@if (config('adminlte.use_route_url', false))
    @php( $dashboard_url = $dashboard_url ? route($dashboard_url) : '' )
@else
    @php( $dashboard_url = $dashboard_url ? url($dashboard_url) : '' )
@endif

@section('adminlte_css')
    @stack('css')
    @yield('css')
@stop

@section('classes_body'){{ ($auth_type ?? 'login') . '-page' }}@stop

@section('body')
    <div class="{{ $auth_type ?? 'login' }}-box">

        {{-- Logo --}}
        <div class="{{ $auth_type ?? 'login' }}-logo">
            <img src="{{ asset(config('adminlte.logo_img')) }}" height="50">
            <b>AdminLTE</b>
        </div>

        {{-- Card Box --}}
        <div class="card card-outline card-primary">

            {{-- Card Header --}}
            @hasSection('auth_header')
                <div class="card-header">
                    <h3 class="card-title float-none text-center">
                        @yield('auth_header')
                    </h3>
                </div>
            @endif

            {{-- Card Body --}}
            <div class="card-body {{ $auth_type ?? 'login' }}-card-body">
                @yield('auth_body')
            </div>

            {{-- Card Footer --}}
            @hasSection('auth_footer')
                <div class="card-footer">
                    @yield('auth_footer')
                </div>
            @endif

        </div>

    </div>
@stop

@section('adminlte_js')
    @stack('js')
    @yield('js')
@stop

{{-- 認証画面レイアウト --}}

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>

    {{-- Base Meta Tags --}}
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    {{-- Custom Meta Tags --}}
    @yield('meta_tags')

    {{-- Title --}}
    <title>AdminLTE 3 | Dashboard</title>
    {{-- Custom stylesheets (pre AdminLTE) --}}
    @yield('adminlte_css_pre')

    <!-- Tell the browser to be responsive to screen width -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Font Awesome -->
    <link rel="stylesheet" href={{ asset('/vendor/AdminLTE/3.0.5/plugins/fontawesome-free/css/all.min.css') }}>
    <!-- Ionicons -->
    <link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
    <!-- Tempusdominus Bbootstrap 4 -->
    <link rel="stylesheet" href={{ asset('vendor/AdminLTE/3.0.5/plugins/tempusdominus-bootstrap-4/css/tempusdominus-bootstrap-4.min.css') }}>
    <!-- iCheck -->
    <link rel="stylesheet" href={{ asset('vendor/AdminLTE/3.0.5/plugins/icheck-bootstrap/icheck-bootstrap.min.css') }}>
    <!-- JQVMap -->
    <link rel="stylesheet" href={{ asset('vendor/AdminLTE/3.0.5/plugins/jqvmap/jqvmap.min.css') }}>
    <!-- Theme style -->
    <link rel="stylesheet" href={{ asset('vendor/AdminLTE/3.0.5/css/adminlte.min.css') }}>
    <!-- overlayScrollbars -->
    <link rel="stylesheet" href={{ asset('vendor/AdminLTE/3.0.5/plugins/overlayScrollbars/css/OverlayScrollbars.min.css') }}>
    <!-- Daterange picker -->
    <link rel="stylesheet" href={{ asset('vendor/AdminLTE/3.0.5/plugins/daterangepicker/daterangepicker.css') }}>
    <!-- summernote -->
    <link rel="stylesheet" href={{ asset('vendor/AdminLTE/3.0.5/plugins/summernote/summernote-bs4.css') }}>
    <!-- Google Font: Source Sans Pro -->
    <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">

    {{-- Custom Stylesheets (post AdminLTE) --}}
    @yield('adminlte_css')
</head>

<body class="@yield('classes_body')" @yield('body_data')>

    {{-- Body Content --}}
    @yield('body')

        <!-- jQuery -->
        <script src={{ asset("vendor/AdminLTE/3.0.5/plugins/jquery/jquery.min.js") }}></script>
        <!-- jQuery UI 1.11.4 -->
        <script src={{ asset("vendor/AdminLTE/3.0.5/plugins/jquery-ui/jquery-ui.min.js") }}></script>
        <!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip -->
        <!-- Bootstrap 4 -->
        <script src={{ asset("vendor/AdminLTE/3.0.5/plugins/bootstrap/js/bootstrap.bundle.min.js") }}></script>
        <!-- ChartJS -->
        <script src={{ asset("vendor/AdminLTE/3.0.5/plugins/chart.js/Chart.min.js") }}></script>
        <!-- Sparkline -->
        <script src={{ asset("vendor/AdminLTE/3.0.5/plugins/sparklines/sparkline.js") }}></script>
        <!-- JQVMap -->
        <script src={{ asset("vendor/AdminLTE/3.0.5/plugins/jqvmap/jquery.vmap.min.js") }}></script>
        <script src={{ asset("vendor/AdminLTE/3.0.5/plugins/jqvmap/maps/jquery.vmap.usa.js") }}></script>
        <!-- jQuery Knob Chart -->
        <script src={{ asset("vendor/AdminLTE/3.0.5/plugins/jquery-knob/jquery.knob.min.js") }}></script>
        <!-- daterangepicker -->
        <script src={{ asset("vendor/AdminLTE/3.0.5/plugins/moment/moment.min.js") }}></script>
        <script src={{ asset("vendor/AdminLTE/3.0.5/plugins/daterangepicker/daterangepicker.js") }}></script>
        <!-- Tempusdominus Bootstrap 4 -->
        <script src={{ asset("vendor/AdminLTE/3.0.5/plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js") }}></script>
        <!-- Summernote -->
        <script src={{ asset("vendor/AdminLTE/3.0.5/plugins/summernote/summernote-bs4.min.js") }}></script>
        <!-- overlayScrollbars -->
        <script src={{ asset("vendor/AdminLTE/3.0.5/plugins/overlayScrollbars/js/jquery.overlayScrollbars.min.js") }}></script>
        <!-- AdminLTE App -->
        <script src={{ asset("vendor/AdminLTE/3.0.5/js/adminlte.js") }}></script>
        <!-- AdminLTE dashboard demo (This is only for demo purposes) -->
        <script src={{ asset("vendor/AdminLTE/3.0.5/js/pages/dashboard.js") }}></script>
        <!-- AdminLTE for demo purposes -->
        <script src={{ asset("vendor/AdminLTE/3.0.5/js/demo.js") }}></script>

    {{-- Custom Scripts --}}
    @yield('adminlte_js')

</body>

</html>

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?