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


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.