Cửa sổ bật lên Tìm kiếm Tự động Hoàn thành dành cho WordPress

Tìm hiểu cách mở rộng hộp tìm kiếm trên trang web WordPress của bạn với cửa sổ bật lên tự động điền / đề xuất. Chúng tôi sẽ tạo một số mã PHP để thực hiện tìm kiếm phía sau và sử dụng jQuery để chuyển hộp văn bản tìm kiếm thành một cửa sổ bật lên tự động điền. Các trình xử lý AJAX của WordPress sẽ nhận các yêu cầu tìm kiếm đến cho chúng tôi và chúng tôi sẽ sử dụng một hàm PHP để trả về một chuỗi các chuỗi được đề xuất đơn giản.

Nó sẽ hoạt động như thế nào

Chúng tôi sẽ cần hai thành phần chính ở đây…
  1. Một thành phần JavaScript giao diện người dùng để xử lý dữ liệu nhập văn bản của người dùng và hiển thị các đề xuất tìm kiếm thả xuống.
    • Chúng tôi sẽ sử dụng thư viện tự động hoàn thành jquery-ui có sẵn để thực hiện việc này cho chúng tôi.
  2. Một thành phần PHP back-end để thực hiện tìm kiếm thực tế - tìm kiếm trong cơ sở dữ liệu cho cụm từ tìm kiếm được yêu cầu của người dùng.
    • Đây sẽ là một hàm đơn giản sử dụng WP_Query để chạy một vòng lặp WordPress tiêu chuẩn.
Chúng tôi sẽ bắt đầu bằng cách tạo một số tệp giữ chỗ và liên kết tệp PHP chính với funcitons.php của chủ đề con tùy chỉnh của chúng tôi. Sau đó, chúng ta sẽ kết hợp mã PHP back-end với nhau. Cuối cùng, chúng tôi sẽ làm cho bit JavaScript front-end hoạt động và kiểm tra tất cả.

Bắt đầu với một số giàn giáo

thông tin Trước khi bắt đầu, hãy đảm bảo rằng bạn đang sử dụng chủ đề con tùy chỉnh.

Điều đầu tiên cần làm là tạo một số tệp giữ chỗ để giữ mã của chúng tôi. Tạo một tệp PHP trong thư mục chính của chủ đề con tùy chỉnh của bạn có tên custom-ajax-search.php và dán phần sau vào đó. Chúng tôi sẽ thay thế điều này sau - điều này chỉ để bắt đầu mọi thứ.

/**
 * Custom AJAX Search (CAS)
 */
// Block direct access.
if (!defined('WPINC')) {
   exit('Do NOT access this file directly.');
}

Tiếp theo, tạo một thư mục con (một lần nữa, trong thư mục chính của chủ đề con tùy chỉnh của bạn) được gọi là custom-ajax-search và tạo hai tệp trống trong đó có tên là cas-frontend.csscas-frontend.js , vì vậy bạn sẽ kết thúc với một cái gì đó như cái này:

Bây giờ chúng ta cần “yêu cầu” tệp PHP chính của mình từ chủ đề con tùy chỉnh, vì vậy hãy mở functions.php và thêm mã sau vào đó:

/**
 * Custom AJAX Search (CAS) - autocomplete
 */
require_once 'custom-ajax-search.php';
Với giàn giáo tại chỗ, hãy tạo một số nội dung trên trang web WordPress của bạn có hộp tìm kiếm trang web trên đó. Trên trang hướng dẫn này, có hai… một là toàn cầu (trong menu chính của trang web) và một là Khối tìm kiếm Gutenberg tiêu chuẩn.

Đúng vậy, giả sử điều trên không làm hỏng trang web của bạn bằng cách nào đó, chúng tôi có thể tiếp tục với mã thực tế.

Bit PHP Back-End

Mã PHP back-end cần thực hiện hai công việc chính đối với chúng ta…
  1. Khởi tạo các thành phần mã của chúng tôi:
    1. Thiết lập trình xử lý action / hook WordPress của chúng tôi.
    2. Thêm JavaScript và CSS có liên quan vào trang.
  2. Xử lý các yêu cầu AJAX đến:
    1. Tìm kiếm nội dung trang web.
    2. Trả về một mảng chuỗi đơn giản ở định dạng JSON.
Mã để làm tất cả điều này là ngắn một cách đáng ngạc nhiên. Chỉ cần sao chép và dán phần sau vào custom-ajax-search.php , thay thế mã giàn giáo mà chúng ta đã có trong đó từ trước đó.
/**
 * Custom AJAX Search (CAS)
 *
 * https://wp-tutorials.tech/refine-wordpress/autocomplete-search-wordpress/
 */
