Wie erstelle ich eine automatische Live-Suche?

22

Ich versuche gerade, eine WordPress-Suchfunktion zu erstellen, die Live-Ergebnisse unter der Suchleiste anzeigt. Es gibt ein Beispiel für die Weltbank Website (Abbildungen unten). Ich bin nicht auf der Suche nach einer automatischen Ausfüllung, wie sie auf Google.com zu finden ist und die von Ihnen eingegebenen Wörter vervollständigt, sondern möchte, dass sie tatsächliche Beiträge auf der Website findet.

Ich habe versucht, durch Wordpress Answers und andere ähnliche Ressourcen zu scrubben, habe aber nur eine Google-Suche implementiert, die nicht das ist, wonach ich suche. Jede Hilfe oder Hinweise in die richtige Richtung wäre sehr dankbar.

Vorher suchen

suche danach

mmaximalist
quelle
Was soll geschehen, wenn der Nutzer auf einen Vorschlag klickt? Füllen Sie einfach das Suchfeld damit?
Rarst
Führt Sie zum jeweiligen Beitrag. Der Benutzer kann weiterhin normal Suchergebnisse eingeben und abrufen. Nur durch Klicken auf Vorschläge wird der Beitrag weitergeleitet.
mmaximalist
Ich habe eine schnelle Lösung für das Befüllen im Sinn, aber das Verknüpfen ist problematischer ... Ich werde darüber nachdenken.
Rarst

Antworten:

20

Im Folgenden wird jQuery UI Autocomplete verwendet, das seit 3.3 in WordPress enthalten ist. (Ich habe das Format von @Rarst : D ausgeliehen).

Es ist immer noch nicht genau das, wonach Sie suchen, aber es gibt Ihnen einen guten Ausgangspunkt. Im Folgenden wird das grundlegende jQuery-UI-Styling verwendet. Sie können jedoch dasjenige verwenden, das derzeit in trac ausgearbeitet ist, und es aus Ihrem Plug-In-Ordner aufrufen.

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();
Stephen Harris
quelle
12

Ok, dies wäre ein sehr einfacher Beispielcode, der den nativen suggest.jsWP-Core für Ajax verwendet und an das Standardsuchformular gebunden ist (aus einem nicht geänderten get_search_form()Aufruf). Es ist nicht genau das, wonach Sie gefragt haben, aber die inkrementelle Suche ist ein großer Schmerz, um perfekt zu werden. :)

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();
Rarst
quelle
0

Du musst es natürlich mit Ajax machen, aber hier gibt es ein Problem. Da WordPress MySQL verwendet, überlasten Sie Ihren Server möglicherweise mit der Suche, wenn Sie versuchen, die Suche mit den tatsächlichen Datenbankabfragen durch Ajax zu füllen. Sie könnten jedoch ein System entwickeln, in dem alle Beiträge in einem großen "wp_options" gespeichert werden. Wenn eine Suche abgeschlossen ist, fragen Sie danach ab, anstatt eine echte Suche durchzuführen. Denken Sie jedoch daran, dass Sie diesen Textblock / diese serialisierte Variable jedes Mal aktualisieren müssen, wenn Sie einen Beitrag erstellen oder bearbeiten.

Wenn Sie nicht bereit sind, etwas Zeit für die Entwicklung dieser Lösung aufzuwenden, würde ich Ihnen diese Art der "Live-Suche" nicht empfehlen.

Webord
quelle
2
In einem solchen Anwendungsfall wäre die Ressourcennutzung von MySQL-Anfragen im Vergleich zum Treffer beim Laden des WP-Kerns für Ajax-Anfragen völlig unbedeutend.
Rarst
1
Abhängig davon, wie Sie versuchen, die Ajax-Anforderung auszuführen. In diesem Fall benötigen Sie nicht den gesamten WP-Kern für Ihre Antwort. Das beste Szenario wäre, einfach $ wpdb zu laden und nach Ihrem Feld zu suchen. Wir waren uns jedoch einig, dass die Verwendung der Haupt-URL von WP Ajax zu Problemen führen kann, wenn sie nicht richtig gehandhabt werden.
Webord
1
Ja, ich stelle nur fest, dass die Leistung von MySQL kein Engpass ist (es sei denn, Sie stoßen auf Hunderttausende von Posts und dergleichen). Der WP-Kern ist viel langsamer. Das Netzwerk ist auch langsamer.
Rarst
Ja, aber es ist viel einfacher und schneller, mit WP Core-Maschinen eine Art von Scalling durchzuführen. Mit MySQL-Maschinen ist langsamer und schwieriger. Aber bei einer normalen Installation stimme ich Ihnen zu.
Webord