WordPressで、検索処理を非同期通信して結果を取得した後、ページネーションをクリックした時、遷移先が…/wp-admin/admin-ajax.php?となり、ページ内の表示が崩れてしまうので、その解決方法についてまとめました。
WordPressで検索処理を実装する際に参考にしてみてください。
▼解決前
▼解決後
目次
非同期処理について
非同期処理を使った検索の身近な例として、こんなものがあります。
・文字を入力すると候補が自動で出てくる機能
・検索したい項目にチェックを入れると検索結果がリアルタイムに切り替わる
これらは非同期処理を行っているので実現できています。
非同期処理はタスクを待機中に他のタスクを実行できる処理方法で、ページ遷移をはさむことなく、ページの一部だけを更新することで検索結果を表示することができます。
ページのリロードがないので、スムーズに検索ができます。また、必要なデータだけを通信するのでサーバーへの負荷を軽減することもできます。
WordPressでの非同期処理通信
WordPressでは、WordPress REST APIが搭載されており、管理画面を通さずにWordPressの投稿・カテゴリ、タグ、コンテンツ等をJSON形式で取得・更新・削除できます。
この記事では非同期処理を使って、カスタム投稿の絞り込みを行う方法を解説したいと思います。
【1】非同期通信用のJSファイルを読み込みセキュリティ用のトークンを読み込んだJSに渡す
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
add_action('wp_enqueue_scripts', function() {s $handle = "common"; $file = $_SERVER['HTTP_HOST'].'/assets/js/'. $handle. '.js'; wp_register_script($handle, $file, array('jquery'), '3.6.3', true); $localize = [ 'ajax_url' => admin_url('admin-ajax.php'), 'nonce_search' => wp_create_nonce('view_search_results'), ]; wp_localize_script($handle, 'localize', $localize); wp_enqueue_script($handle); }); |
・wp_register_script()でcommon.jsというファイルを読み込む準備をしています。
・wp_localize_script()でPHPからJSにデータを渡します。
ajax_urlはAjaxリクエストの送り先、nonce_searchはセキュリティトークンでnonce認証に使用されます。
・wp_enqueue_script()で実際にJSファイルを読み込んでいます。
1 2 3 4 5 6 7 8 9 |
function view_search_results() { $nonce = $_REQUEST['nonce']; if(wp_verify_nonce($nonce, 'view_search_results')) { get_template_part('template_parts/ajax-search'); } die(); } |
nonce認証を行う関数です。nonce認証はクロスサイトリクエストフォージェリ(CSRF)攻撃を防ぎ、正当なユーザーによる正当なリクエストであることを確認するために行います。
nonce認証でセキュリティトークンが正しいか確認出来たら、結果を表示するファイルを読み込む処理をしてあります。
1 2 3 4 |
add_action('wp_ajax_view_search_results', 'view_search_results'); add_action('wp_ajax_nopriv_view_search_results', 'view_search_results'); |
最後にのnonce認証を行う関数をフック登録します。「wp_ajax_」はWPにログインしているユーザー向け、「wp_ajax_nopriv_」はログインしてないユーザー向け。
両方書くことで、誰がアクセスしてもAjax検索が使えるようになります。
【2】結果を表示するファイルでページネーションの調整を行う
JSから検索のために入力した値を受け取り絞り込み検索を行います。
その後、ページネーションの調整を行います。下記はページネーションで使う関数です。
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
$parameter = $_GET['parameter'] ?? null; function pagination($pages, $paged, $range = 3) { $pages = (int) $pages; // float型で渡る可能性があるため明示的にint型に変換 $paged = $paged ?: 1; // $pagedが空の場合は1(最初のページ)を設定 // ボタンに使う表示テキスト $text_first = ""; $text_before = ""; $text_next = ""; $text_last = ""; // ページリンク生成用URLフォーマット設定(現在は未使用) $big = 9999999999; $args = array( 'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))), 'format' => '%#%', ); if ($show_only && $pages === 1) { // 1ページのみでも表示設定がtrueの場合 echo '<div class="pagination"><span class="current pager">1</span></div>'; return; } if ($pages === 1) return; // ページが1枚で表示設定もない場合は終了 if (1 !== $pages) { // 2ページ以上ある場合にページネーションを表示 echo '<div class="c-pagination-list">'; if ($paged > $range + 1) { // 「最初へ」のリンクを表示(未実装) } if ($paged > 1) { // 「前へ」のリンクを表示 echo '<a href="', str_replace("/wp-admin/admin-ajax.php?", "/case/page/" . ($paged - 1) . "/?", get_pagenum_link($paged - 1)), '" class="prev"><span class="txt">', $text_before, '</span></a>'; } for ($i = 1; $i <= $pages; $i++) { if ($i <= $paged + $range && $i >= $paged - $range) { // 現在ページの前後$rangeページを表示 if ($paged === $i) { echo '<span class="current page-numbers">', $i, '</span>'; } else { echo '<a href="', str_replace("/wp-admin/admin-ajax.php?", "/case/page/$i/?", get_pagenum_link($i)), '" class="page-numbers">', $i, '</a>'; } } } if ($pages > $range + 1): // 範囲外のページがある場合に「…」と最終ページを表示 echo '<span class="page-numbers dots">…</span>'; echo '<a href="', str_replace("/wp-admin/admin-ajax.php?", "/case/page/$pages/?", get_pagenum_link($pages)), '" class="page-numbers">', $pages, '</a>'; endif; if ($paged < $pages) { // 「次へ」のリンクを表示 echo '<a href="', str_replace("/wp-admin/admin-ajax.php?", "/case/page/" . ($paged + 1) . "/?", get_pagenum_link($paged + 1)), '" class="next page-numbers">', $text_next, '</a>'; } echo '</div>'; } } |
pagination()でページネーションを出力しています。表示崩れを解決するために大事なところはstr_replace()で「/wp-admin/admin-ajax.php?」とURLが出力されているところを「/カスタム投稿名/page/何ページ目かの数字」に書き換えるところです。これによりテーマファイル内に遷移できます。
【3】アーカイブページを調整する
ページネーション内のリンクをクリックした後はURLにクエリパラメータがついた状態になると思います。
これを利用し分岐処理を行い、遷移後も絞り込み結果が反映されている状態にします。これで検索処理を非同期通信し、ページネーションをクリックした後、ページ内の表示が崩れてしまう問題を解決できました。
まとめ
今回はWordPressでの非同期処理のやり方とページネーションで表示が崩れてしまう時の対策を記載しました。
非同期処理の検索は記事の絞り込みや地図検索等で使用することがあると思うのでその際は参考にしてみてください。
WordPressを使ったホームページ制作はBRISKにおまかせ!
BRISKはWordPressを使ったホームページ制作を得意としています。
ヒアリングから設計、公開後の運用支援に至るまで、一貫して丁寧に対応。外注に頼らず、細部まで配慮された提案が可能です。
新規ウェブサイト制作のお客様には3ヵ月間の無料保守サービスを提供していますので是非ご検討ください。
「何を掲載すればよいかわからない」といったご相談も歓迎しています。
無料でのご提案も行っていますので、まずはお気軽にお問い合わせください!