// Block direct access.
if (!defined('WPINC')) {
   exit('Do NOT access this file directly.');
}
// Configure with these settings.
const CAS_ACTION_SEARCH = 'cas_search';
const CAS_DEFAULt_CSS_SELECTOR = 'form[role="search"] input[type="search"]';
const CAS_MAX_SEARCH_RESULT_COUNT = 5;
/*
 * Listen for incoming AJAX requests.
 */
function cas_init() {
   add_action('wp_ajax_nopriv_' . CAS_ACTION_SEARCH, 'cas_search');
   add_action('wp_ajax_' . CAS_ACTION_SEARCH, 'cas_search');
}
add_action('init', 'cas_init');
/**
 * Add our CSS and JS to the pages.
 */
function cas_enqueue_scripts() {
   $base_url = get_stylesheet_directory_uri() . '/' . pathinfo(__FILE__, PATHINFO_FILENAME) . '/';
   $theme_version = wp_get_theme()->get('Version');
   // Add our stylesheet.
   wp_enqueue_style('cas-frontend', $base_url . 'cas-frontend.css', null, $theme_version);
   // Enqueue and "localise" our script in the page footer.
   wp_enqueue_script('cas-frontend',
      $base_url . 'cas-frontend.js',
      array('jquery-ui-autocomplete'),
      $theme_version,
      true
   );
   wp_localize_script(
      'cas-frontend',
      'casData', array(
         'cssInputSelectors' => CAS_DEFAULt_CSS_SELECTOR,
         'ajaxAction' => CAS_ACTION_SEARCH,
         'ajaxUrl' => admin_url('admin-ajax.php'),
      )
   );
}
add_action('wp_enqueue_scripts', 'cas_enqueue_scripts');
/**
 * Our main search function.
 */
function cas_search() {
   $response = array();
   $search_query = wp_strip_all_tags($_POST['searchQuery']);
   // error_log('search: ' . $search_query);
   if (!empty($search_query)) {
      $args = array(
         'post_type' => 'post',
         'post_status' => 'publish',
         's' => $search_query,
         'posts_per_page' => CAS_MAX_SEARCH_RESULT_COUNT,
      );
      $query = new WP_Query($args);
      while ($query->have_posts()) {
         $query->the_post();
         $response[] = html_entity_decode(get_the_title());
      }
      // Usually you would call wp_reset_postdata() here, but we don't need
      // to because our code is the last thing that's going to happen - we're
      // calling wp_die().
   }
   echo json_encode($response);
   wp_die();
}

Mã phải dễ đọc và tuân theo một cấu trúc khá chuẩn cho loại trình tự yêu cầu và phản hồi dựa trên AJAX này.

Cốt lõi của chức năng tìm kiếm ngừng hoạt động AJAX tùy chỉnh mà chúng tôi đã xác định, được gọi là “ cas_search ” (được xác định bởi CAS_ACTION_SEARCH ). Các hành động thực tế mà WordPress sẽ đưa ra là wp_ajax_nopriv_cas_search (nếu người dùng chưa đăng nhập) và wp_ajax_cas_search (nếu người dùng đã đăng nhập).

quan trọng Thông thường, bạn muốn bao gồm một nonce WordPress trong phản hồi yêu cầu của mình, vì vậy bạn có thể xác minh các yêu cầu của người dùng đến. Nhưng… nonce là phiên cụ thể, vì vậy mỗi khách truy cập nên được chỉ định nonce của riêng họ. Hộp tìm kiếm của chúng tôi chắc chắn là hiển thị công khai và trang web của bạn có thể sẽ sử dụng một số loại plugin bộ nhớ đệm trang (ví dụ: Comet Cache). Bạn không bao giờ nên bao gồm một nonce trên một trang đã lưu trong bộ nhớ cache, bởi vì một khi trang được lưu vào bộ nhớ cache, mọi khách truy cập xem trang sẽ nhận được cùng một nonce.

Một số kiểu cần thiết

Thư viện jQuery UI Autocomplete (trong WordPress) không cung cấp kiểu riêng để xử lý những thứ như danh sách gợi ý bật lên. Vì vậy… chúng ta cần phải tự mình làm điều này. Đó là CSS khá đơn giản và nó có nghĩa là chúng tôi đã kiểm soát 100% cách cửa sổ bật lên của chúng tôi hiển thị. Dán phần sau vào tệp cas-frontend.css của bạn để bắt đầu.
/*
 * cas-frontend.css
 */
form[role="search"] {
    position: relative;
    padding: 0;
    margin: 0;
}
.ui-autocomplete {
    position: absolute;
    z-index: 1000;
    float: left;
    display: none;
    min-width: 8em;
    list-style: none;
    background-color: white;
    border: 1px solid rgba(0, 0, 0, 0.2);
    box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.2);
}
.ui-autocomplete .ui-menu-item-wrapper {
    display: block;
    padding: 0.5em 1em;
}
.ui-state-hover,
.ui-state-active {
    color: white;
    text-decoration: none;
    border: none;
    cursor: pointer;
    /* You probably want to change the background-color */
    background-color: blue;
}
.ui-helper-hidden-accessible {
    display: none;
}

