[WordPress] JSでカテゴリ一覧を取得する

前回の投稿で、WordPressのデータをJSで取得する必要が生じたので、書いたコードを載せておく。
これはちょっと特殊で、
カテゴリの一覧を取得して、各カテゴリがoptionとなるセレクタ(プルダウンメニュー)として表示し、
その1つを選択すると、その子カテゴリの一覧が、メニューの下に表示されるという機能になる。

コードの中で “Type” と呼んでいるものは案件上の呼び方で、意味は「カテゴリ」のこと。

実際はこれ以外にも、タグなどを表示させるコードも書いてクエリーで切り替えるようにしているが、カテゴリに関する部分のみを抜粋した。

/* テンプレート側のコード */

$parent = get_query_var( 'outparent' );
$exclude = get_query_var( 'outexclude' );

if( $parent && !is_numeric( $parent ) ) {
    exit;
}
if( !preg_match( '/^[0-9\,]*$/', $exclude) ) {
    exit;
}
$args = array(
    'parent' => $parent,
    'exclude' => $exclude,
    'hide_empty' => 0
);
$terms = get_terms( 'projects_category', $args );
$arr_output = [];

foreach ( $terms as $term ) {
    $obj_output = new stdClass();
    $obj_output->id = $term->term_id;
    $obj_output->name = $term->name;
    $obj_output->url = get_term_link( $term->term_id, 'projects_category' );
    $obj_output->description = $term->description;
    $cat_meta = get_option( 'taxonomy_my_meta_'.$term->term_id );
    $obj_output->image_url = esc_url( $cat_meta['indeximg'] );

    $arr_output[] = $obj_output;
}
$json_output = json_encode($arr_output, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
echo $json_output;

このテンプレートは、output-api というスラッグの固定ページ用のテンプレートとして用意した。
JSからこの固定ページのURLを叩いてデータを取得する。

上記は、URLで与えられたクエリーの値を取得して、get_terms() のパラメータとして使用し、投稿タイプ projects のタームの配列を取得、ループで回して個々のタームのタイトル・URLなどのパラメータをオブジェクトのプロパティにしたうえで、新たな配列に順次追加する。
その配列をJSONに変換して出力する。

 

クエリーはWordPressで扱えるようにするために、 query_vars に追加する必要があるので、下記のように functions.php に記述をおこなった。

/* functions.php */

function my_add_query_vars( $vars ){
    $vars[] = 'outparent';
    $vars[] = 'outexclude';
    return $vars;
}
add_filter( 'query_vars', 'my_add_query_vars' );

 

表示部分(この場合トップページ)に用意するHTML

/* HTML */

<div class="type-selector"></div>
<div class="project-list"></div>

 

そして、JavaScript(jQuery)のコード

/* JS側のコード(jQuery) */

(function($){
$(function(){
    var apiUrl = 'http://xxxxxxx/output-api/?';

    var selector = {
        typeQuery: 'outparent=0',
        setType: function(){
            this.ajax(apiUrl + this.typeQuery, $('.type-selector'), '- Type -');
        },
        writeSelector: function(data, el, label){
            var options = JSON.parse(data);
            var tag = '<select>';
            tag  += '<option value="">' + label + '</option>';
            for(var i = 0; i < options.length; i++){
                tag += '<option value="' + options[i].id + '">' + options[i].name + '</option>';
            }
            tag += '</select>';
            el.html(tag);
        },
        ajax: function(url, el, label){
            $.ajax(url, {
                type: 'GET',
                dataType: 'text',
                async: true
            }).done(function(data){
                selector.writeSelector(data, el, label);
            }).fail(function(data){
                console.log(data);
            });
        }
    };
    selector.setType();

    var list = {
        typeListQuery: 'outexclude=257,258,259,260,261',
        allType: function(){
            this.ajax(apiUrl + this.typeListQuery);
        },
        byType: function(id){
            var query = 'outparent=' + id;
                this.ajax(apiUrl + query);
        },
        writeList: function(data){
            var list = JSON.parse(data);
            var tag = '';
            for(var i = 0; i < list.length; i++){
                tag += '<a href="' + list[i].url + '">';
                tag += '<div style="background-image:url(\'' + list[i].image_url + '\')"></div>';
                tag += '<p>' + list[i].name + '</p>';
                tag += '</a>';
            }
            $('.project-list').html(tag);
        },
        ajax: function(url){
            $.ajax(url, {
                type: 'GET',
                dataType: 'text',
                async: true
            }).done(function(data){
                list.writeList(data);
            }).fail(function(data){
                console.log(data);
            });
        }
    };
    list.allType();

    $('.type-selector').on('change', 'select', function(){
        var id = $(this).val();
        list.byType(id);
    });
});
})(jQuery);

上記で、
変数 selector に定義しているものが、selectタグ(プルダウンメニュー)に関するもの。
変数 list に定義しているものが、メニューの下に表示する子カテゴリ一覧に関するもの。
プルダウンメニューからType(カテゴリ)を選択すると、その子カテゴリ一覧がメニューの下に表示される。

outexclude= で除外カテゴリを列挙しているが、これらは親カテゴリのこと。何もせず取得すると親子カテゴリが混じってしまうので、親を取り除いて子カテゴリだけの一覧にするため。(自動的に子カテゴリだけに出来なくて残念だけど)

カテゴリ一覧という、あまり一般的でないケースについて長々と書いてしまったけど、参考になる人が居れば幸いです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です