2012年8月1日水曜日

[Cakephp2.2][Twitter bootstrap2.0.4]CakephpでTwitter bootstrapのサンプルサイトを作る。その5

最近オリンピックのサッカーの試合みてばかりで寝不足です。目指せアベック優勝!!!

Controllerの概要

Controllerの役目

CakephpのControllerは色々と指示を出す人です。多分、日本名は魂斗羅くんです。流行りのキラキラネームですが、仕事はできるヤツです。
魂斗羅くんはユーザーの注文を受け取って、ModelやView(美優さん)をこき使い、ユーザーに正しく返答できるようにするのが責任範囲です。
関係ないModelやViewは呼び出しません。必要に応じて美優さんに助っ人つけます。そんな感じの仕事をしてます。

PagesControllerを改造する

今までの所index.ctpでレイアウトを指定してますが、これをPagesControllerで指定するように変更します。
index.ctpのレイアウトを設定している部分を削除します。

app/View/Pages/index.ctp
<?php 
//$this->layout = "guest";
?>
...
 
PagesControllerのindexメソッドにレイアウトをguestに設定します。
app/Controller/PagesController
...

 public function index(){
  $this->layout = "guest";
 }
 
...
ブラウザで「dream-travel.boo.jp/twitter_bootstrap_2.0.4/」にアクセスします。

見た目が変わらないので、よく分かりませんがとりあえずOKです。

他のページを追加する。

とりあえず1ページだけ追加してみます。まず、routesの設定をコメントアウトします。

app/Config/routes.php
...
// Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display')); //コメントアウトします。
...
 
これは、urlが「/pages/hoge」や「/pages/page」とかなら、PagesControllerのdisplayメソッドを呼び出すようにしているので無効にしています。
後は簡単で2箇所修正します。コントローラにメソッドを追加します。
app/Controller/PagesController
...

 public function index(){
  $this->layout = "guest";
 }
 //add
 public function scaffolding() {
  $this->layout = "guest";
 }

...
Viewも追加します。中身はまあ、ここでは適当にしておきます。
app/View/Pages/scaffolding.ctp
<?php 
?>
<div class="row">
 <div class="span3">サイド</div>
 <div class="span9">scaffolding</div>
</div>

ブラウザで「dream-travel.boo.jp/twitter_bootstrap_2.0.4/pages/scaffolding」にアクセスします。

... 相変わらず変化しないので、分かりづらいですがOKのようです。

色々と試す

ここで色々と試してみたいと思います。とりあえず以下の用にscaffoldingメソッド内でレイアウトをdefaultに指定してみます。

app/Controller/PagesController
...

 public function index(){
  $this->layout = "guest";
 }
 public function scaffolding() {
  $this->layout = "default";
 }

...
ブラウザで各アドレスにアクセスします。
「dream-travel.boo.jp/twitter_bootstrap_2.0.4/」

「dream-travel.boo.jp/twitter_bootstrap_2.0.4/pages/scaffolding」

scaffoldingの方はCakephpデフォルトのレイアウトが適応されてます。つまりメソッド毎にレイアウトを振り分ける事ができます。


もう一つ試します。PagesControllerのメンバでレイアウトを設定してみます。
app/Controller/PagesController
...
 
/**
 * This controller does not use a model
 *
 * @var array
 */
 public $uses = array();
 
 public $helpers = array('B99TwitterBootstrap');
 
 public $layout = "guest";

...

 public function index(){
  //$this->layout = "guest"; ←実際は削除する。
 }
 public function scaffolding() {
  //$this->layout = "default"; ←実際は削除する。
 }
 
...
ブラウザで各アドレスにアクセスします。
「dream-travel.boo.jp/twitter_bootstrap_2.0.4/」

「dream-travel.boo.jp/twitter_bootstrap_2.0.4/pages/scaffolding」

両方共guestのレイアウトが適応されてます。メソッド毎に変えないという事ならこれでも良いです。

もっと汎用的にレイアウトを設定する

上記の方法でそれぞれレイアウトを設定しても問題ないのですが、Cakephp1.3で何個かサイト作った経験で私は定形的以下の方法でやってます。
1.AppControllerを修正します。beforeFilter()を追加して、その中に条件付きでレイアウト設定します。

app/Controller/AppControllerを修正
...

class AppController extends Controller {
 
 public function beforeFilter(){
  //レイアウトの設定
  if (Configure::read('debug') == 0) {
   $this->layout = "guest";
  }
 }
}
  
Cakephp的に全てのコントローラはAppControllerを継承する必要があります。なのでこのコントローラで設定した事は全てのコントローラに適応されます。
また、beforeFilter()メソッドはCakephpのコールバックの1つで、コントローラの各アクションの前に実行されます。
Configure::read('debug')はapp/Config/core.phpで設定するデバッグのレベルを取得します。
なのでここで追加した内容は、「全てのコントローラのアクション実行前にデバッグレベルが0だったらレイアウトをguestに設定する」という事をしてます。

2.各コントローラにbeforeFilter()を追加して、その中に条件付きでレイアウト設定します。ここではPagesControllerを修正します。
app/Controller/PagesController
 ...
 
 // public $layout = "guest"; //←実際は削除
 
 ...
 
 public function beforeFilter(){
  //レイアウトの設定
  if ('CakeError' === $this->name && Configure::read('debug') > 0){
   $this->layout = "defalut";
  } else if('admin' === $this->request['prefix']) {
//   $this->layout = "admin";
  } else {
   $this->layout = "guest";
  } 
 }
 
この追加は何をしているかと言うと、PagesControllerの各アクション前に
  1. エラーがあるかつデバッグレベルが0を超えていたらレイアウトはdefalut
  2. 管理者用のアクセスだったらレイアウトはadmin
  3. それ以外はguest
という事をやっています。管理者のアクセスについてはここでは説明省きますが、とにかくユーザーアクセスの状態によってレイアウト設定を振り分けてます。

汎用的にレイアウトを設定した場合アクセス結果

上の修正をした時のアクセス結果のスクショです。

URL デバッグレベル 2 デバッグレベル 0
dream-travel.boo.jp/twitter_bootstrap_2.0.4/
dream-travel.boo.jp/twitter_bootstrap_2.0.4/pages/hoge
dream-travel.boo.jp/twitter_bootstrap_2.0.4/hoge
いかがでしょうか?まあ、これはあくまでも私が個人的いいなと思っている方法なので色々とアラがあるかもしれませんが、良かったら皆さんも試してみて下さい。

まとめ

  • コントローラで色々と仕事を振り分ける
  • 設定をコントローラで行う事もある
  • AppControllerとかコールバック関数とかがある

環境とか

項目内容
PHPフレームワークCakephp 2.2.0
IDEEclipse 3.6
開発環境?MAMP
PCMacmini
OSMac OS Lion

0 件のコメント:

コメントを投稿