CakePHP4にAdminLTEを適用する

2020年11月13日

前回、以下の記事でCakePHPのbakeコマンドを使用して、画面を作成しました。

CakePHP4では、CakePHP3に比べ、デザインも綺麗になった感がありますが、今回はAdminLTEを適用してみようと思います。
本記事では2020年10月現在の最新版であるCakePHP4.1.5を使用しています。

AdminLTEとは?

AdminLTEとは、Bootstrapベースで作られたCSSフレームワークです。
主に、管理画面の作成に特化していますが、様々なデザインが準備されているので、多岐に渡って使用できると思います。

左側のサイドメニューや、グラフ、表など、様々なデザインが用意されています。

・AdminLTE公式サイト
https://adminlte.io/

様々なデザインは以下のページから確認できます。
https://adminlte.io/themes/v3

ユーザーを登録する画面にAdminLTEを適用する

前回の記事で以下のような画面を作成しました。

登録する画面

このデザインをAdminLTEに変更していきます。
AdminLTEに以下のような登録画面のテンプレートが用意されているので、それを使用します。

AdminLTEの登録画面テンプレート

画面は以下のURLから確認できます。
https://adminlte.io/themes/v3/pages/examples/register.html

レイアウトを作成する

レイアウトには、ヘッダーやフッターなど、各ビューで共通になる部分を記載します。
レイアウトのファイルはデフォルトで、「templates/layout/default.php」となります。

今回は、左サイドメニューが無いレイアウトを作成したいので、「templates/layout/side_menu_none.php」というファイルを新規で作成しました。

<?php
/**
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link          https://cakephp.org CakePHP(tm) Project
 * @since         0.10.0
 * @license       https://opensource.org/licenses/mit-license.php MIT License
 * @var \App\View\AppView $this
 */
?>
<!DOCTYPE html>
<html>
<head>
  <?= $this->Html->charset() ?>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>AdminLTE 3 | <?= $this->fetch('title') ?></title>
  <!-- Tell the browser to be responsive to screen width -->
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <?= $this->Html->meta('icon') ?>

  <!-- Font Awesome -->
  <?= $this->Html->css('//pro.fontawesome.com/releases/v5.10.0/css/all.css') ?>
  <!-- Ionicons -->
  <?= $this->Html->css('//code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css') ?>
  <!-- icheck bootstrap -->
  <?= $this->Html->css('//cdnjs.cloudflare.com/ajax/libs/icheck-bootstrap/3.0.1/icheck-bootstrap.min.css') ?>
  <!-- Theme style -->
  <?= $this->Html->css('//cdnjs.cloudflare.com/ajax/libs/admin-lte/3.0.5/css/adminlte.min.css') ?>
  <!-- Google Font: Source Sans Pro -->
  <?= $this->Html->css('//fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700') ?>

  <?= $this->fetch('meta') ?>
  <?= $this->fetch('css') ?>
  <?= $this->fetch('script') ?>
</head>
<body class="hold-transition register-page">
<div class="register-box">
  <div class="register-logo">
    <a href="../../index2.html"><b>Admin</b>LTE</a>
  </div>

  <div class="card">
    <div class="card-body register-card-body">
      <?= $this->Flash->render() ?>
      <?= $this->fetch('content') ?>
    </div>
    <!-- /.form-box -->
    </div><!-- /.card -->
</div>
<!-- /.register-box -->

<!-- jQuery -->
<?= $this->Html->script('//code.jquery.com/jquery-3.5.1.min.js') ?>
<!-- Bootstrap 4 -->
<?= $this->Html->script('//stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js') ?>
<!-- AdminLTE App -->
<?= $this->Html->script('//cdnjs.cloudflare.com/ajax/libs/admin-lte/3.0.5/js/adminlte.min.js') ?>
</body>
</html>

レイアウトファイルでは、AdminLTEで使用するCSSやscriptの読み込みをCakePHPの構文に置き換えます。

コントローラーを修正する

先ほど作成したレイアウトを使用する設定をコントローラーに追加します。
以下のようにaddメソッドの一番下にレイアウトの設定を追加しました。

    public function add()
    {
        $user = $this->Users->newEmptyEntity();
        if ($this->request->is('post')) {
            $user = $this->Users->patchEntity($user, $this->request->getData());
            if ($this->Users->save($user)) {
                $this->Flash->success(__('The user has been saved.'));

                return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('The user could not be saved. Please, try again.'));
        }
        $this->set(compact('user'));
        $this->viewBuilder()->setLayout('side_menu_none');
    }

ビューを修正する

ビューのファイル「templates/Users/add.php」を以下のように修正します。
まずは、formタグとボタンをCakePHPの構文に修正し、FacebookとGoogle+のログインは除いています。

