Cercare solo articoli del blog (widget di ricerca predefinito di WordPress)
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.

@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.

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

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

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

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 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 ;-)

Il tuo utilizzo di pre_get_posts
è completamente sbagliato.
pre_get_posts
è un'azione, non un filtro. Controlla il sorgentedo_action_ref_array( 'pre_get_posts', array( &$this ) );
Sì,
add_filter
funziona perchéadd_action
chiamaadd_filter
, ecco perché il tuo codice funzionerà. Ma per quanto riguarda l'uso corretto, è semplicemente sbagliato. Se qualcosa è un'azione, usaadd_action()
. Ha semplicemente sensoWP_Query::is_search
(eWP_Query::is_search()
per quel che vale) restituisce true su qualsiasi query in cuis
viene passato aWP_Query
. Ricorda, i tag condizionali all'interno diWP_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 aWP_Query
verranno dall'analisi dell'URL.pre_get_posts
altera tutte le istanze diWP_Query
,query_posts
eget_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 utilizzanoget_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 …', '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;
}
}

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' );

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