WordPressでAjaxのPagerっぽいものを作ってみた

なんかタイトルじゃわかりづらいかもしれないですが、facebookとかで一番下にスクロールすると続きが自動的に読み込まれるやつ。あれです。

それをWordPressでやってみた的な話です。

なぜそんなものが必要か

ただやってみたかっただけです。

それと、wpの勉強。今更ながらですが今回のブログでwpデビューしたのですが、なんか実装しようとしないと仕組みなんて理解しようとしないし、実際にソースコード読んでゴリゴリっとやった方が覚えるだろうって思ったんです。

ツッコミなどございましたら、コメントもらえるとうれしいです。

Ajaxで取得するページの作成

まずはAjaxで取得するページの作成を行います。

  • ページ数を渡して投稿の一覧を表示する
  • 記事数は「表示設定」の「最大投稿数」を引き継ぐ
  • ヘッダー・フッターはいらない

まず上記要件を満たしたページの作成を行います。

「固定ページ」→「新規作成」で”pager”という名前で固定ページを作成します。

固定ページを編集 ‹ sawara.me — WordPress 2013-04-16 15-04-10

このままだとナビメニューに”pager”とか出てきてしまうので、ページ属性から親を”ホーム”にします。

固定ページを編集 ‹ sawara.me — WordPress 2013-04-16 15-17-18
※ ちなみに”ホーム”は表示設定でフロントページに設定されています。

階層表示もされてしまうので、「header.php」の”wp_nav_menu”の引数に”depth”に1を指定。

header.php
<?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_class' => 'nav-menu', 'depth' => 1 ) ); ?>

※ メニューから消す方法はwpの設定でできるのかもしれませんが、よくわからなかったので。

テンプレートに「Ajax Pager」を指定したのはヘッダー・フッターを出力したくなかったためです。
テンプレートのセレクトボックスには以下のディレクトリにあるファイルが自動的に読み込まれて設定できるようになっています。

/ドキュメントルート/wp-content/themes/テーマのディレクトリ/page-templates/

今回はここに「ajax-pager.php」というファイルを設置し、以下のような内容にしました。

ajax-pager.php
<?php
/**
 * Template Name: Ajax Pager
 *
 */
// <!--more--> で区切る(trueだと区切られず全文出力)
global $more;
$more = false;
// 現在のページ数の取得
$queryPage= get_query_var('page');
// 空の場合は0を設定
if(empty($queryPage))
{
	$queryPage = 1;
}
?>
<?php query_posts('post_type=post&paged='.$queryPage); /* 投稿をページ数を指定して取得 */?>
<?php if (have_posts()) : ?>
<?php while (have_posts()) : ?>
<?php the_post(); ?>
	<div class="widget">
		<a href="<?php the_permalink(); ?>" ><?php the_post_thumbnail( ); ?></a>
		<div class="widget_content">
		<span class="date"><?php the_time('Y年n月j日'); ?></span>
		<p><a href="<?php the_permalink(); ?>" ><?php the_title(); ?></a></p>
		<?php the_content( ); ?>
		</div>
	</div>
<?php endwhile; ?>
<?php endif; ?>

※ whileの中身は適時書き換えるとして。

いったん固定ページ”pager”を公開にして保存し、表示してみます。

2013-04-16 18-50-22 2013-04-16 18-51-01

表示件数を2件にして表示してみました。左が1ページ目、右が2ページ目です。
ページ数を指定するときはURLに”?page=2″等をGET値を加えて確かめます。3ページ目からは記事が無かったので、何も表示されませんでした。

これでAjaxで取得するページの準備は完了しました。

呼び出す側のページの設定

呼び出す側ではJavaScriptをサクッと書いていきます。
一応jQueryが読み込まれている事前提です。

content.php
<div id="pagerload">
    <!-- ここに記事を表示 -->
</div>
<div id="pagertrigger"></div>

id:pagertriggerの<div>までスクロール位置が来たら、id:pagerloadの<div>の中に記事を表示するようにJavaScriptを記述します。

JavaScript
// トリガフラグ
var trgFlg = false;
// ページ数
var page = 1;
$(window).load(function(){
	$(window).scroll(function(){
		// id:pagertriggerの座標がウィンドウのスクロール下限よりも小さければajax実行
		if ($(window).scrollTop()+$(window).height() > $('#pagertrigger').offset().top && !trgFlg ) {
			// スクロールの度に実行されないようにフラグを立てる
			trgFlg = true;
			$('#pagertrigger').html('<div><img src="/images/ajax-loader.gif" /></div>');
			$.ajax({
				type : "post",
				url : "/home/pager/",
				data : "page="+(++page).toString(),
				dataType : "html",
				success : function(re)
				{
					$('#pagertrigger').html('');
					if(re.replace(/^\s+|\s+$/g, "") !== '')
					{
						$('#pagerload').append(re);
						triggerFlg = false;
					}
					else
					{
						$('#pagertrigger').html('<p>記事がありません。</p>');
					}
				},
				error : function()
				{
					$('#pagertrigger').html('<p>データの取得に失敗しました。</p>');
				}
			});
		}
	});
});

上記例では1ページ目がデフォルトで表示されている事を想定しているため、2ページ目からajaxで取得するようになっています。

初期状態で1ページ目を表示しない場合は、4行目の数値を0にすればOKです。ただその場合、初期状態でスクロールできないページになってしまっていると、そもそもスクロールイベントが取得できなくなってしまうため、初回表示の際に必ず一回は実行されるように実装する等の対応が必要になってきます。

実装例

一応このブログのTOPに実装してみました。
自分もやってみたいと思った方は是非使ってみてください。

ソースコードを読みながら実装したので、もしかしたらもっとスマートな方法があるかも。時間があったらプラグインとか作ってみたいと思います。

コメントを残す