concrete5でPjaxを使ってみよう!

最終更新日
2017.08.14

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.phpelements/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」用に書いたサンプルコードです。ヘッダーに直接書き込むか外部 JavaScript ファイルにしてヘッダーで読み込んでください。これは「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>