カテゴリーを選択したら該当する記事一覧を表示させる際に、ページ遷移をせずにAjaxを使い記事を表示させる方法です。
今回は応用編になります。基本編はこちら。
完成品
セレクトボックスを選択をしたら、選択したカテゴリーのIDをサーバーサイドに渡してあげて、該当する記事を取得して画面に表示というのが一連の流れです。
リクエスト送信先のパス設定
WordPressではadmin-ajax.phpというファイルでAjaxのリクエストを受け付けてくれるので、まずはJavaScriptで使えるようにURLを定義します。
functions.phpに以下コードを記載します。
<?php
function add_my_ajaxurl() {
?>
<script>
var ajaxurl = '<?php echo admin_url( 'admin-ajax.php'); ?>';
</script>
<?php
}
add_action( 'wp_head', 'add_my_ajaxurl', 1 );
?>
クライアント側の実装
今回はデモとしてajax-sort
というスラッグ名の固定ページに記事一覧を表示させるようにします。
なので、page-ajax-sort.php
を用意します。
カテゴリーのセレクトボックスを用意
カテゴリーを選択できるように、カテゴリー名を取得してセレクトポックスを作成します。
JSで使用する用に、selectタグのidにはid="js-category-select"
を設定しておきます。
<?php
$terms = get_terms('category');
?>
<select name="position" id="js-category-select" class="select-box">
<option value="">全てのカテゴリー</option>
<?php foreach ( $terms as $term ) : ?>
<option value="<?php echo $term->term_id; ?>"><?php echo $term->name; ?></option>
<?php endforeach; ?>
</select>
カテゴリーを選択できるセレクトボックスができました。
記事一覧を表示させる
WP_Queryを使用して、記事の一覧を取得して表示します。
JSで使用する用に、ulタグのidにはid="js-articles-area"
を設定しておきます。
<?php
$terms = get_terms('category');
?>
<select name="position" id="js-category-select" class="select-box">
<option value="">全てのカテゴリー</option>
<?php foreach ( $terms as $term ) : ?>
<option value="<?php echo $term->term_id; ?>"><?php echo $term->name; ?></option>
<?php endforeach; ?>
</select>
<!-- 以下追記 -->
<?php
$args = [
'post_type' => 'post',
'post_status' => 'publish',
];
$the_query = new WP_Query($args);
?>
<ul id="js-articles-area" class="archive-list">
<?php if( $the_query->have_posts() ) : ?>
<?php while( $the_query->have_posts() ) : $the_query->the_post(); ?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endwhile; ?>
<?php else: ?>
<p>記事はありません</p>
<?php endif; wp_reset_postdata();?>
</ul>
※アーカイブページで作成する場合はサブクエリではなくメインクエリを使用してもOK。
これで記事一覧が表示されます。
カテゴリーを選択したときの処理を記載
カテゴリーを選択したら、Ajaxでサーバーサイドに渡してあげて、取得した記事一覧を画面に表示させる処理を記載します。
JavaScriptファイルに以下を記載します。
jQuery(function($) {
//カテゴリーを選択したとき
$('#js-category-select').on('change', function(){
var categoryId = $(this).val();
selectPost(categoryId);
});
//投稿の表示
function selectPost(categoryId){
var categoryId = categoryId;
$.ajax({
type: 'POST',
url: ajaxurl,
data: {
'action' : 'get_select_post', //呼び出すphpの関数
'category' : categoryId, //カテゴリーIDを渡す
},
success: function( response ){ //成功した時の処理
var jsonData;
var result_html = '';
if ( response !== '[]' ) {
jsonData = JSON.parse( response ); //JSON形式を配列に変換
$.each( jsonData, function( i, val ){ //表示させるHTMLに整形
result_html += '<li><a href="' + val['permalink'] + '">' + val['title'] +'</a></li>';
});
} else { //投稿がないとき
result_html = '<li>該当するデータがありません</li>';
}
$('#js-articles-area').html(result_html); //記事一覧を表示させる
},
error: function () { //失敗した時の処理
alert("通信に失敗しました。再度やり直してください。");
}
});
return false;
}
});
今回はカテゴリーのIDを渡してあげるので、data
のところに'category' : categoryId
を入れます。
呼び出すPHP関数はget_select_post
とします。
サーバー側の実装
次は呼び出される関数get_select_post
を作成します。
functions.php
に以下コードを記載します。
//選択した投稿の取得
function get_select_post(){
$category_id = $_POST["category"];
global $post;
$returnObj = array();
$args = [
'post_type' => 'post',
'cat' => $category_id,
'post_status' => 'publish',
];
$query_posts = new WP_Query($args);
if ($query_posts->have_posts()) {
while($query_posts->have_posts()) {
$query_posts->the_post();
$returnObj[] = array(
'title' => get_the_title(),
'permalink' => get_permalink(),
);
}
}
wp_reset_postdata();
echo json_encode( $returnObj );
wp_die();
}
//ログインしているユーザー向け関数
add_action( 'wp_ajax_get_select_post', 'get_select_post' );
//非ログインユーザー用関数
add_action( 'wp_ajax_nopriv_get_select_post', 'get_select_post' );
$_POST["category"]
で受け取ったcategoryのIDを取得できるので、この情報を元にWP_Queryで記事を取得して、フロント側に渡してあげます。
実行
これで完成ですので、カテゴリーを選択すると記事一覧が非同期で切り替わります。
あとはこれを応用すれば、カテゴリーではなくタグでソートをしたり、カスタムタクソノミーを組み合わせて複数条件でソートすることなども可能です。