실시간 자동 완성 검색을 만드는 방법은 무엇입니까?


22

현재 검색 바 아래에 라이브 결과를 보여주는 워드 프레스 검색 기능을 만들려고합니다. 세계 은행 웹 사이트 에 예가 있습니다 (아래 화면). 입력 한 단어를 완성하는 Google.com에서와 같이 자동 완성을 찾고 있지는 않지만 사이트에서 실제 게시물을 찾으려고합니다.

Wordpress Answers 및 기타 유사한 리소스를 통해 스크럽을 시도했지만 내가 찾고있는 것이 아닌 Google 유형 검색을 구현하기 만했습니다. 올바른 방향의 도움이나 요점은 크게 감사하겠습니다.

검색 전

이후 검색


사용자가 제안을 클릭하면 어떻게됩니까? 검색 창을 채우시겠습니까?
Rarst

해당 게시물로 이동합니다. 사용자는 여전히 입력하고 검색 결과를 정상적으로 얻을 수 있지만 제안을 클릭하면 게시물로 연결됩니다.
맥시 멀리스트

나는 채우기에 대한 빠른 해결책을 염두에두고 있지만 더 문제가 많은 것을 연결하면 ... 생각할 것입니다.
Rarst

답변:


20

다음은 3.3 이후 WordPress에 포함 된 jQuery UI 자동 완성을 사용합니다. ( @Rarst : D 에서 형식을 빌 렸습니다 ).

그것은 여전히 ​​당신이 쫓고있는 것이 아니지만 좋은 출발점을 제공합니다. 다음은 기본 jQuery UI 스타일을 사용 하지만 현재 trac에서 해결 된 스타일을 사용 하여 플러그인 폴더에서 호출 할 수 있습니다.

class AutoComplete {

    static $action = 'my_autocomplete';//Name of the action - should be unique to your plugin.

    static function load() {
        add_action( 'init', array( __CLASS__, 'init'));
    }

    static function init() {
        //Register style - you can create your own jQuery UI theme and store it in the plug-in folder
        wp_register_style('my-jquery-ui','http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css');    
        add_action( 'get_search_form', array( __CLASS__, 'get_search_form' ) );
        add_action( 'wp_print_footer_scripts', array( __CLASS__, 'print_footer_scripts' ), 11 );
        add_action( 'wp_ajax_'.self::$action, array( __CLASS__, 'autocomplete_suggestions' ) );
        add_action( 'wp_ajax_nopriv_'.self::$action, array( __CLASS__, 'autocomplete_suggestions' ) );
    }

    static function get_search_form( $form ) {
        wp_enqueue_script( 'jquery-ui-autocomplete' );
        wp_enqueue_style('my-jquery-ui');
        return $form;
    }

    static function print_footer_scripts() {
        ?>
    <script type="text/javascript">
    jQuery(document).ready(function ($){
        var ajaxurl = '<?php echo admin_url( 'admin-ajax.php' ); ?>';
        var ajaxaction = '<?php echo self::$action ?>';
        $("#secondary #searchform #s").autocomplete({
            delay: 0,
            minLength: 0,
            source: function(req, response){  
                $.getJSON(ajaxurl+'?callback=?&action='+ajaxaction, req, response);  
            },
            select: function(event, ui) {
                window.location.href=ui.item.link;
            },
        });
    });
    </script><?php
    }

    static function autocomplete_suggestions() {
        $posts = get_posts( array(
            's' => trim( esc_attr( strip_tags( $_REQUEST['term'] ) ) ),
        ) );
        $suggestions=array();

        global $post;
        foreach ($posts as $post): 
                    setup_postdata($post);
            $suggestion = array();
            $suggestion['label'] = esc_html($post->post_title);
            $suggestion['link'] = get_permalink();

            $suggestions[]= $suggestion;
        endforeach;

        $response = $_GET["callback"] . "(" . json_encode($suggestions) . ")";  
        echo $response;  
        exit;
    }
}
AutoComplete::load();

12

