WordPress で ajax を使う場合ちゃんとやり方が用意されていて、公式ディレクトリに公開するならこれに準拠した作り方をしないと怒られます(怒られるどころかとても親切にやり方を教えてくれます。本当にありがたいです。)。

さて、今回はフロントページに投稿のタイトルを10件ずつ読み込むというのを例にやってみます。

まずは、 functions.php に。

1
2
3
4
5
6
7
8
function my_enqueue_ajax_script() {
    if ( is_front_page() ) {
        wp_enqueue_script( 'jquery' );
        wp_enqueue_script( '【ハンドル名※なんでもOK】', '【このあと作る jQuery の絶対パス】', array ( 'jquery' ), false, true );
        wp_localize_script( '【↑と同じハンドル名】', '【変数名※競合しないようにユニークな名称にする】', array ( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
    }
}
add_action( 'wp_enqueue_scripts', 'my_enqueue_ajax_script' );

これで head 内にこんなコードが挿入されます。

1
2
3
4
5
<script type="text/javascript">
/* <![CDATA[ */
var 【wp_localize_script() で設定した変数名】 = {"ajax_url":"http:\/\/【あなたのサイトのホスト名】\/wp-admin\/admin-ajax.php"};
/* ]]> */
</script>

次に jQuery です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
jQuery(function($) {
    var posts_per_page = 10;// 何件ずつ読み込むか
    var page_count = 1;
    var offset = 0;
    var run_ajax = function() {
        if (page_count > 1)
            offset = posts_per_page * (page_count - 1);
        $.ajax({
            url: 【wp_localize_script() で設定した変数名】.ajax_url,
            type: 'POST',
            dataType: 'json',
            data: {
                action: '【アクション名(なんでもOK)】',
                offset: offset
            },
            async: true
        }).done(function(data){
            $('.items').append(data.html);
            if (!data.last)
                $('.more').show();
        });
    };
    var more = function() {
        $(this).hide();
        page_count++;
        run_ajax();
    };
    // 「さらに読み込むボタン(.more)」 をクリックしたらボタンは削除して ページ数を1ページ進め more() を実行する
    $(document).on('click', '.more', more);
    run_ajax();
});

次に実行するPHPです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function my_generate_json() {
    global $wp_query;
    $posts_per_page = 10;
    extract ( $_POST );
    $args = array (
        'post_type' => 'post',
        'posts_per_page' => $posts_per_page,
        'offset' => (int) $offset,
    );
    $wp_query = new WP_Query( $args );
    $html = '';
    if ( $wp_query->have_posts() ) {
        while ( $wp_query->have_posts() ) {
            $wp_query->the_post();
            $html .= get_the_title() . '<br>';
        }
        wp_reset_postdata();
    }
    $last = ( $wp_query->found_posts > ( $offset + $posts_per_page ) ) ? false : true;
    $json = json_encode ( array ( 'html' => $html, 'last' => $last ) );
    header ( 'Content-Type: application/json; charset=utf-8' );
    echo $json;
    exit;
}
add_action( 'wp_ajax_【jQuery で設定したアクション名】', 'my_generate_json' );
add_action( 'wp_ajax_nopriv_【jQuery で設定したアクション名】', 'my_generate_json' );

最後にフロントページのHTMLです。

1
2
<div class="items"></div>
<div class="more">さらに読み込む</div>

読み込みが遅ければ「さらに読み込む」と同じ要領で「読み込み中」を表示すればいいし、スクロールイベントで一番下までスクロールしたら more() を実行したりもできます。