Como criar uma pesquisa ao vivo de preenchimento automático?

22

Atualmente, estou tentando criar uma função de pesquisa wordpress que mostra resultados ao vivo abaixo da barra de pesquisa. Há um exemplo no Banco Mundial site (telas abaixo). Não estou procurando um preenchimento automático, como você encontraria no Google.com.br, que completa as palavras digitadas, mas quero que ele encontre postagens reais no site.

Eu tentei fazer uma limpeza através do Wordpress Answers e outros recursos semelhantes, mas só consegui implementar uma pesquisa de tipo do Google que não é o que estou procurando. Qualquer ajuda ou orientação na direção certa seria muito apreciada.

pesquisar antes

pesquisar depois

mmaximalist
fonte
O que você deseja que aconteça quando o usuário clicar na sugestão? Basta preencher a caixa de pesquisa com ela?
Rarst
Leva você para a respectiva postagem. O usuário ainda pode digitar e obter os resultados da pesquisa normalmente, apenas o clique em sugestões direcionaria para a postagem.
Mmaximalist
Eu tenho uma solução rápida em mente para preenchimento, mas vincular mais problemático ... Vai pensar nisso.
Rarst

Respostas:

20

O seguinte usa o preenchimento automático da interface do usuário do jQuery, incluído no WordPress desde a versão 3.3. ( Emprestei o formato do @Rarst : D).

Ainda não é exatamente o que você procura, mas oferece um bom ponto de partida. A seguir, é utilizado o estilo básico da interface do usuário do jQuery, mas você pode usar o que está atualmente elaborado no trac e chamar isso da sua pasta de plug-in.

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
fonte
12

Ok, isso seria um exemplo de código muito básico que usa o suggest.jsnúcleo WP nativo do Ajax e vincula ao formulário de pesquisa padrão (de get_search_form()chamada não modificada ). Não é exatamente o que você pediu, mas a pesquisa incremental é uma grande dor para se aperfeiçoar. :)

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
fonte
0

Você deve fazer isso usando o Ajax, é claro, mas aqui há um problema. Como o WordPress usa o MySQL, você pode sobrecarregar o servidor com a pesquisa, se tentar preencher a pesquisa com as consultas reais do banco de dados através do Ajax, mas o que você pode fazer é desenvolver um sistema no qual todas as postagens sejam salvas em uma grande "wp_options" campo e, quando uma pesquisa é concluída, você consulta a partir dele em vez de fazer uma pesquisa real. Mas lembre-se de que você precisa atualizar esse pedaço de texto / variável serializada toda vez que criar ou editar uma postagem.

Se você não estiver disposto a gastar algum tempo para desenvolver essa solução, não recomendo que você faça esse tipo de "pesquisa ao vivo".

Webord
fonte
2
Nesse caso de uso, o uso de recursos das solicitações do MySQL seria completamente insignificante em comparação com o carregamento do núcleo do WP para solicitações do Ajax.
Rarst
1
Depende de como você está tentando fazer a solicitação do Ajax; nesse caso, você realmente não precisa de todo o núcleo do WP para sua resposta, o melhor cenário seria apenas carregar $ wpdb e procurar seu campo. Mas concordamos que, usando o URL principal do WP Ajax, os dois podem resultar em um problema, se não forem bem tratados.
Webord 20/02
1
Sim, estou apenas observando que o desempenho do MySQL não seria um gargalo (a menos que você entre em centenas de milhares de posts e afins). O núcleo do WP é muito mais lento. A rede também é mais lenta.
Rarst
Sim, mas fazer algum tipo de Scalling com máquinas WP Core é muito mais fácil e rápido. Com máquinas MySQL é mais lento e mais difícil. Mas em uma instalação normal, eu concordo com você.
Webord 20/02