【WordPress】投稿ページ(single.php)でAjax通信で無限スクロールする方法
今回はWordPressの投稿ページ(single.php)で、Ajaxを使った無限スクロールの実装方法を説明します。
前提条件は以下
- 投稿ページ、またはカスタム投稿ページで無限スクロール
- jQueryのAjax通信を使う
- パーマリンクは投稿IDに設定する必要あり(後ほど説明します)
説明する環境は以下
- macOS Catalina v10.15.5
- Visual Studio Code v1.46.1
投稿ページでAjax通信で無限スクロールする方法
home.phpやarchive.phpなどの一覧ページではなく、single.phpの投稿ページで無限スクロールさせます。
コードは以下の記事を参考にしています。
パーマリンクを投稿IDで設定
single.phpで無限スクロールさせるときに、メインとして表示される記事を除外して、それ以外の記事を順番に表示させます。
サブループで除外の設定をするときに、表示されている記事の投稿IDを使うので、以下のようにパーマリンク設定をする必要があります。今回の構造上ではphpから投稿IDを取得できないため、JavaScriptを使って投稿IDを取得するためです。
投稿ページ(single.php)に書くこと
<?php get_header(); ?>
<main class="l-main">
<div class="c-block">
<div class="c-block__inner">
<article class="p-article">
<?php if ( have_posts() ) : //条件分岐:投稿があるなら ?>
<?php while ( have_posts() ) : the_post();//繰り返し処理開始 ?>
<?php endwhile; // 繰り返し終了 ?>
<?php endif; //条件分岐終了 ?>
</article>
<div id="js-ajax"> <!-- ここに無限スクロールの記事を表示させる -->
</div>
</div>
</div>
</main>
<?php get_footer();
id名js-ajaxのブロック中に無限スクロールさせる記事を表示させていきます。
JavaScriptで書くこと
init.jsというファイルを作成して以下に内容を書きます。
$(function () {
if ($("#js-ajax").length) { /* id名js-ajaxがあれば以下を実行 */
let documentHeight = $(document).height(); /* ページの全高さを取得 */
let windowsHeight = $(window).height(); /* ブラウザの高さを取得 */
let url = "http://test.com/wp-content/themes/test/ajax.php"; /* ajax.phpまでのパス */
let postNumNow = 0; /* 最初に表示させる記事数 */
let postNumAdd = 5; /* 追加する記事数 */
let siteUrl = window.location.pathname.split("/"); /* サイトのurlを取得して、/ごとに分割 */
let postId = siteUrl[siteUrl.length - 1]; /* 分割したurlから最後部分を取得(投稿ID) */
let flag = false;
$(window).on("scroll", function () {
let scrollPosition = windowsHeight + $(window).scrollTop();
if (scrollPosition >= documentHeight - 500) {
if (!flag) {
flag = true;
$.ajax({
type: "POST",
url: url,
data: {
post_num_now: postNumNow,
post_num_add: postNumAdd,
post_id_add: postId,
},
success: function (response) {
$("#js-ajax").append(response);
documentHeight = $(document).height();
postNumNow += postNumAdd;
flag = false;
},
});
}
}
});
}
});
重要な部分を説明します。
ajaxファイルの読み込み(6行目)
後ほどajax.phpというファイルを作成して、その中に無限スクロールする内容を書いていきます。ajax.phpはhome.phpやsingle.phpと同じ階層に配置するので、そこまでのパスを指定しましょう。
let url = "http://test.com/wp-content/themes/test/ajax.php"; /* ajax.phpまでのパス */
表示させる記事数を指定(8、9行目)
ページが表示されたときに、最初に何記事表示させておいて、何記事ずつ表示させるのか指定します。
let postNumNow = 0; /* 最初に表示させる記事数 */
let postNumAdd = 5; /* 追加する記事数 */
投稿IDを取得する(11、12行目)
ajax.phpから投稿IDを取得できないため、サイトURLを分割して投稿IDを取得しています。
let siteUrl = window.location.pathname.split("/"); /* サイトのurlを取得して、/ごとに分割 */
let postId = siteUrl[siteUrl.length - 1]; /* 分割したurlから最後部分を取得(投稿ID) */
無限スクロールで表示させる内容を書く
無限スクロールで表示させる内容を書きます。
ajax.phpという名前でファイルを作成したら以下を書きます。ajax.phpはhome.phpやsigle.phpと同じ階層に配置します。
<?php
require_once '../../../wp-load.php'; //wordpressの関数を使うために読み込み
$offset = isset( $_POST['post_num_now'] ) ? $_POST['post_num_now'] : 0;
$posts_per_page = isset( $_POST['post_num_add'] ) ? $_POST['post_num_add'] : 0;
$post_id_name = isset( $_POST['post_id_add'] ) ? $_POST['post_id_add'] : 0;
$post_id_array = [$post_id_name]; //投稿IDを配列化する
$args = array(
'posts_per_page' => $posts_per_page, //何件ずつ表示させるのか
'offset' => $offset, //何件目から表示させるのか
'post__not_in' => $post_id_array, //一番上にある記事は除外
'post_type' => 'post', //投稿タイプ
'post_status' => 'publish',//公開の記事だけ
'has_password' => false //パスワードがある記事は除外
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
?>
<?php global $previousday;
while ( $the_query->have_posts() ) : $the_query->the_post();
$previousday = '';
// -------- ここから繰り返し---------- ?>
<article class="p-article">
</article>
<?php // -------- 繰り返しここまで-----------
endwhile; ?>
<?php // -------- WP_query終了-----------
endif; ?>
<?php wp_reset_postdata(); ?>
重要な部分を説明します。
WordPress関数を使えるようにする(3行目)
Ajax通信したファイルはWordPress関数が使えないので、wp-load.phpを最初に読み込むことで使えるようにします。
require_once '../../../wp-load.php'; //wordpressの関数を使うために読み込み
Ajax通信でデータを受け取る(5〜7行目)
init.jsで取得している以下のデータをajax.phpに渡しています。
- 最初から表示させる記事数
- 追加する記事数
- 投稿ID
$offset = isset( $_POST['post_num_now'] ) ? $_POST['post_num_now'] : 0; //最初から表示させる記事数
$posts_per_page = isset( $_POST['post_num_add'] ) ? $_POST['post_num_add'] : 0; //追加する記事数
$post_id_name = isset( $_POST['post_id_add'] ) ? $_POST['post_id_add'] : 0; //投稿ID
投稿IDを配列化する(8行目)
Ajax通信で受け取った投稿IDを配列化しています。
$post_id_array = [$post_id_name]; //投稿IDを配列化する
投稿IDを配列化する理由は、14行目のpost__not_inで記事を除外するときに配列で投稿IDを指定する必要があるからです。
'post__not_in' => $post_id_array, //一番上にある記事は除外(投稿IDを除外)
おわりに
今回はWordPressの投稿ページに、Ajax通信を使って無限スクロールする方法を紹介しました。パーマリンク設定を投稿IDで設定するなど制約がある実装方法ですが、参考にしてみてください。