1月 2012のアーカイブ
Kohana で pjax をしてみたよ!
先日作成した簡単なページのページネーション部を pjax で動作するようにしてみました!
pjax については google で検索するといっぱいでてくるので、そちらを参照してください(´・ω・`)
Kohana PHP で実現するために、まずはモジュールを探してみました!
Kohana には http://kohana-modules.com/ というサイトがあり、現時点(2012/1/6)で 605 ものモジュールが登録されています。早速探してみると…あったあった、ありました!
(※ 他にも Facebook だったり Twitter だったり google map だったり、いろいろと便利なモジュールが用意されていますよ! )
Kopjax – Pjax jQuery ajax module for Kohana 3.1(.2)
https://github.com/cambiata/kopjax
セットアップ
モジュールをダウンロードし modules/ ディレクトリに解凍。 ディレクトリ名称を kopjax にしました。
モジュールを追加したら bootstrap.php に追記しましょう。
/** * Enable modules. Modules are referenced by a relative or absolute path. */ Kohana::modules(array( // 'auth' => MODPATH.'auth', // Basic authentication // 'cache' => MODPATH.'cache', // Caching with multiple backends // 'codebench' => MODPATH.'codebench', // Benchmarking tool 'database' => MODPATH.'database', // Database access // 'image' => MODPATH.'image', // Image manipulation 'orm' => MODPATH.'orm', // Object Relationship Mapping // 'unittest' => MODPATH.'unittest', // Unit testing // 'userguide' => MODPATH.'userguide', // User guide and API documentation 'pagination' => MODPATH.'pagination', 'kopjax' => MODPATH.'kopjax', ));
一番下に追加しました。
pagination モジュールのリンクを変える
前回の記事のままでは、ページ指定が query_string 設定となり ?page_id= となっていました。 これを route 設定に変更します。
Route::set() を追加
ルーティングを追加して、ページの指定をURLに含ませる形式を設定します。
application/bootstrap.php に追記します。
Route::set('top', '(<page_id>)', array('page' => '[0-9]+'))
->defaults(array(
'controller' => 'top',
'action' => 'index',
'page_id' => null,
));
Controller_Top の、 action_index() でページを切り替えます。 URL にすると http://www.example.com/1 などと数値がページ送りid(page_id) になります。
pagination の設定を変更
$pagination = Pagination::factory(array(
'item_per_page' => 10,
'total_items' => $all_address->count_all(),
'current_page' => array(
'source'=> 'route',
'key' => 'page_id'),
'auto_hide' => false,
'first_page_in_url' => false,
));
current_page の source の部分を query_string から route に変更しました。
リンクを pjax 対応にする
モジュールには pjaxdemo というコントローラやビューファイルが用意されており、これを参考に書き換えます。
コントローラ
最初に Controller_Top を変更します。
ajax(pjax)出力か通常の出力かを判定しビューを切り替えて出力する様です。 CakePHP には beforeFilter() や afterFilter() のほか、 beforeRender() などありますが、 KohanaPHP には before() および after() の2種類のコールバックがあります。 このコールバックを利用し、複数のアクションに対して処理を行うようにします。
public function after()
{
if (!$this->request->is_ajax()) {
$this->view = View::factory('pjax/template');
} else {
$this->view = View::factory('pjax/content');
}
$this->view->set('content', $this->content);
$this->response->body($this->view);
}
ajax の場合には pjax/template を。通常のアクセスの場合は pjax/content を読み込む形になるようです。
ビュー
コントローラで指定した pjax/template および pjax/content を用意します。
もちろん、ひな形となるファイルはモジュール kopjax の中に views/pjax/ 以下にそれぞれファイルがありますので、この2つのファイルを application/views/ の下に pjax ディレクトリを作成してコピーします。
※ そのままでも良いのですが、サンプル用のリンクなどがある為。
template.php
<html>
<head>
<title>address</title>
</head>
<?php $mediabase = Route::url('media'); ?>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"></script>
<script type="text/javascript" src="<?php echo $mediabase ?>/pjax/js/jquery.pjax.js"></script>
<script type="text/javascript">
$(function(){
// pjax
$('a').pjax('#content')
})
</script>
</head>
<body>
<div id="content">
<?php echo View::factory('pjax/content')->set('content', $content) ?>
</div>
<?php echo date('Y-m-d H:i:s'); ?>
</body>
</html>
サンプルにあったデモ用のリンクを削除し、pjax化するリンクの対象をアンカータグすべてに変更しました。
content.php
<?php echo $content; ?> <hr /> <?php echo (Request::current()->is_ajax()) ? 'Content part loaded using Ajax' : 'Whole page loaded using standard Page refresh'?>
3行目で、ajax で表示されているか、通常読み込みされたかどうかが表示されるようになっています。
おわり
あとは、データを10件以上登録しページ送りをしてみてください。
Content part loaded using Ajax
と表示され、その下の時刻もページを切り替えても書き換わらず、同じ時間が表示されています。そして、2ページ目などが表示されている状態で、再読み込みをすると、2ページ目のまま、最下部の表示が以下のように変わるはずです。
Whole page loaded using standard Page refresh
Kohana データベースへの登録とページネーション 〜 ページネーション 〜
データベース登録できたので、次はページネーションを。
同梱モジュールには含まれていない様子だったので、さっさとググッて見つけてきました。
kloopko / kohana-pagination [ https://github.com/kloopko/kohana-pagination ]
ページからダウンロードしてきて、展開したら modules/ 以下にコピーします。
次に bootstrap.php に追加。
/**
* Enable modules. Modules are referenced by a relative or absolute path.
*/
Kohana::modules(array(
// 'auth' => MODPATH.'auth', // Basic authentication
// 'cache' => MODPATH.'cache', // Caching with multiple backends
// 'codebench' => MODPATH.'codebench', // Benchmarking tool
'database' => MODPATH.'database', // Database access
// 'image' => MODPATH.'image', // Image manipulation
'orm' => MODPATH.'orm', // Object Relationship Mapping
// 'unittest' => MODPATH.'unittest', // Unit testing
// 'userguide' => MODPATH.'userguide', // User guide and API documentation
'pagination' => MODPATH.'pagination',
));
pagination というディレクトリでコピーしたので MODPATH.’pagination’ となっています。
追記するのはコントローラーとビューの2つ。
コントローラーに追記
$_POST の if 文の前に追加します。
$all_address = ORM::factory('address');
$pagination = Pagination::factory(array(
'item_per_page' => 10,
'total_items' => $all_address->count_all(),
));
$addresses = $all_address->limit($pagination->items_per_page)
->offset($pagination->offset)
->find_all();
$view = View::factory('address/create')
->set('pagination', $pagination)
->set('addresses', $addresses)
->bind('errors', $errors);
特に絞り込むような条件もないので、全件の件数を 4行目で pagination に設定し、1ページ10件ずつ(item_per_page) に設定します。
10件ずつ区切って表示するため、 limit() および offset() にそれぞれ、 item_per_page と offset を指定し取得範囲を変動させます。
結果を、先ほどの view に set() でビューに渡せば完了です。
ビューに追記
<?php
echo $pagination->render();
?>
<?php echo $pagination->total_items; ?>件登録があります
<table>
<? foreach ($addresses as $address): ?>
<tr>
<td><?php echo $address->firstname; ?></td>
<td><?php echo $address->lastname; ?></td>
</tr>
<?php endforeach; ?>
</table>
create.php に最後に上記を追記。
1行目の render() によって、ページ送りが表示されます。
また、このままではページ送りが First や Last、Next といった英語表記になっています。
しかし i18n による国際化の仕組みによって日本語にすることができます。
application/i18n/ に配下に ja.php ファイルを作成。
以下のように記述します。
<?php defined('SYSPATH') or die('No direct script access.');
return array(
'First' => '最初へ',
'Previous' => '前へ',
'Next' => '次へ',
'Last' => '最後へ',
);
これによって、日本語表示になります。
Kohana データベースへの登録とページネーション 〜 登録 〜
先日のセットアップから引き続き。
今度は、データベースにデータを登録し、ページネーションで表示してみました。
まずは、データベースを新規に作成しテーブルを作ります。
CREATE TABLE `addresses` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`firstname` varchar(10) NOT NULL DEFAULT '',
`lastname` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
addresses …。 という名前ですが、とりあえず名前だけ。
次に、 application/bootstrap.php を編集し、 ORM および database のモジュールを使えるように、コメントアウトされている各行を外します。
/**
* Enable modules. Modules are referenced by a relative or absolute path.
*/
Kohana::modules(array(
// 'auth' => MODPATH.'auth', // Basic authentication
// 'cache' => MODPATH.'cache', // Caching with multiple backends
// 'codebench' => MODPATH.'codebench', // Benchmarking tool
'database' => MODPATH.'database', // Database access
// 'image' => MODPATH.'image', // Image manipulation
'orm' => MODPATH.'orm', // Object Relationship Mapping
// 'unittest' => MODPATH.'unittest', // Unit testing
// 'userguide' => MODPATH.'userguide', // User guide and API documentation
));
最後に application/config/ 配下に database.php ファイルを作成し以下のような記述を追加します。
<?php
return array(
'default' => array(
'type' => 'mysql',
'connection' => array(
'hostname' => 'localhost',
'username' => 'データベースユーザー名',
'password' => 'データベースパスワード',
'persistent' => false,
'database' => 'データベース名'
),
'table_prefix' => '',
'charset' => 'utf8',
'profiling' => true
)
);
準備完了。
モデルを作る
addresses のモデルを作ります。 application/classes/model の配下に address.php ファイルを作ります。テーブル名は複数形ですが、モデル名は単数形となります。
<?php defined('SYSPATH') or die('No direct access allowed.');
class Model_Address extends ORM
{
public function rules()
{
return array(
'firstname' => array(
array('not_empty'),
),
'lastname' => array(
array('not_empty'),
),
);
}
}
class 名は、 Model_ から始まります。 ひとつだけ function がありますが、 バリデーションルールです。
この例では、 firstname および lastname に対して not_empty ルールを設定しています。これにより、空での登録はできなくなります。
後ほど設定するエラー表示の指定により、このままでも英語によるエラーが表示されますが、ついでに解りやすく日本語にしておきましょう。
メッセージは application/messages 配下に設置します。 models ディレクトリを作成し、 作成したディレクトリ内に address.php ファイルを以下の通り作ります。
<?php
return array(
'firstname' => array(
'not_empty' => '必ず入力してください',
),
'lastname' => array(
'not_empty' => '必ず入力してください',
),
);
これで、バリデーションによって表示されるエラーメッセージを変更することができます。
コントローラーを作る
Kohana PHP では、セットアップ直後 welcome.php が default コントローラーとして / にアクセスされた際に表示されるよう設定されています。
まずはこの設定を変更します。
application/bootstrap.php を開き、 Route::set() を変更します。
/**
* Set the routes. Each route must have a minimum of a name, a URI and a set of
* defaults for the URI.
*/
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'top',
'action' => 'index',
));
controller に指定した top.php(Controller_Top) の action に指定した index(action_index()) がデフォルトと変更できました。
ではファイルを作ります。
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Top extends Controller {
public function action_index()
{
$view = View::factory('address/create')
->bind('errors', $errors);
if ($_POST) {
$address = ORM::factory('address')->values($_POST);
try {
$address->save();
} catch(ORM_Validation_Exception $e) {
$errors = $e->errors('models');
}
}
$this->response->body($view);
}
}
7行目で、表示するビューを指定しています。 address/create と指定することで application/views/address/create.php を指定することになります。 8行には bind() が記載されています。 bind() は、ビューに対し値を渡してあげるメソッドですが、参照渡しによって行われます。
10行目からは、フォームから投稿された場合の処理になります。 address モデルに対し送信されたデータをセットし、保存を試みます。
バリデーションによりエラーとなった場合は、 $errors にエラー内容が代入されます。
ビューを作る
<?php echo Form::open('/'); ?>
<div>
<?php
echo Form::label('firstname', '姓');
echo Form::input('firstname');
echo Arr::get($errors, 'firstname');
?>
</div>
<div>
<?php
echo Form::label('lastname', '名');
echo Form::input('lastname');
echo Arr::get($errors, 'lastname');
?>
</div>
<?php echo Form::submit('submit', '登録'); ?>
<?php echo Form::close(); ?>
このビューによって、何も記入せずに「登録」ボタンをクリックすると以下の通り、エラーが表示されます。

Kohana PHP 3.2 セットアップ
ブログの更新をすごく長い間サボってしまっていました。
久しぶりの更新は、 Kohana PHP framework 3.2 を使ったプログラムの作成を。
本当に久しぶりすぎたので、とりあえずセットアップから開始したいと思います。
環境
- Ubuntu 11.10
- nginx 1.0.5
- php 5.3.13
MySQL 入れるの忘れてた。 入れると 5.1.58。
セットアップ
それぞれをインストールし、今回は nginx + php-fpm で構築しました。
cat /etc/nginx/sites-available/default
server {
listen 80;
server_name localhost;
root /home/yasuhiro/www;
index index.php;
location / {
try_files $uri $uri/ @kohana;
}
location @kohana {
rewrite ^ /index.php/$uri last;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /\.ht {
deny all;
}
}
nginx と php-fpm を起動して、ブラウザで http://localhost/ にアクセスしてみます。
環境テストが動作し、 こちらの画面では、キャッシュディレクトリとログディレクトリに書き込めないというエラーが表示されています。それぞれ、書き込みできるようパーミッションを変更。
再度リロードすると…
先ほどまで、赤く警告が表示されていましたが全てがグリーンに変わりました。
メッセージに従って www ディレクトリ配下にある install.php をリネーム(使わないので削除でもいいよ!)すると、インストール完了です!
リロードすると左上に「hello, world!」と表示されるシンプルな画面になります。