<?php
/**
 * @var \App\View\AppView $this
 * @var \App\Model\Entity\User $user
 */
?>
<?php
    $this->assign('title', 'ユーザー登録');
?>
<p class="login-box-msg">Register a new membership</p>

<?= $this->Form->create($user) ?>
<div class="input-group mb-3">
    <input type="text" class="form-control" placeholder="Full name">
    <div class="input-group-append">
    <div class="input-group-text">
        <span class="fas fa-user"></span>
    </div>
    </div>
</div>
<div class="input-group mb-3">
    <input type="email" class="form-control" placeholder="Email">
    <div class="input-group-append">
    <div class="input-group-text">
        <span class="fas fa-envelope"></span>
    </div>
    </div>
</div>
<div class="input-group mb-3">
    <input type="password" class="form-control" placeholder="Password">
    <div class="input-group-append">
    <div class="input-group-text">
        <span class="fas fa-lock"></span>
    </div>
    </div>
</div>
<div class="input-group mb-3">
    <input type="password" class="form-control" placeholder="Retype password">
    <div class="input-group-append">
    <div class="input-group-text">
        <span class="fas fa-lock"></span>
    </div>
    </div>
</div>
<div class="row">
    <div class="col-8">
    <div class="icheck-primary">
        <input type="checkbox" id="agreeTerms" name="terms" value="agree">
        <label for="agreeTerms">
        I agree to the <a href="#">terms</a>
        </label>
    </div>
    </div>
    <!-- /.col -->
    <div class="col-4">
    <?= $this->Form->button(__('Register'), ['class' => 'btn btn-primary btn-block']) ?>
    </div>
    <!-- /.col -->
</div>
<?= $this->Form->end() ?>

<a href="login.html" class="text-center">I already have a membership</a>

この時点では、画面は以下のようになります。

AdminLTE適用後

続いて、各入力項目にCakePHPを適用します。
前回の記事で作成したusersテーブルは「nickname」を定義していたので、「Full name」を「nickname」に変更し、以下のようにCakePHPの構文に変更します。

<?= $this->Form->control('nickname', ['placeholder' => 'ニックネームを入力してください']) ?>

これで画面を表示すると、以下のようになります。

「nickname」にAdminLTEのスタイルが適用されていないので修正します。

CakePHPの場合、タグごとにどういう構成でHTMLが出力されるかというのが決まっています。
今回の場合は、以下のようにHTMLが出力されます。

<div class="input text required">
  <input type="text" name="nickname" placeholder="ニックネームを入力してください"
    required="required" data-validity-message="This field cannot be left empty" oninvalid="this.setCustomValidity(''); if (!this.value) this.setCustomValidity(this.dataset.validityMessage)" oninput="this.setCustomValidity('')"
    id="nickname" maxlength="50">
</div>

この場合、inputタグに「form-control」というclassが付いていなかったり、inputタグがdivタグに囲われています。

これを修正するには、各項目ごとにスタイルを適用しても良いのですが、CakePHPではフォームのテンプレートとして、各項目を設定できる機能があるので、テンプレートを使用します。

formタグの前に以下の記述を追加します。

<?php
    $this->Form->setTemplates([
        'inputContainer' => '{{content}}',
        'input' => '<input type="{{type}}" class="form-control" name="{{name}}"{{attrs}}/>',
        'label' => false,
    ]);
?>

テンプレートを追加することで、inputタグの構成と、inputタグを囲むdivタグ、labelタグを無くすという設定をしています。

テンプレートを使用しない場合は、予めタグの種類によって、タグの構成がどうなっているかがデフォルトで決まっています。
内容については以下をご覧ください。
https://api.cakephp.org/3.8/class-Cake.View.Helper.FormHelper.html#%24_defaultConfig

また、合わせて「nickname」以外の項目にもCakePHPの構文を適用しておきます。
フォームのテンプレートを設定することで、以下のような画面になりました。

AdminLTE適用後

AdminLTE適用後の動きを確認する

ここまでで、AdminLTEを適用してデザインの修正ができたので、動きの確認をしてみます。
以下のように入力して、「Register」ボタンをクリックします。

すると、データの登録が行われ、以下のように一覧画面が表示されます。
登録したデータも表示されることが確認できました。

AdminLTEは様々なデザインが用意されていて使いやすい

CakePHPにAdminLTEを適用してみました。

AdminLTEはデザインの種類も豊富ですし、適用するにもテンプレートをコピーして使えるので、大変便利だと思います。

本記事で紹介したのは、登録画面というシンプルなものでしたが、管理画面の作成などAdminLTEで出来ることはたくさんありますので、ぜひ試してみてください。