ライブオートフィル検索を作成する方法


22

現在、検索バーの下にライブ結果を表示するワードプレス検索機能を作成しようとしています。世界銀行のウェブサイトに例があります(下の画面)。入力した単語を補完するGoogle.comにあるようなオートフィルを探しているのではなく、サイトの実際の投稿を見つけたい。

Wordpress Answersなどのリソースを使用してスクラブを実行しようとしましたが、探しているものではないGoogleタイプの検索を実装しているだけです。正しい方向への助けやポイントは大歓迎です。

検索前

後に検索


ユーザーが提案をクリックするとどうなりますか?検索ボックスに入力するだけですか?
Rarst

それぞれの投稿に移動します。ユーザーは引き続き検索結果を通常どおり入力して取得できます。候補をクリックするだけで投稿に移動できます。
mmaximalist

私は充填のための迅速な解決策を念頭に置いていますが、より問題のあるリンクを...それについて考えます。
Rarst

回答:


20

以下では、jQuery UI Autocompleteを使用します。これは、3.3以降、WordPressに含まれています。(@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.js、Ajaxのネイティブ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を介して実際のデータベースクエリで検索を実行しようとすると、サーバーに過度のストレスがかかる可能性がありますが、すべての投稿を1つの大きな「wp_options」に保存するシステムを開発することですフィールドを検索し、検索が完了すると、実際の検索を行う代わりに、そこからクエリを実行します。ただし、投稿を作成または編集するたびに、このtext / serialized変数のチャンクを更新する必要があることを忘れないでください。

このソリューションの開発に時間を費やすつもりがない場合、この種の「ライブ検索」を行うことはお勧めしません。


2
このようなユースケースでは、MySQLリクエストのリソース使用量は、AjaxリクエストのWPコアをロードするヒットと比較して、まったく重要ではありません。
最悪

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.