Concrete5でpjaxを使ってみよう!
pjaxのライブラリを変えて色々やりたくなったので少し触っているConcrete5で試してみました。
長いあいだMODXオンリーになってましたが、前から使ってみたいと思ってたCMSなのでもっと勉強してコンテンツを増やしていきたいと思います(●'◡'●)
pjaxとは?
pjaxとはAjaxでコンテンツを入れ替えるのと同時にURLも変更してくれるjQueryのプラグインの名前です。
Githubのようなスムーズでイケてるページ遷移を行います。
javascriptの「pushState」などの新しいヒストリー関数とAjaxやサーバーサイドスクリプトを組み合わせて作られているのでjQueryプラグインじゃなくても実装は可能です。実際この技術がなんと呼ばれるのかはわかりませんが、とりあえずpjax(pushState + ajax = pjax)で浸透してるみたいです。Chrome、Firefox、IE10以降などのブラウザで動作し、非対応のブラウザでは通常のページ遷移をします。
pjaxの基本についてはこちらのページでも書いていますのでよかったらご覧下さい。
動作デモ
こちらのデモページを御覧ください。(別窓で開きます)
共通デモのためConcrete5で作成したページではありませんが、こんな感じの動きをします。
jquery.pjax.jsプラグインのダウンロード
jquery.pjax.js こちらからダウンロードできます。(2014.05.19時点の最新版はVer.1.32.9でした)
テーマの中のどこをpjax遷移させるか考えよう

pjaxは直接ページ遷移をしないでリンク先のページからajaxでコンテンツを取得して必要な部分だけを書き換えます。
Concrete5はヘッダーの内容が変わったりページタイプをページによって簡単に変更する事ができますが、例えばブログページでコンテンツ部分だけを更新させようとしても次の記事がどのページタイプを使っているか分からない場合があります。それを考慮してコンテンツ部分とサイドバーはひとつのかたまりにしてしまいます。
それから、ヘッダーのメニューと画像部分もページによって変わるのでここも遷移させた方がいいですね!
テーマファイルを編集する
今回の説明はデフォルトで入っているテーマ「greek_yogurt」を使用します。念の為テスト用にテーマフォルダの「greek_yogurt」を/themes/にコピーし、フォルダの名前を「greek_yogurt_pjax」などに変更してこっちを使用します。管理画面のテーマ選択から「greek_yogurt_pjax」を選択しておきます。
以降説明にあるテーマファイルは「greek_yogurt_pjax」を開いて編集してください。
elements/header.phpを開いてヘッダー部分のCSSの後あたりにpjaxを読み込むタグを追加します。
<script type="text/javascript" src="/js/jquery.pjax.js"></script>
次に、メインとサイドバーを一緒に遷移させるため2つを囲んだタグが欲しいのですが「greek_yogurt」にはこれが存在しないので新しくタグを追加します。
elements/header.phpとelements/blog_header.phpの一番最後に以下のタグを追加します。
<div id="pjaxContent">
elements/footer.phpの先頭に以下のような記述がありますがこの下に閉じタグを追加します。
<?php defined('C5_EXECUTE') or die("Access Denied."); ?>
追加すると以下のようになります。
<?php defined('C5_EXECUTE') or die("Access Denied."); ?>
<div class="clear"></div>
</div>
一応これで事前準備はおわり!
次にelements/header.phpを開いてpjaxの設定をします。一応以下は「greek_yogurt」用に書いたサンプルコードです。ヘッダーに直接書き込むか外部jsファイルにしてヘッダーで読み込んでください。これは「greek_yogurt」に大分最適化しているので他のテーマの場合IDの部分を修正する必要があります。
<script type="text/javascript">
$(document).ready(function() {
// 管理モードはpjaxをしない
if (!$('#ccm-page-controls-wrapper').get(0)) {
$.pjax({
area : function(event) {
// クリックされたエリアによってエフェクト処理をする場所を変更する
if ($(event.target).closest('.ccm-tags-display').length || $(event.target).closest('#main-content-sidebar-archives').length) {
$(event.target).data('areaname', '#main-content-container');
} else {
$(event.target).data('areaname', '#pjaxContent');
}
return '#pjaxContent, #header .nav, #header-image';
},
link : 'a:not([target="_blank"],.nopjax)',
// IN/OUTのエフェクト処理
callbacks : {
before : function(event) {
$($(event.target).data('areaname')).animate({
opacity : 0
}, 100);
},
update : {
content : {
before : function(event) {
$($(event.target).data('areaname')).animate({
opacity : 1
}, 100);
}
},
}
},
// CSSとJavascriptをロードします
load : { css: true, script: true },
// エフェクトの待ち時間
wait : 220,
ajax : { timeout : 3000 }
});
}
});
// URLに[]が含まれている場合の処置
$(document).on('ready, pjax.ready', function() {
$('a').each(function(){
var url = $(this).attr('href');
url = url.replace(/\[(.*?)\]/g, "%5B$1%5D");
$(this).attr('href', url);
});
});
</script>
ちょっといろいろ書いてあって編集の仕方が分からない!という場合は以下のコードを使用してエフェクト処理などを少しづつ追加して見てくださいね(●'◡'●)
<script type="text/javascript">
$(document).ready(function() {
// 管理モードはpjaxをしない
if (!$('#ccm-page-controls-wrapper').get(0)) {
$.pjax({
area : function(event) {
return '#pjaxContent, #header .nav, #header-image';
},
link : 'a:not([target="_blank"],.nopjax)',
load : { css: true, script: true },
ajax : { timeout : 3000 }
});
}
});
// URLに[]が含まれている場合の処置
$(document).on('ready, pjax.ready', function() {
$('a').each(function(){
var url = $(this).attr('href');
url = url.replace(/\[(.*?)\]/g, "%5B$1%5D");
$(this).attr('href', url);
});
});
</script>
テストしてみよう!
うまくpjaxできるかテストしてみましょう。念のため管理画面でキャッシュをクリアして、フルページキャッシュをオフにしておきます。きちんとpjax遷移しているか確認するためelements/header.phpの先に追加した#pjaxContentタグの直前にタイムスタンプを表示させておきます。
<?php echo time();?>
<div id="pjaxContent">
ヘッダー画像の下に数字が表示されたと思いますが、この数字はフルページキャッシュをしていなければページ移動の度に変わります。ページ移動してみてこの数字の末尾の方が変化しなければpjax遷移しているということですね!
うまく数字が変わらずに遷移しているようなら成功です。 time()の部分を削除してフルページキャッシュを元の設定に戻しておきましょう。
また、私自身Concrete5をまだそんなに使い倒していないので場合によってこの方法は使用できないかもしれません。フォームやツイッターでご指摘いただければ反映しますので気軽にご連絡ください!
フォームを使用しているページについて
フォームとは限らないと思うのですが、お問い合わせやブログのコメントその他一部のブロックを使用しているページではpjax遷移した後に通常遷移してしまうようです。2重遷移になってしまうのでlinkパラメータで.nopjaxを付けるなど対策してください。(原因を追ってみようと思ったのですが時間がなくて放置中です。対処方法分かったら追記します)
ゲストブックブロックではコアにある<a name="guestBookForm-<?php echo $controller->bID?>"></a>の部分が原因だったみたいで以下のように修正したらpjax遷移しました。空のアンカーが影響してるのかもしれません。
<a href="#" name="guestBookForm-<?php echo $controller->bID?>"></a>