Cercare solo articoli del blog (widget di ricerca predefinito di WordPress)

21 feb 2016, 22:23:17
Visualizzazioni: 18.3K
Voti: 4

Stavo utilizzando questo codice:

// Aggiunge un filtro per modificare la query di ricerca
add_filter( 'pre_get_posts','search_only_blog_posts' );

// Funzione per limitare la ricerca solo agli articoli del blog
function search_only_blog_posts( $query ) {

    if ( $query->is_search ) {
        // Imposta il tipo di post solo su 'post' (articoli del blog)
        $query->set( 'post_type', 'post' );
    }
    return $query;
}

...finché non ho realizzato che si applica praticamente a qualsiasi ricerca predefinita in WordPress (inclusa la ricerca nella pagina dell'elenco degli articoli nell'area di amministrazione, ecc.).

Come potrei fare in modo che il widget di ricerca cerchi solo gli articoli del blog (non post personalizzati, tassonomie, immagini, ecc.) senza che si applichi a qualsiasi ricerca predefinita di WP (solo alle ricerche dal widget) ?

O sarebbe più semplice creare un widget di ricerca personalizzato?

Preferirei utilizzare tutto ciò che WordPress offre e non reinventare la ruota.

0
Tutte le risposte alla domanda 5
6

@PieterGoosen ha una buona descrizione del perché la tua callback pre_get_posts ti sta dando problemi.

Ecco un'alternativa per limitare il widget di ricerca nativo al tipo di post post:

/**
 * Limita i widget di ricerca nativi al post type 'post'
 */
add_filter( 'widget_title', function( $title, $instance, $id_base )
{
    // Target del search base
    if( 'search' === $id_base )
        add_filter( 'get_search_form', 'wpse_post_type_restriction' );
    return $title;
}, 10, 3 );

function wpse_post_type_restriction( $html )
{
    // Esegui solo una volta
    remove_filter( current_filter(), __FUNCTION__ );

    // Inietta il valore post_type nascosto
    return str_replace( 
        '</form>', 
        '<input type="hidden" name="post_type" value="post" /></form>',
        $html 
    );
}

dove andiamo a modificare l'output della funzione get_search_form() ma solo per i widget di ricerca.

22 feb 2016 10:48:30
Commenti

Un metodo piuttosto insolito per usare il filtro widget_title ;-)

Pieter Goosen Pieter Goosen
22 feb 2016 10:59:26

sì, in questo caso è utile, il filtro widget_display_callback era un'altra possibilità ;-) @PieterGoosen

birgire birgire
22 feb 2016 11:12:33

Grazie per l'informazione, non si è mai troppo vecchi o troppo brutti per imparare qualcosa ;-)

Pieter Goosen Pieter Goosen
22 feb 2016 11:15:01

Entrambe sono ottime risposte, ma tendo a preferire quella più breve che utilizza la ricerca stessa di WordPress. @PieterGoosen, WP_Widget non dà un errore di deprecato? Non ho trovato alternative online (ho fatto solo alcune ricerche veloci, non è in cima alla mia lista di priorità al momento).

N00b N00b
22 feb 2016 18:59:06

@N00b No, penso che tu lo confonda con i costruttori di tipo PHP4 deprecati. Come ho detto, il mio codice viene dal core stesso, ho solo cambiato i nomi di conseguenza ;-)

Pieter Goosen Pieter Goosen
22 feb 2016 19:02:32

@PieterGoosen Ah, questo spiega molte cose, sembra che non abbia capito appieno l'errore di deprecato.. Grazie comunque. Posso usare la tua risposta per sistemare i miei widget. Due piccioni con una fava, bang!

N00b N00b
22 feb 2016 19:05:35
Mostra i restanti 1 commenti
1

Il tuo utilizzo di pre_get_posts è completamente sbagliato.

  • pre_get_posts è un'azione, non un filtro. Controlla il sorgente

    do_action_ref_array( 'pre_get_posts', array( &$this ) );
    

    Sì, add_filter funziona perché add_action chiama add_filter, ecco perché il tuo codice funzionerà. Ma per quanto riguarda l'uso corretto, è semplicemente sbagliato. Se qualcosa è un'azione, usa add_action(). Ha semplicemente senso

  • WP_Query::is_search (e WP_Query::is_search() per quel che vale) restituisce true su qualsiasi query in cui s viene passato a WP_Query. Ricorda, i tag condizionali all'interno di WP_Query non vengono impostati in base all'URL, ma in base alle variabili di query passate ad esso. Per la query principale, le variabili di query passate a WP_Query verranno dall'analisi dell'URL.

  • pre_get_posts altera tutte le istanze di WP_Query, query_posts e get_posts, front-end e back-end a prescindere, quindi dovresti mirare solo alla query principale se vuoi mirare solo a quella. Inoltre, vorresti mirare solo al front-end, specialmente per archivi e query di ricerca.