자, 이것은 suggest.jsAjax에 native WP 코어를 사용 하고 수정되지 않은 get_search_form()호출의 기본 검색 양식에 바인딩하는 매우 기본적인 예제 코드입니다 . 정확히 요구 한 것은 아니지만 증분 검색은 완벽하게 얻는 데 큰 고통입니다. :)

class Incremental_Suggest {

    static function on_load() {

        add_action( 'init', array( __CLASS__, 'init' ) );
    }

    static function init() {

        add_action( 'wp_print_scripts', array( __CLASS__, 'wp_print_scripts' ) );
        add_action( 'get_search_form', array( __CLASS__, 'get_search_form' ) );
        add_action( 'wp_print_footer_scripts', array( __CLASS__, 'wp_print_footer_scripts' ), 11 );
        add_action( 'wp_ajax_incremental_suggest', array( __CLASS__, 'wp_ajax_incremental_suggest' ) );
        add_action( 'wp_ajax_nopriv_incremental_suggest', array( __CLASS__, 'wp_ajax_incremental_suggest' ) );
    }

    static function wp_print_scripts() {

        ?>
    <style type="text/css">
        .ac_results {
            padding: 0;
            margin: 0;
            list-style: none;
            position: absolute;
            z-index: 10000;
            display: none;
            border-width: 1px;
            border-style: solid;
        }

        .ac_results li {
            padding: 2px 5px;
            white-space: nowrap;
            text-align: left;
        }

        .ac_over {
            cursor: pointer;
        }

        .ac_match {
            text-decoration: underline;
        }
    </style>
    <?php
    }

    static function get_search_form( $form ) {

        wp_enqueue_script( 'suggest' );

        return $form;
    }

    static function wp_print_footer_scripts() {

        ?>
    <script type="text/javascript">
        jQuery(document).ready(function ($) {
            $('#s').suggest('<?php echo admin_url( 'admin-ajax.php' ); ?>' + '?action=incremental_suggest');
        });
    </script><?php
    }

    static function wp_ajax_incremental_suggest() {

        $posts = get_posts( array(
            's' => $_REQUEST['q'],
        ) );

        $titles = wp_list_pluck( $posts, 'post_title' );
        $titles = array_map( 'esc_html', $titles );
        echo implode( "\n", $titles );

        die;
    }
}

Incremental_Suggest::on_load();

0

물론 Ajax를 사용하여 수행해야하지만 여기에 문제가 있습니다. WordPress는 MySQL을 사용하므로 Ajax를 통한 실제 데이터베이스 쿼리로 검색을 채우려 고하면 검색에 서버에 부담을 줄 수 있지만 모든 게시물이 하나의 큰 "wp_options"에 저장되는 시스템을 개발해야합니다. 필드를 찾은 다음 실제 검색을 수행하는 대신 검색을 수행합니다. 그러나 게시물을 만들거나 편집 할 때마다이 텍스트 / 직렬화 된 변수 청크를 업데이트해야합니다.

이 솔루션을 개발하는 데 약간의 시간을 할애하지 않으려면 이런 종류의 "실시간 검색"을 수행하지 않는 것이 좋습니다.


2
이러한 유스 케이스에서 MySQL 요청의 리소스 사용량은 Ajax 요청에 대한 WP 코어로드 적중과 비교할 때 완전히 중요하지 않습니다.
Rarst

1
Ajax 요청을 수행하는 방법에 따라이 경우 실제로 모든 WP 코어가 필요하지는 않지만 최상의 시나리오는 $ wpdb를로드하고 필드를 검색하는 것입니다. 그러나 주 WP Ajax URL을 사용하면 잘 처리되지 않으면 둘 다 문제가 될 수 있다는 데 동의했습니다.
Webord

1
예, 수십만 개의 게시물에 들어 가지 않는 한 MySQL 성능에 병목 현상이 발생하지 않습니다. WP 코어는 훨씬 느립니다. 네트워크도 느립니다.
Rarst

예. 그러나 WP Core 시스템으로 일종의 Scalling을 수행하는 것이 훨씬 쉽고 빠릅니다. MySQL 시스템을 사용하면 속도가 느리고 어려워집니다. 그러나 정상적인 설치에서는 동의합니다.
Webord
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.