CoComina– Web design and Programing –

【WordPress x Ajax】選択されたカテゴリの記事をAjaxで読み込む方法

今回はWordpressとAjaxを組み合わせて、クリックされたカテゴリに属する記事のみを取得して表示する方法です。

そもそもAjaxとはなんでしょう?

Ajaxとは、Webブラウザに実装されているJavaScriptのHTTP通信機能を使って、Webページのリロードを伴わずにサーバとXML形式のデータのやり取りを行って処理を進めていく対話型Webアプリケーションの実装形態。

引用元:IT用語辞典

とのことです。では、Ajaxの仕組みが理解できた所で、おおまかな流れを説明します。
主に下記のようになっています。

カスタムナビゲーションにてカテゴリーリスト作成

カテゴリーを1つずつテンプレートに直接記述したり、get_the_category_list を使用してもいいのですが、それだと納品後にクライアントが変更しにくいなど使い勝手が悪いので、今回はWordpressのカスタムメニュー機能を使います。

まずは、使用するテーマでカスタムメニューがサポートしてるか確認しましょう。
「管理画面→外観→メニュー」とあればそのテーマはカスタムメニューをサポートしています。

見当たらない場合は下記をfunctions.phpに追記しましょう。

<?php register_nav_menus( array( 'menu-categorise' => 'カテゴリーリスト'
	)
);
?>

これでカスタムメニューが使えるようになります。
次は出力する方法ですが、wp_nav_menu だと、デフォルトで出力されるHTMLに余計なIDやClassが付与されてしまいます。
よって、今回は下記の方法で出力します。

<?php
    $menu_name = 'menu-categorise';
    if(($locations = get_nav_menu_locations()) && isset($locations[$menu_name])){
		echo '
<ul id="categorise">';
		$menu       = wp_get_nav_menu_object($locations[$menu_name]);
		$menu_items = wp_get_nav_menu_items($menu->term_id);
		foreach((array)$menu_items as $key => $menu_item){
	    		$title = $menu_item->title; // カテゴリー名
			$url   = $menu_item->url;   // カテゴリーURL
			$slug = explode('/', $url); // カテゴリーURLを / 区切りで分割してスラッグを取得
			if($count == 1){
				$firstSlug  = $slug[5]; // 最初のカテゴリーのスラッグを取得
			}

			echo '
<li><a data-cat="'.$slug[5].'" href="'.$url.'">'.$title.'</a></li>

';
		}
		echo '</ul>

';
    }

    // 取得した最初のカテゴリーのスラッグを使い記事を出力しておく。
    $catSlug = get_category_by_slug($firstSlug);
    $catID   = $catSlug->cat_ID;
    $catName = $catSlug->cat_name;

    $args = array(
         'category'       => $catID // カテゴリーのID指定して絞り込み
        ,'posts_per_page' => 4 // 4件表示
    );
    $myPosts = get_posts($args);
    foreach($myPosts as $post){
        setup_postdata($post);
        echo '
<div id="article_outer">';
        echo '
<div class="article_inner">';
        echo '<a href="'.get_the_permalink().'">';
        echo '
<h3>記事のタイトル「'.get_the_title().'」</h3>

';
        echo '

カテゴリー:'.$catName.'

';
        echo '</a>';
        echo '</div>

';
        echo '</div>

';
    }
    wp_reset_postdata();
?>

■dumpしてみたのですがカテゴリースラッグは格納されないようだったので今回は explode(‘/’, $url) を使って $url から分割して取得しています。

注意:パーマリンク設定によって$slug[5]にカテゴリースラッグが格納されない場合がありますので環境に合わせて修正してください。

上記の記述で出力されたHTMLがこちらです。

data属性を出力してますが、後ほど使用しますので次の章で説明しやす!

<!-- Categorise -->

<ul id="categorise">

<li><a data-cat="music" href="http://example.com/category/music">音 楽</a></li>


<li><a data-cat="movie" href="http://example.com/category/movie">映 画</a></li>

</ul>

<!-- Article -->

<div id="article_outer">

<div class="article_inner">
		<a href="http://example.com/category/music/1">

<h3>記事のタイトル「35xxxv」</h3>



カテゴリー:音 楽

		</a>
	</div>

</div>

ここでは下記のカテゴリ設定を想定しています。

  • カテゴリー名:音 楽(スラッグ → music)
  • カテゴリー名:映 画(スラッグ → movie)

クリックされたカテゴリーのスラッグを取得してAjaxでデータを渡す

カテゴリーリストを出力したら今度はクリックされたカテゴリーリストのスラッグを取得してAjaxにPOSTします。


var $ajaxUrl = location.href+'wp-admin/admin-ajax.php', // WordPressでAjaxを使うときの送り先
	$catList = $('.cat_list'),
	$catSlug;