Ecco un esempio su come usare pre_get_posts correttamente per la query principale: (Puoi cambiare la chiusura in spaghetti normali se lo desideri, solo una nota, usa le chiusure solo se sei sicuro di non voler rimuovere l'azione in seguito poiché le funzioni anonime non possono essere rimosse)

add_action( 'pre_get_posts', function ( $q )
{
    if (    !is_admin()         // Solo front-end,
         && $q->is_main_query() // Solo la query principale
         && $q->is_search()     // Solo la pagina di ricerca
    ) {
        $q->set( 'post_type', ['my_custom_post_type', 'post'] );
    }
});

Per rispondere alla tua domanda sul widget di ricerca, ecco cosa ho trovato

  • Il widget di ricerca semplicemente chiama get_search_form()

  • Non c'è un filtro utile per mirare specificamente al widget di ricerca. I filtri disponibili in get_search_form() mireranno a tutti i moduli che utilizzano get_search_form()

Con quanto sopra, dovresti creare il tuo widget di ricerca con il tuo modulo personalizzato

Puoi provare quanto segue: (Modificato dal widget di ricerca del core, nota, tutto è non testato)

class My_Custom_Search extends WP_Widget {
    /**
     * Configura una nuova istanza del widget di ricerca.
     *
     * @since 1.0.0
     * @access public
     */
    public function __construct() {
        $widget_ops = [
            'classname'   => 'widget_custom_search', 
            'description' => __( "Un modulo di ricerca personalizzato per il tuo sito.")
        ];
        parent::__construct( 'custom-search', _x( 'Ricerca personalizzata', 'Il mio widget di ricerca personalizzato' ), $widget_ops );
    }

    /**
     * Mostra il contenuto per l'istanza corrente del widget di ricerca.
     *
     * @since 1.0.0
     * @access public
     *
     * @param array $args     Argomenti di visualizzazione inclusi 'before_title', 'after_title',
     *                        'before_widget', e 'after_widget'.
     * @param array $instance Impostazioni per l'istanza corrente del widget di ricerca.
     */
    public function widget( $args, $instance ) {
        /** Questo filtro è documentato in wp-includes/widgets/class-wp-widget-pages.php */
        $title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );
        echo $args['before_widget'];

        if ( $title ) {
            echo $args['before_title'] . $title . $args['after_title'];
        }

        $form = '<form role="search" method="get" class="search-form" action="' . esc_url( home_url( '/' ) ) . '">
            <label>
                <span class="screen-reader-text">' . _x( 'Cerca:', 'etichetta' ) . '</span>
                <input type="search" class="search-field" placeholder="' . esc_attr_x( 'Cerca &hellip;', 'placeholder' ) . '" value="' . get_search_query() . '" name="s" title="' . esc_attr_x( 'Cerca:', 'etichetta' ) . '" />
            </label>
            <input type="hidden" value="post" name="post_type" id="post_type" />
            <input type="submit" class="search-submit" value="'. esc_attr_x( 'Cerca', 'pulsante di invio' ) .'" />
        </form>';

        echo $form;

        echo $args['after_widget'];
    }

    /**
     * Mostra il modulo delle impostazioni per il widget di ricerca.
     *
     * @since 1.0.0
     * @access public
     *
     * @param array $instance Impostazioni correnti.
     */
    public function form( $instance ) {
        $instance = wp_parse_args( (array) $instance, ['title' => '')];
        $title = $instance['title'];
        ?>
        <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Titolo:'); ?> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>" /></label></p>
        <?php
    }

    /**
     * Gestisce l'aggiornamento delle impostazioni per l'istanza corrente del widget di ricerca.
     *
     * @since 1.0.0
     * @access public
     *
     * @param array $new_instance Nuove impostazioni per questa istanza inserite dall'utente via
     *                            WP_Widget::form().
     * @param array $old_instance Vecchie impostazioni per questa istanza.
     * @return array Impostazioni aggiornate.
     */
    public function update( $new_instance, $old_instance ) {
        $instance = $old_instance;
        $new_instance = wp_parse_args((array) $new_instance, ['title' => '')];
        $instance['title'] = sanitize_text_field( $new_instance['title'] );
        return $instance;
    }
}
22 feb 2016 09:08:16
Commenti

Per favore vedi il mio aggiornamento

Pieter Goosen Pieter Goosen
22 feb 2016 10:21:33
1

Puoi semplicemente inserire questo codice nel tuo file functions.php.

function SearchFilter($query) 
{
    if (($query->is_search)&&(!is_admin())) {
        $query->set('post_type', 'post');
    }
    return $query;
}

add_filter('pre_get_posts','SearchFilter');
12 apr 2016 15:53:09
Commenti

Ha funzionato perfettamente - molto bene!

manifestor manifestor
19 set 2018 17:43:32
1

Scrivi semplicemente questo codice nel tuo file functions.php del tema WordPress.

function wpdocs_my_search_form( $form ) {
$form = '<form role="search" method="get" id="searchform" class="searchform" action="' . home_url( '/' ) . '" >
<div><label class="screen-reader-text" for="s">' . __( 'Cerca:' ) . '</label>
<input type="text" value="' . get_search_query() . '" name="s" id="s" />
<input type="hidden" value="post" name="post_type" id="post_type" />
<input type="submit" id="searchsubmit" value="'. esc_attr__( 'Cerca' ) .'" />
</div>
</form>';

return $form;
} add_filter( 'get_search_form', 'wpdocs_my_search_form' );
16 set 2017 03:38:07
Commenti

Per favore, spiega perché questo aiuta... in una modifica. Grazie.

kaiser kaiser
16 set 2017 12:22:12
2
-3

Si prega di fare riferimento a questo codice e alle impostazioni nel seguente link

22 feb 2016 08:30:44
Commenti

Per favore pubblica una risposta reale, non un link a qualche pagina dove qualcuno potrebbe trovare una soluzione

Pieter Goosen Pieter Goosen
22 feb 2016 08:54:27

Inoltre questo è ciò che l'autore ha già, non lo aiuterà in alcun modo...

flomei flomei
22 feb 2016 09:54:18