以前、AdminLTEをLaravelのbladeでテンプレート化する方法を書きました。が、実際に管理画面を作るためには階層構造など、もう少し考える点があるので、それをまとめてみます。
やりたいこと
管理画面でよくあるトップメニュー(横メニュー)に、主メニュがあり、サイドバーメニュー(縦メニュー)にサブメニューがあるという構造において、最適なテンプレート化パターン(わいる分割・階層パターン)が良いかまとめたい。
なお、これは執筆時点(2015年8月8日)での「最適」なもので、随時更新します。
こんな画面を想定。
構造としてはTOPメニューとして
- 顧客管理(member)
- 在庫管理(item)
があり、各TOPメニューに対して、
- 新規登録
- 編集
のサブメニューがあるという構成。管理画面ではよくある構成です。
構造を考える
結論から言うと、下記のような構造にしました。
まず、全体的な構成としては、
- views以下に管理画面全体を入れるadminフォルダを作成。
- 管理画面全体に共通となる要素はshareフォルダに入れる。
- 各TOPメニュー毎にサブフォルダを作る(ここでは、memberとitem)。
サブフォルダの要素としては、
- sidebarはTOPメニュー毎に違うので各サブフォルダ内に作成。
- sidebarメニューに紐づくファイルをそれぞれ作る(ここではnewとedit)。
その他の特記事項としては、
- メニューの選択状態は各ページにおいてjQueryでaddclass("active")とすることで実現。
- なので、TOPメニューとサイドメニューの各メニューにid(もしくはclass)を設定し制御します。
としました。
コードを考える
コードの要点を見てみます。
まず、このテンプレート構造の中心となるファイルはviews/admin/share/layoutです。
少し長いですが、重要な構造なので、全部貼り付けます。
<!doctype html>
<head>
<meta charset="utf-8">
<title>
@yield('title')
</title>
<!-- for responsive -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- bootstrap -->
<link href="{{asset("bower_components/admin-lte/bootstrap/css/bootstrap.min.css")}}" rel="stylesheet" type="text/css" />
<!-- font awesome -->
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<!-- ionicons -->
<link href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet" type="text/css" />
<!-- adminLTE style -->
<link href="{{asset("bower_components/admin-lte/dist/css/AdminLTE.min.css")}}" rel="stylesheet" type="text/css" />
<link href="{{asset("bower_components/admin-lte/dist/css/skins/skin-blue.min.css")}}" rel="stylesheet" type="text/css" />
<style>
.navbar-nav>li.active>a{
background-color: #666;
}
</style>
</head>
<body class="skin-blue">
<div class="wrapper">
<!-- ヘッダー -->
@include('admin.share.header')
<!-- サイドバー -->
{{-- @include('share.sidebar') --}}
@yield('sidebar')
<!-- content -->
<div class="content-wrapper">
<!-- コンテンツヘッダ -->
@yield('content')
</div><!-- end content -->
<!-- フッター -->
@include('admin.share.footer')
</div><!-- end wrapper -->
<!-- JS -->
<!-- jquery -->
<script src="{{asset("bower_components/admin-lte/plugins/jQuery/jQuery-2.1.4.min.js")}}" type="text/javascript"></script>
<!-- bootstrap -->
<script src="{{asset("bower_components/admin-lte/bootstrap/js/bootstrap.min.js")}}" type="text/javascript"></script>
<!-- adminLTE -->
<script src="{{asset("bower_components/admin-lte/dist/js/app.min.js")}}" type="text/javascript"></script>
<!-- chart.js -->
<script src="{{asset("bower_components/admin-lte/plugins/chartjs/Chart.min.js")}}" type="text/javascript"></script>
<!-- JS記述 -->
@yield('sctipt')
</body>
</html>
要点はおおよそ次の箇所です(行番号打ちたい)。
- @yield('title') タイトルは動的に変更できるようにしました。
- @include('admin.share.header') TOPメニュー部は共通要素なので、共通化しincludeします。
- @yield('sidebar') サイドバーは動的要素になるのでincludeではなく、@yieldとし、各ファイルで定義。
- @yield('content') コンテンツは当然動的要素になるので@yieldとして各ファイルで定義。
- @include('admin.share.footer') フッター部は共通要素なので、共通化しincludeします。
- @yield('sctipt') 各ページで必要となるjsを記述する場所を@yieldで定義。場所は各JSファイルの読み込み後とします。
参照先になっているテンプレートファイルのコードは、こちらの記事を参考にしてください(ここでは長くなるので割愛)。
あと、<head>...</head>の最後に、
<style>
.navbar-nav>li.active>a{
background-color: #666;
}
</style>
を追加し、TOPメニューの<li class="active">記述時のbackground-colorを定義しています(何故か、AdminLTEでは定義されていないため)。
追記:2.2.3では修正されているようなので不要です。
各要素を見てみる
では、顧客管理メニュー(member)のファイルを見てみます。
新規作成(new)のファイルです。
@extends('admin.share.layout')
@section('title')
Member Management
@stop
@section('sidebar')
@include('admin.member.sidebar')
@stop
@section('content')
<section class="content-header">
<h1>Member</h1>
<ol class="breadcrumb">
<li><a href="">Home</a></li>
<li>Memeber</li>
<li>New</li>
</ol>
</section>
<section class="content">
<div class="box">
<div class="box-body">
content
</div>
</div>
</section>
@stop
@section('sctipt')
<script>
$(function(){
$("#member").addClass("active");
$("#new").addClass("active");
});
</script>
@stop
要点としては、
まず、テンプレートの呼び出し、
@extends('admin.share.layout')
これはshareで定義したメインのLayoutです。
そして、
@section('sidebar')
@include('admin.member.sidebar')
@stop
の箇所で、同じフォルダにあるsidebar.blade.phpを呼び出している点、
@section('sctipt')
<script>
$(function(){
$("#member").addClass("active");
$("#new").addClass("active");
});
</script>
@stop
の箇所で、jsを実行し、選択されたTOPメニューと再度メニューにclass="active"を付与しているところです。もちろん、制御されるメニューにはid定義が必要です。
サイドメニューの方は各機能毎にファイルができるので直接class="active"をハードコーディングしてもいいでしょう。
ちなみに、サイドメニュー(sidebar.blade.php)は、
<!-- サイドバー -->
<aside class="main-sidebar">
<section class="sidebar">
<ul class="sidebar-menu">
<!-- メニューヘッダ -->
<li class="header">顧客管理機能一覧</li>
<!-- メニュー項目 -->
<li id="new"><a href="/admin/member/new">新規登録</a></li>
<li id="edit"><a href="/admin/member/edit">編集</a></li>
</ul>
</section>
</aside><!-- end sidebar -->
こんな感じです。
実務向け
少し発展させたものを、直ぐにLaravelに反映させられるようにしておきます。
自動化してもいいですが、とりあえず手動モード。
Laravelのインストール
とりあえずtestという名前で作成。
composer create-project laravel/laravel test
AdminLTEインストール
Laravelのpublicフォルダにadmin-lteをインストールします。
cd test/public
bower install admin-lte
このとき - を忘れずに。adminlteという別のリポジトリがある。
下の注意書きも読んで下さい。
テンプレートインストール(展開)
ダウンロードして、展開したadminフォルダをresources/views/以下に展開
ルートを設定
//member
Route::get('admin/member',function(){
return view('admin.member.index');
});
Route::get('admin/member/new',function(){
return view('admin.member.new');
});
Route::get('admin/member/edit',function(){
return view('admin.member.edit');
});
//item
Route::get('admin/item',function(){
return view('admin.item.index');
});
Route::get('admin/item/new',function(){
return view('admin.item.new');
});
Route::get('admin/item/edit',function(){
return view('admin.item.edit');
});
//login
Route::get('admin/login',function(){
return view('admin.login');
});
注意
ここでは、bowerで各種ライブラリをインストールしているので、基本的に最新版がインストールされます。その場合、adminテンプレート中(admin/share/layout.blade.php)のCDNのURL等に不整合が発生する可能があります。その際は、ダンロードされたAdminLTEフォルダ(bower_components/admin-lte)の中のstarter.htmlを参考にしながら、CDNのURLやローカルPathを修正するとよいでしょう。
以上です。