WPのタームと子タームでAjaxでドリルダウン(中古車屋さん編)
ドリルダウンとは何なのかわからない人は、あれですあれ、中古車屋さんとかの絞り込み検索で、メーカーのセレクトボックスで「トヨタ」とか選ぶと、その下の車種のセレクトボックスが「クラウン」とか「カローラ」とかに自動的に変化するあれですあれ。
あれを今回はメーカーを親タームとし、車種を子タームとしてAjaxでドリルダウンを作ってみようという方法をご紹介しています。
簡単なものですが、使い勝手はあると思います。ひとつの参考として見てみて下さい。
流れとしては下記の様な感じで進めていきます。
- carカスタム投稿を作成
- cartypeタクソノミーを作成
- メーカータームと車種子タームを作成
- パーマリンクの変更
- carカスタム投稿にそれぞれの中古車を登録
- archive.phpに絞り込み検索の土台となるformを設置
- function.phpにPHP側の処理を作成
- drilldown.jsを作成して、Javascript側の処理を作成
では、そんな感じで進めていきましょう!
carカスタム投稿を作成
カスタム投稿名はなんでもいいんですが、今回は「car」という名前にしてみました。
カスタム投稿タイプの作成には、ご存知【Custom Post Type UI】プラグインを使うのがいいと思います。
だって面倒くさくないし、簡単だし、【Custom Post Type UI】でのカスタム投稿タイプの作成に関しては、非常に丁寧に説明してくれているサイトが大量にあるので、ググってみてね(丸投げっ汗)。
で、とりあえず「car」というカスタム投稿タイプを作成して下さい。
cartypeタクソノミーを作成
カスタム投稿同様に【Custom Post Type UI】で、「cartype」タクソノミーを作成して下さい。
コレもわからなければググって下さいねー。
親タームメーカー、子ターム車種になるようにタームを作成
そのままなんですが、今作った「cartype」タクソノミーに、親タームメーカー、子ターム車種になるようにタームになる様にメーカーと車種を作っていって下さい。
パーマリンクの変更
設定のパーマリンクの変更から、共通設定を「投稿名」にチェックを入れて保存して下さい。
carカスタム投稿にそれぞれの中古車を登録
上記の設定でcarカスタム投稿から中古車を登録して、メーカーと車種のタクソノミーを設定できるようになりましたので、とりあえずサンプルを登録していって下さい。
archive.phpに絞り込み検索の土台となるformを設置
今回はサンプル作成に「Twenty Sixteen」のテーマを使いました。
とりあえず今回は、archive.phpのループの上くらいに下記のフォームを記入して下さい。
<form method="post" id="searchform" action="<?php home_url( '/' ) ?>"> <input type="hidden" name="s" id="s" value=""> <dl> <dt>メーカー</dt> <dd><?php get_maker_select() ?></dd> </dl> <dl> <dt>車種</dt> <dd> <select name="vehicle" id="vehicle"></select> </dd> </dl> <input type="submit" class="searchsubmit" value="絞り込む"> </form>
メーカーのセレクトボックスを作る部分はの部分で、後ほどfunction.phpで作っていきます。
車種のセレクトボックスはその下のselectの部分で、後ほどdrilldown.jsとfunction.phpでAjaxで出力するようになります。
function.phpにPHP側の処理を作成
まず、デフォルトのjqueryを読み込まないようにwp_enqueue_scriptsフックにちょっと追加しましょう。
「Twenty Sixteen」では、add_action( 'wp_enqueue_scripts', 'twentysixteen_scripts' );という関数が既にフックされていますので、そのtwentysixteen_scripts関数の先頭に下記を追加して下さい。
wp_deregister_script('jquery');
wp_enqueue_script( 'jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js', array(), '1.7.1' );
ここまでの作業を終了していれば、下記はコピペでOKです。function.phpの下の方にでも書いておいて下さい。
何をしているかは簡単にソース内に記述しています。
//メーカーのセレクトボックスを作る
function get_maker_select () {
global $wp_query;
$actives = array();
foreach ( $wp_query->tax_query->queries as $val ) { //現在選択されているメーカーを取得
$actives = array_merge( $actives, $val['terms'] );
}
$terms = get_terms( 'cartype', array('hide_empty'=>0,'parent'=>0) ); //cartypeから親タームのみ取得
if ( !empty( $terms ) && !is_wp_error( $terms ) ){ //空じゃなかったらselectを作成していく
echo '<select name="maker" id="maker">';
echo '<option value="" date-tag_id="" ' . $selected . '>選択なし</option>';
foreach ( $terms as $term ) { //各opution作成ループ
if ( in_array( $term->slug, $actives) ) { //選択中だったらselectedをつける
$selected = 'selected';
} else {
$selected = '';
}
echo '<option value="' . $term->slug .'" date-tag_id="' . $term->term_id .'" ' . $selected . '>' . $term->name . '</option>'; //メーカーopution作成
}
echo '</select>';
}
}
//WPでajaxをするための準備
function include_drilldown(){
global $post;
wp_enqueue_script('drilldown', get_template_directory_uri().'/js/drilldown.js', array('jquery')); //wp_head()でdrilldown.jsを読み込む
wp_localize_script( 'drilldown', 'drilldown_vars', array(
'ajaxurl' => admin_url('admin-ajax.php'),
)
); //WPでAjaxをするための準備
}
add_action( 'wp_enqueue_scripts', 'include_drilldown'); //スクリプトをインクルードするアクションフック
//子タームをjsに返す
function kThePost () {
$maker_id = $_POST['maker']; //フォームからメーカーIDを取得
$termchildren = get_term_children( $maker_id , 'cartype' ); //メーカーIDから子ターム(車種)のIDの配列を取得
$result = array();
foreach ( $termchildren as $child ) { //車種のID配列を回す
$putarray = get_term_by( 'id', $child, 'cartype' ); //車種IDからオブジェクトを取得
array_push( $result, $putarray ); //子ターム(車種)配列を作っていく
}
header('Content-Type: application/json; charset=utf-8'); //お約束
echo json_encode($result); //jsに子ターム(車種)オブジェクトを渡す
die(); //お約束
}
add_action( 'wp_ajax_kthepost', 'kThePost'); //wp_ajax_アクション名でAjaxリクエストハンドラを行うために実行
add_action( 'wp_ajax_nopriv_kthepost', 'kThePost' ); //wp_ajax_nopriv_アクション名でAjaxリクエストハンドラを行うために実行
//formから送られてきた情報を元にタクソノミーページにリダイレクトさせる
function showQ($vars) {
if ( isset( $_POST['s'] ) ) { //検索フォームからのPOSTで
if ( !empty( $_POST['vehicle'] ) && !empty( $_POST['maker'] ) ) { //メーカー名も車種も入っていたら
if ( mb_detect_encoding( $_POST['vehicle'] ) !== 'ASCII' ) {
$_POST['vehicle'] = urlencode( $_POST['vehicle'] );
}
$url = '/cartype/' . $_POST['vehicle'] . '/';
wp_redirect( home_url( $url ) ); //車種のタクソノミーページにリダイレクト
exit; //お約束
} else if ( !empty( $_POST['maker'] ) ) { //メーカーだけが入ってたら
if ( mb_detect_encoding( $_POST['maker'] ) !== 'ASCII' ) {
$_POST['maker'] = urlencode( $_POST['maker'] );
}
$url = '/cartype/' . $_POST['maker'] . '/';
wp_redirect( home_url( $url ) ); //メーカーのタクソノミーページにリダイレクト
exit; //お約束
}
}
return $vars;
}
add_filter( 'request', 'showQ'); // Query の VALUE
//ついでに管理画面の各投稿のカテゴリが勝手に並び替えられるのを止める
function lig_wp_category_terms_checklist_no_top( $args, $post_id = null ) {
$args['checked_ontop'] = false;
return $args;
}
add_action( 'wp_terms_checklist_args', 'lig_wp_category_terms_checklist_no_top' );
drilldown.jsを作成して、Javascript側の処理を作成
次はjs側の処理です。
drilldown.jsというファイルを作成し、下記をコピペしてjsフォルダに保存して下さい。
$( function () {
$(window).ready( function() {
selectRvent();
});
$("select#maker").on("load change", function () {
selectRvent();
} );
function selectRvent() {
$('#vehicle > option').remove();
var maker = $('[name=maker] option:selected').attr("date-tag_id");
$.ajax( {
type: 'POST',
url: drilldown_vars['ajaxurl'], //PHPから取得したadmin-ajax.phpまでのURL
data: {
'action' : 'kthepost', //Ajaxアクション名
'maker': maker
},
success: function( response ){ //PHPからメーカーオブジェクトを取得
$('#vehicle').append($('<option>').html('選択なし').val(''));
$.each( response, function(index, elem) {
$('#vehicle').append($('<option>').html(elem.name).val(elem.slug)); //optionを作成していく
if (decodeURI(elem.slug) == elem.vehicle) {
$('#vehicle').val(elem.slug);
}
} );
}
} );
}
} );
まとめ
実用するにはもうちょっと作り込む必要がありますが、これでとりあえずターム子タームを使ったAjaxのドリルダウンが実現できるはずです。
更に実際に絞り込み検索に使うのであれば、走行距離とか色とか色々な選択が出来るように作らなくてはなりません。
まぁとりあえず今回はWordPressのターム子タームでAjaxのドリルダウンをする時の参考として、今回は中古車屋さんの絞り込み検索を例としてやってみました。