$catList.on('click', function(){
	$catSlug = $(this).data('cat'); // data-cat属性の値を取得

	$.ajax({
		type:'POST',
		url:$ajaxURL,
		cache:false,
		timeout:3000,
		data: {
			'action':'my_ajax_action', // 処理を行う関数名
			'slug':$catSlug // カテゴリースラッグを変数として渡す
		},
	}).then({
		function(response){
			// scusessの時の処理
		},
		function(response){
			// errorの時の処理
		}
	});
});

処理の流れとしては、

  • クリックされた、data-cat属性の値を取得(カテゴリースラッグを取得)
  • $ajaxUrlにデータを渡す時に、カテゴリースラッグも変数にして渡す

現在は、取得したカテゴリースラッグを渡しているだけなので表面上は何も起こりません。
(chromeのデベロッパーツール(console)には、http://example.com/wp-admin/admin-ajax.phpと出力される)

データを渡した後は「渡されたデータに対して何かを返す」という処理が必要になります。
返されたデータは(response)に格納されます。次の章ではその返す処理を行います。

渡されたカテゴリースラッグに属する記事のみ生成して返す

データを受け取ったら今度はそのデータに対して返す処理を行います。

カテゴリースラッグは $_POST[‘slug’] で受け取ることができます。

■functions.php

<?php add_action('wp_ajax_my_ajax_get_posts', 'my_ajax_get_posts'); add_action('wp_ajax_nopriv_my_ajax_get_posts', 'my_ajax_get_posts'); function my_ajax_get_posts(){ $catSlug = get_category_by_slug($_POST['slug']); $catName = $catSlug->cat_name;

		$args = array(
			 'category_name'  => $_POST['slug'] // $.ajaxで渡されたカテゴリースラッグが入る
			,'posts_per_page' => 4
		);
		$query = new WP_Query($args);
		if($query->have_posts()){
			while($query->have_posts()){
				$query->the_post();
				echo '
<div class="article_inner">';
				echo '<a href="'.get_the_permalink().'">';
				echo '
<h3>記事のタイトル「'.get_the_title().'」</h3>

';
				echo '

カテゴリー:'.$catName.'

';
				echo '</a>';
				echo '</div>

';
			}
		}
		wp_reset_query();
		die();
	}
?>

これで返す処理の完了です。このデータは(response)に格納されます。

処理の流れとしては、

  • $_POST[‘slug’]で送られてきたカテゴリースラッグを受け取り絞り込む。
  • ループして記事を生成する。

をしてるだけですね。

注意点としては、前述したAjaxのactionの名前は処理を返す関数名と同じ必要があり、wp_ajax_(関数名)、wp_ajax_nopriv_(関数名)の箇所も同じ関数名を設定する必要があります。
(関数名を変更したら動かなくなってちょっとパニクったのは秘密!)

他にも$argsにexcludeなどを設定して特定の記事は除外するなど、お好みでカスタマイズしてください。

返された記事を表示する

WordPressとAjaxで選択されたカテゴリの記事のみ読み込む:346h

データを渡す、渡されたデータに対して処理を返す作業は完了しましたので、後は表示するのみです。
今回は#article_outerの中に記事を表示します。

前述したJavascriptのAjaxのsuccessとerror時の処理を下記の様に変更します。

var $ajaxUrl = location.href+'wp-admin/admin-ajax.php', // WordPressでAjaxを使うときの送り先
    $catList = $('.cat_list'),
    $catSlug;
 
$catList.on('click', function(){
    $catSlug = $(this).data('cat'); // data-cat属性の値を取得
 
    $.ajax({
        type:'POST',
        url:$ajaxURL,
        cache:false,
        timeout:3000,
        data: {
            'action':'my_ajax_action', // 処理を行う関数名
            'slug':$catSlug // カテゴリースラッグを変数として渡す
        },
    }).then({
        function(response){
			$articleOuter = $('#article_outer');
			$response = response; // 返されたデータを変数に格納
			$articleOuter.html(''); // #article_outer内のHTMLを一度削除する
			$articleOuter.html($response); // my_ajax_actionで生成されたデータ(response)を再度挿入する
        },
        function(response){
			$articleOuter.html(''); // #article_outer内のHTMLを一度削除する
			$articleOuter.html('

エラー:読み込みに失敗しました。

'); // エラー時のメッセージ
        }
    });
});

これでクリックされたカテゴリーに属する記事のみに表示を切り替えることができます。ページ移動せずに切り替わるので気持ちいいですね。

Ajaxの設定をする時はエラー時の処理とtimeoutを必ず設定することをお勧めします。
読み込み始めたものの、いつまでも何も変化がないというのはユーザにとってストレスを与えてしまいます。

なので、必ずtimeoutで時間を設定してエラーの時でも何らかの処理を返しましょう。

今回、WordpressとAjaxの組み合わせは初めてだったので自分用の備忘録としての意味も含めて、記事を書かせていただきましたが、お役に立てば幸いです。

(良いと思ったらシェアしてもらえると泣いて飛んで喜びますよ!!)

Endpoint