[CakePHP]WordPressよりもckeditor/ckfinderを使ってみた

[CakePHP 2.2.3]

1月から、「みんなの英語ひろば」で記事コンテンツを配信し始めました。

http://eigohiroba.jp/t

当初、ベースのシステムはCakePHP、記事コンテンツWordPressと分けていたのですが、この2つのシステムの相性がよろしくないので、記事コンテンツ向けにWordPressはやめて、普通にCakePHPで作ることにしました。

3日程で作ることができたのですが、、今回ご紹介するckeditorとckfinderというツールのおかげでかなり楽でした。こちらはjavascriptでテキストエリアに簡単に機能を付加できる多機能エディタで、本当に、かなりのスグレモノです。

ちなみに、ckeditorが本体で、ckfinderは追加機能で、画像アップロード機能を追加するのに使いました。

2013 01 27 1831

導入方法は簡単

CakePHPの場合、それぞれダウンロードしたファイルを、以下に配置します。

app/webroot/js/ckeditor/

app/webroot/js/ckfinder/

そして、使用したいビューの中で、以下のように呼び出すだけです。

[php]
<?php $this->Html->script(‘ckeditor/ckeditor’, array(‘inline’ => false));?>
<?php $this->Html->script(‘ckfinder/ckfinder’, array(‘inline’ => false));?>

<?=$this->Form->input(‘body’, array(‘class’=>’ckeditor’, ‘id’=>’editor1’))?>
[/php]
[js]
<script type="text/javascript">
if (typeof CKEDITOR != ‘undefined’) {
var editor = CKEDITOR.replace( ‘editor1’ );
CKFinder.setupCKEditor( editor, ‘/js/ckfinder/’ ) ;
}
</script>
[/js]

実装例

2013 01 27 1841

ckeditorを読み込んだ場合、テキストエリアがこのように変わります。

2013 01 27 1842

エディタ上にあるボタンのうち、「イメージ」ボタンをおすとこのようなウインドウが開きます。

2013 01 27 1843

アップロード機能(ckfinderがちゃんと読み込まれていればこのアップロードタブが出てきます)

2013 01 27 1844

さらに、「イメージ」ウインドウから過去にアップロードした画像一覧を見ることもできます。
こちらもckfinderの機能です。

CakePHPとWordPressを一緒に動作させると2つのシステムを管理するのが大変になってしまいます。簡単なブログ機能で良い場合、ckeditorを候補に入れてみるのはいかがでしょうか。

[CakePHP]scripts_for_layoutへのmeta(noindex等)の渡し方

[CakePHP1.3.11, 2.1.3]

CakePHPはコンテンツ部分をレイアウトに埋め込む、いわゆるレイアウトテンプレート型のビューなので、scripts_for_layout変数などを使って、コンテンツ部分からレイアウト部分にページ特有のcssやjsファイルなどを読み込ませることが出来るわけですが、このコンテンツ部分からレイアウトへの渡し方がバージョンによって異なるのでお気をつけ下さい、というエントリです。

1.2〜1.3の場合

※コンテンツ部分のビューファイルです。contacts/index.ctp等

[php]
<?php $html->meta(null, null, array(‘name’ => ‘robots’, ‘content’ => ‘noindex,follow’, ‘inline’ => false));?>
[/php]

2.x〜の場合

[php]
<?php $this->Html->meta(null, null, array(‘name’ => ‘robots’, ‘content’ => ‘noindex,nofollow’), false);?>
[/php]

もちろん、layoutファイルには、<head>タグ内に以下を入れるのをお忘れなく。

[php]
<?=$scripts_for_layout?>
[/php]

[CakePHP]コントローラー内で一時的に一部validateを無効にする方法

[CakePHP1.2.3]

コントローラ内でvalidationをする際に、全てoffにするのは簡単です。

[php]
$this->Model->save($data, false);
[/php]

と、saveの第二引数にfalseをセットします。

しかし、一部のvalidationのみoffにしたい場合もあるでしょう。そういうときはどうすればいいのでしょうか。
実は、単純に以下のようにするだけなのでした。

[php]
//コントローラ内
unset($this->Account->validate[‘crosslink_url’]);
[/php]

他にも、モデル内でsetValidateなどのメソッドを作って切り替える、などの方法も考えられます。

[CakePHP]paginateではbindModelの第二引数にfalseが必要

[CakePHP1.2.3]

なんか、今開発中なのでしょうがないですが、最近CakePHPのネタばかり書いています。

今回は、コントローラ内でpaginateを呼び出す前にbindModelする際の注意点です。

通常では、paginateはモデル内で定義されたアソシエーションの設定通りにデータを取得します。
しかし、取得前に、bindModelやunbindModelでアソシエーションを一時的に変更することがあると思います。

例えば、Tagのidで絞り込んだArticleの一覧が欲しい場合があります。

そのような時は、以下のようにします。

[php]
//コントローラ内
$this->Article->bindModel(array(‘hasOne’ => array(‘ArticlesTag′)), false);
$this->paginate = array(
‘conditions’ => array(‘ArticlesTag.tag_id’ => $tag_id)
);
$articles = $this->paginate(‘Article’);
[/php]

一番上の、bindModelメソッドの第二引数にfalseを入れるのがミソです。これを入れないと正しく動作してくれません。
この第二引数は、モデルのfindメソッド実行後にモデル内のアソシエーション設定に戻すかどうかのフラグです。
falseを入れると、findメソッドが1回呼ばれた後でもbindした設定が有効になったままになります。

この設定が必要な理由は、pagination呼び出し時に件数を数えるfindと、データを取得するfind、計2回findメソッドが呼ばれるためです。こちらはなかなか気づきにくいところですので、お気をつけ下さい。

[CakePHP]カスタムpaginationを使い分ける方法

[CakePHP1.2.3]

カスタムpaginationはモデル内で、paginateメソッドをオーバーライドすることで、実現できます。

しかしこの方法の欠点としては、このモデルの全てのpaginationでこのカスタム仕様が有効になってしまうことです。例えば、公開ページはカスタム設定を使いたいけれども、管理画面ではカスタム設定を使いたくないという場合はあるかと思います。今回私もそういう使い方をする必要があり、解決方法を考えてみました。

解決方法としては、以下のように、メソッドの第7引数のextra変数を使って切り分けるのが良さそうです。

[php]
//モデル内
function paginate($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null, $extra = array()) {

if (!empty($conditions)) {
$params[‘conditions’] = $conditions;
}
if (!empty($fields)) {
$params[‘fields’] = $fields;
}
if (!empty($order)) {
$params[‘order’] = $order;
}
if (!empty($limit)) {
$params[‘limit’] = $limit;
}
if (!empty($page)) {
$params[‘page’] = $page;
}
if (!empty($recursive)) {
$params[‘recursive’] = $recursive;
}

if (!empty($extra[‘type’]) && $extra[‘type’] == ‘custom’) {
//カスタム設定
return $this->find(‘custom’, $params);
}
else {
//普通のpagination設定
return $this->find(‘all’, $params);
}
}
[/php]

コントローラ側のpaginate設定では、以下の様にします。

[php]
//コントローラー内
$this->paginate = array(
‘conditions’ => array(‘各種条件’),
‘type’ => ‘custom’,
);
[/php]

これで問題なくカスタムpaginationの動作を切り替えることが出来るようになりました。めでたしめでたし。