2013/06/18 追記:
タイトルの変更は、以下のようにカスタムヘッダを用いた方が良さそうです。
2013/03/23 追記:
v1.5.3用に、サンプルコードの一部を修正しました。
--
極力ミニマムな内容を意識して、メモしておきます。
確認したブラウザは
* Mac Chrome 24.0.1312.57
* Mac Firefox 18.0.2
* Mac Safari 6.0.2 (8536.26.17)
です。(Winはまだです。)
2013/02/19追記:
IE9(Win)は動かないです。普通の遷移になります。(10で対応??)
普通の遷移にも対応させておくことが重要です。
以下、ポイントです。
* 画面遷移時、URLを変えつつ非同期にコンテンツを取得すること。
* pjax時も非pjax時(直アクセス時)も、HTMLのタイトルが変わること。
* 非pjax時、該当ページのコンテンツが表示されること。
以下、手順です。
(1)
FuelPHP 1.5.2 をDL、展開
(2)
pjaxをDL、展開
https://github.com/defunkt/jquery-pjax
* public/assets/app/pjax/jquery.pjax.js の配置になります。
(3)
以下、各ファイルのサンプルです。正しい場所に正しいファイル名で作成して、そのままコピペで動くと思います。
classes/controller/index.php (Controller_Index クラス)
* pjax時も非pjax時も、とりあえずコレを呼びます。
* 各actionで、後述のController_Ajaxの対応するget_xxxを呼びます。
* pjax時はget_xxxの戻り値をそのまま返却、非pjax時はget_xxxの戻り値をtemplateに当てはめます。
<?php
class Controller_Index extends Controller_Template
{
private static function is_pjax()
{
// TODO: 本来は Input クラスを拡張するのが好ましそう
return Input::server('HTTP_X_PJAX') !== null;
}
public function before()
{
parent::before();
$this->template->title = 'FuelPHP x Pjax';
// 参考:
// http://madroom-project.blogspot.jp/2012/09/fuelphpassetassets.html
Asset::add_path('assets/app/', 'css');
Asset::add_path('assets/app/', 'js');
Asset::add_path('assets/app/', 'img');
// Input::is_ajax() で true を返却させるため
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'xmlhttprequest';
}
/**
* index ページ
*/
public function action_index()
{
$response = Request::forge('ajax/index')->execute()->__toString();
if (static::is_pjax())
{
// pjax でのアクセス時
return $response;
}
else
{
// 直接なアクセス時
$this->template->title .= ' - INDEX';
$this->template->set('content', $response, false);
}
}
/**
* foo ページ
*/
public function action_foo()
{
$response = Request::forge('ajax/foo')->execute()->__toString();
if (static::is_pjax())
{
return $response;
}
else
{
$this->template->title .= ' - FOO';
$this->template->set('content', $response, false);
}
}
/**
* bar ページ
*/
public function action_bar()
{
$response = Request::forge('ajax/bar')->execute()->__toString();
if (static::is_pjax())
{
return $response;
}
else
{
$this->template->title .= ' - BAR';
$this->template->set('content', $response, false);
}
}
}
classes/controller/ajax.php (Controller_Ajax クラス)
* 各ページのコンテンツ取得メソッド(get_xxx)の他に、HTMLタイトル取得メソッド(get_title)を用意しています。
<?php
class Controller_Ajax extends Controller_Rest
{
protected $_supported_formats = array(
'html' => 'text/html',
);
public function before()
{
parent::before();
! Input::is_ajax() and die();
}
/**
* タイトルを取得
*/
public function get_title($page = null)
{
$page === null and die();
$title = 'FuelPHP x Pjax';
switch ($page)
{
case 'index':
$title .= ' - INDEX';
break;
case 'foo':
$title .= ' - FOO';
break;
case 'bar':
$title .= ' - BAR';
break;
default:
break;
}
$this->response($title);
}
/**
* index ページのコンテンツを取得
*/
public function get_index()
{
$this->response(View::forge('ajax/index'));
}
/**
* foo ページのコンテンツを取得
*/
public function get_foo()
{
$this->response(View::forge('ajax/foo'));
}
/**
* bar ページのコンテンツを取得
*/
public function get_bar()
{
$this->response(View::forge('ajax/bar'));
}
}
views/template.php
* <a data-pjax ... のリンクをクリックすると"#pjax-container"の中身がpjaxで変化します。
* pjaxの確認用に、YouTube動画を埋め込んで有ります。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title><?php echo $title; ?></title>
<?php echo Asset::js('http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'); ?>
<?php echo Asset::js('pjax/jquery.pjax.js'); ?>
</head>
<script>
$(document).ready(function() {
// pjaxの初期化
$(document).pjax('[data-pjax] a, a[data-pjax]', '#pjax-container');
// タイトルの取得
$(document).on('click', 'a[data-pjax]', function(event) {
$("title").load("/ajax/title/" + $(this).attr("title"));
});
});
</script>
<body>
<a data-pjax href="<?php echo Uri::create('index/index'); ?>" title="index">index</a>
<a data-pjax href="<?php echo Uri::create('index/foo'); ?>" title="foo">foo</a>
<a data-pjax href="<?php echo Uri::create('index/bar'); ?>" title="bar">bar</a>
<div id="pjax-container">
<?php echo $content; ?>
</div>
<iframe width="420" height="315" src="http://www.youtube.com/embed/MDBLhdSy5t4" frameborder="0" allowfullscreen></iframe>
</body>
</html>
views/ajax/index.php
<p>Page - index</p>
views/ajax/foo.php
<p>Page - foo</p>
views/ajax/bar.php
<p>Page - bar</p>
以下が確認出来れば、成功です。
* YouTube動画を再生しながら画面遷移をして、動画の再生が途切れないこと。
* 各ページのURLに直接アクセスしてコンテンツが正しく表示されること。
* HTMLのタイトルが正しく変わること。