Bit trình duyệt Front-End - JavaScript

Phần cuối cùng này, mã JavaScript dựa trên trình duyệt giao diện người dùng, sẽ khó và tốn thời gian để viết từ đầu. Vì vậy, chúng tôi sẽ không làm điều đó. Trong mã PHP, hãy lưu ý rằng tập lệnh cas-frontend.js của chúng tôi phụ thuộc vào jquery-ui-autocomplete , là một tập lệnh tiêu chuẩn được bao gồm trong WordPress. Đó là một cách dễ sử dụng để thêm các hộp tự động hoàn thành cửa sổ bật lên.

Sao chép và dán phần này vào cas-frontend.js .
/*
 * cas-frontend.js
 */
(function($) {
    'use strict';
    $(window).on('load', function() {
        // console.log('custom-ajax-search : load');
        if (typeof(casData) != 'undefined') {
            $(casData.cssInputSelectors).autocomplete({
                appendTo: $(event.target).closest("form"),
                minLength: 3,
                source: customSearchSource,
                select: searchSelectedItem
            });
            function searchSelectedItem(event, ui) {
                // Copy the slected item into the search text box.
                $(event.target).val(ui.item.label);
                // Find the clostest (parent) form and submit it.
                $(event.target).closest("form").submit();
            }
            function customSearchSource(request, response) {
                // console.log('search: ' + request.term);
                // Send the HTTP POST data to our server, with the action and
                // search term (searchQuery).
                $.post(casData.ajaxUrl, {
                        action: casData.ajaxAction,
                        searchQuery: request.term
                    },
                    function(data, status) {
                        var responseData = null;
                        if (data) {
                            // console.log('good response: ' + data);
                            var responseData = JSON.parse(data);
                        } else {
                            // console.log('bad response: ' + data);
                        }
                        if (Array.isArray(responseData)) {
                            response(responseData);
                        } else {
                            response([]);
                        }
                    }
                );
            }
        }
    });
})(jQuery);
Lưu ý các dòng được chú thích với các lệnh gọi đến console.log (…). Nếu bạn bỏ ghi chú những điều này, bạn sẽ thấy các thông báo chẩn đoán hữu ích trong bảng điều khiển JavaScript của trình duyệt. Chỉ cần nhớ bình luận chúng một lần nữa (hoặc xóa chúng) khi bạn hoàn thành… để giữ mọi thứ đẹp và ngăn nắp.

Logic chia ra như thế này:

  • Sau khi tài liệu được tải (sự kiện 'tải')…
    • Nếu biến toàn cục casDatađã được đặt (sử dụng hàm wp_localize_script () trong tệp PHP của chúng tôi)…
      • Đối với tất cả các bộ chọn CSS phù hợp ('form [role = "search"] input [type = "search"]'), hãy gọi hàm jQuery-UI, autocomplete()
        • "Source" handler:: customSearchSource Điều này sử dụng post()hàm jQuery để gọi hành động AJAX back-end cas_search của chúng ta và trả về kết quả dưới dạng một mảng chuỗi đơn giản.
        • Trình xử lý “select” searchSelectedItem :: Được gọi khi người dùng chọn một mục trong danh sách bật lên tự động hoàn thành. Chúng tôi sao chép mục đã chọn vào hộp văn bản tìm kiếm của chúng tôi và sau đó chúng tôi gửi biểu mẫu.
Nên làm vậy. Hãy chơi với nó và tận hưởng sự hài lòng.

Tinh chỉnh và mở rộng

Việc mở rộng và tùy chỉnh điều này sẽ khá dễ dàng, bởi vì chúng tôi đã giữ logic cốt lõi trong một chức năng nhỏ độc lập tuyệt vời… cas_search(). Tất cả những gì hàm này cần làm là điền vào $responsemảng bằng các chuỗi có liên quan / được đề xuất, lặp lại mảng ở định dạng JSON, sau đó gọi wp_die ().

Bạn có thể sửa đổi $argsđể nó chỉ tìm kiếm tiêu đề bài đăng hoặc có thể thay đổi post_type thành thứ gì đó phù hợp hơn với trang web của bạn, chẳng hạn như loại bài đăng tùy chỉnh. Bạn cũng có thể chuyển từ tìm kiếm các bài đăng sang tìm kiếm các thuật ngữ phân loại… bất cứ thứ gì bạn muốn. Chỉ cần trả về một mảng các chuỗi trong $response. Dễ.

Chúc bạn tìm kiếm trang web vui vẻ.