Come creare una ricerca personalizzata per un custom post type?
Ho un campo di ricerca per i post del blog, ma ho bisogno di un altro per un custom post type. Come posso creare questo modulo di ricerca personalizzato con un layout dei risultati di ricerca differente?

Ecco cosa ho provato e ho ottenuto una soluzione in 3 passaggi. Supponiamo che il tuo custom post type sia "products"
1 . Aggiungi il Codice della Funzione qui puoi specificare archive-search.php
function template_chooser($template)
{
global $wp_query;
$post_type = get_query_var('post_type');
if( $wp_query->is_search && $post_type == 'products' )
{
return locate_template('archive-search.php'); // reindirizza a archive-search.php
}
return $template;
}
add_filter('template_include', 'template_chooser');
2 . Crea il template dei risultati di ricerca per il custom post type (archive-search.php)
<?php
/* Template Name: Custom Search */
get_header(); ?>
<div class="contentarea">
<div id="content" class="content_right">
<h3>Risultati della ricerca per: <?php echo htmlentities($s, ENT_QUOTES, 'UTF-8'); ?> </h3>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<div id="post-<?php the_ID(); ?>" class="posts">
<article>
<h4><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h4>
<p><?php the_excerpt(); ?></p>
<p align="right"><a href="<?php the_permalink(); ?>">Leggi di più</a></p>
<span class="post-meta"> Pubblicato da <?php the_author(); ?>
| Data: <?php echo date('j F Y'); ?></span>
</article><!-- #post -->
</div>
<?php endwhile; ?>
<?php endif; ?>
</div><!-- content -->
</div><!-- contentarea -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>
Costruisci il Modulo di Ricerca
In questo Modulo di Ricerca, il valore "products" è nascosto e cercherà solo i post di tipo product.<div> <h3>Cerca Prodotti</h3> <form role="search" action="<?php echo site_url('/'); ?>" method="get" id="searchform"> <input type="text" name="s" placeholder="Cerca Prodotti"/> <input type="hidden" name="post_type" value="products" /> <!-- // valore 'products' nascosto --> <input type="submit" alt="Cerca" value="Cerca" /> </form> </div>
per saperne di più, vorrei rimandarti a questo link
http://www.wpbeginner.com/wp-tutorials/how-to-create-advanced-search-form-in-wordpress-for-custom-post-types/

Suggerimento: quando si registra il tipo di post, l'argomento publicly_queryable deve essere impostato su true. In caso contrario, get_query_var('post_type') non restituirà mai il valore post_type fornito nell'argomento url. https://codex.wordpress.org/Function_Reference/register_post_type#Arguments

Un altro suggerimento/modifica suggerita: get_query_var('post_type')
ha restituito un array (invece di una stringa) quindi non poteva essere confrontato direttamente. Poiché sto cercando un solo tipo di post alla volta, ho semplicemente modificato la mia variabile $post_type
in $post_type[0]
.

c'è un modo per riscrivere l'url da http://localhost:3000/?s=cloud%27&post_type=product
a http://localhost:3000/search/cloud/product

@YarGnawh Mi scuso per la risposta tardiva, dai un'occhiata a https://wordpress.stackexchange.com/questions/15418/pretty-permalinks-for-search-results-with-extra-query-var. C'è anche un plugin chiamato rewrite https://wordpress.org/plugins/rewrite/

il filtro search_template
sembra essere un'alternativa più appropriata a template_include

Il codice sopra ha funzionato per me. Ho solo dovuto modificare <?php the_exerpt(); ?> e cambiarlo in <?php the_excerpt(); ?>

Ecco cosa funziona per me. Non è così pulito ma non sono riuscito a far funzionare nessuna delle altre soluzioni.
Form di ricerca per Custom Post Type:
<form role="search" method="get" class="search-form" action="<?php echo home_url( '/' ); ?>">
<label>
<span class="screen-reader-text"><?php echo _x( 'Cerca:', 'etichetta' ) ?></span>
<input type="search" class="search-field" placeholder="<?php echo esc_attr_x( 'Cerca …', 'placeholder' ) ?>" value="<?php echo get_search_query() ?>" name="s" title="<?php echo esc_attr_x( 'Cerca:', 'etichetta' ) ?>" />
<input type="hidden" name="post_type" value="book" />
</label>
<input type="submit" class="search-submit" value="<?php echo esc_attr_x( 'Cerca', 'pulsante invio' ) ?>" />
</form>
Nel file functions.php:
function searchfilter($query) {
if ($query->is_search && !is_admin() ) {
if(isset($_GET['post_type'])) {
$type = $_GET['post_type'];
if($type == 'book') {
$query->set('post_type',array('book'));
}
}
}
return $query;
}
add_filter('pre_get_posts','searchfilter');
Nel file search.php:
<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<?php if(isset($_GET['post_type'])) {
$type = $_GET['post_type'];
if($type == 'book') {?>
/* Formato per il custom post type "book" */
<?php } else { ?>
/* Formato per i custom post type che non sono "book",
oppure puoi usare elseif per specificare un secondo post type
allo stesso modo di sopra. Copia il formato predefinito qui se
hai un solo custom post type. */
<?php } ?>
<?php } else { ?>
/* Formato da visualizzare quando il parametro post_type
non è impostato (cioè formato predefinito) */
<?php } ?>
<?php endwhile; else: ?>
/* Cosa visualizzare se non ci sono risultati. */
<?php endif; ?>
Naturalmente in tutti e tre i punti dovrai sostituire "book" con il tuo custom post type.
Spero che questo possa essere d'aiuto a qualcuno!

Un codice breve più attualizzato
function template_chooser($template)
{
global $wp_query;
$post_type = $wp_query->query_vars["pagename"];
// Se esiste un parametro di ricerca 's' nell'URL e il tipo di pagina è 'products'
if( isset($_GET['s']) && $post_type == 'products' )
{
// Reindirizza al template archive-search.php
return locate_template('archive-search.php');
}
return $template;
}
// Aggiunge il filtro per includere il template personalizzato
add_filter('template_include', 'template_chooser');

Stavo cercando di utilizzare due diversi moduli per le mie ricerche normali e le mie ricerche su un custom post type.
Il mio custom post type utilizza un header diverso rispetto alle pagine normali. Nella mia pagina normale, la chiamata al modulo di ricerca è:
<?php get_search_form(true); ?>
E la chiamata al modulo di ricerca nell'header del custom post type è:
<?php get_template_part('search','library'); ?>
Che ha un campo aggiuntivo:
<input type="hidden" name="post_type" value="library" /> //Dove "library" è il mio custom post type.
Nel file functions ho il seguente codice che hai fornito.
/** Ricerca Personalizzata per Library */
function search_library($template)
{
global $wp_query;
$post_type = get_query_var('post_type');
if( $wp_query->is_search && $post_type == 'library' )
{
return locate_template('search-library.php'); // reindirizza a archive-search.php
}
return $template;
}
add_filter('template_include', 'search_library');
Che rileva se il modulo di ricerca sta effettuando una ricerca all'interno dei campi personalizzati, mostrando così la ricerca in un template personalizzato, altrimenti utilizza il template normale.
Modifica: corretta la chiamata alla funzione get_search_form() che avrebbe restituito true in ogni caso.

Vale la pena notare che get_search_form('true')
dovrebbe essere get_search_form(true)
. get_search_form
cerca un input booleano, quindi o true
o false
. Racchiudendolo tra virgolette si sta passando una stringa, non un parametro booleano. Per come è configurata questa funzione, sia 'true'
che 'false'
restituirebbero lo stesso risultato, poiché sono entrambe stringhe non vuote (il che fa sì che la funzione restituisca true in entrambi i casi).

Per risolvere il problema della ricerca con input vuoto puoi sostituire il codice della funzione con questo:
function template_chooser($template)
{
global $wp_query;
$post_type = get_query_var('post_type');
if( isset($_GET['s']) && $post_type == 'products' )
{
return locate_template('archive-search.php'); // reindirizza a archive-search.php
}
return $template;
}
add_filter('template_include', 'template_chooser');

Ho 10 CPT (Custom Post Type) ciascuno con la propria pagina dei risultati di ricerca (layout diversi per ognuno) e usando questo non funzionava per me.
Dopo ulteriori ricerche, ho trovato questo approccio dove si condiziona il template search.php per caricare un altro template se c'è un CPT nell'URL.
Sostanzialmente in search.php inserisci questo:
<?php
// controlla se c'è un post type nell'URL + nonce per la sicurezza
if ( isset( $_GET['post_type'], $_GET['custom_search_nonce_field'] ) && wp_verify_nonce( $_GET['custom_search_nonce_field'], 'custom_search_nonce_action' ) ) {
// salvalo per dopo
$post_type = $_GET['post_type'];
// controlla se esiste un template di ricerca
if ( locate_template( 'search-' . $post_type . '.php' ) ) {
// caricalo ed esci
get_template_part( 'search', $post_type );
exit;
}
}
?>
e il modulo di ricerca sarà qualcosa del genere:
<form class="search" action="<?php echo home_url( '/' ); ?>">
<input type="search" name="s" placeholder="Cerca…">
<input type="submit" value="Cerca">
<input type="hidden" name="post_type" value="kb_article">
<?php wp_nonce_field( 'custom_search_nonce_action', 'custom_search_nonce_field' ); ?>
</form>

So che questa è una discussione datata, ma utilizzo shortcode personalizzati nel mio file functions.php per abilitare ricerche legate a specifici tipi di post e, nel mio caso, tassonomie personalizzate. Uso Pods per un archivio di video-lezioni organizzato per anno e volevo che le ricerche fossero limitate solo a quell'anno specifico. Questo è il codice attualmente funzionante (nel mio functions.php):
/*Ricerca personalizzata per Archivio Video Anno 2020 - aggiunge lo shortcode [2020search] per la ricerca*/
function video2020searchform( $form ) {
$form = '<form role="search" method="get" id="searchform" action="' . home_url( '/' ) . '" >
<div class="my-custom-search"><label class="screen-reader-text" for="s">' . __('Cerca per:') . '</label>
<input type="hidden" name="video_year" value="video-archive-2020" />
<input type="text" value="' . get_search_query() . '" name="s" id="s" placeholder="Cerca negli archivi 2020 per relatore o parola chiave..." />
<input type="submit" id="searchsubmit" value="'. esc_attr__('Cerca') .'" />
</div>
</form>';
return $form;
}
add_shortcode('2020search', 'video2020searchform');
// fine del modulo di ricerca 2020
Ho quindi una pagina con i video in evidenza del 2020, con lo shortcode del modulo di ricerca sopra di esso, così gli utenti possono cercare nel resto dei contenuti del 2020. name="video_year"
è la tassonomia personalizzata creata da Pods, il tipo di post è anch'esso creato da Pods e si chiama "videos", e value="video-archive-2020"
è lo slug dall'anno video di Pods di cui ho bisogno. Se avessi un tipo di post personalizzato "books", una tassonomia "book-genre" e stessi cercando di limitare la ricerca ad "adventure", "book-genre" sarebbe il valore del campo 'name' e "adventure" sarebbe il 'value'. Spero che questo possa essere d'aiuto a qualcuno, e grazie a tutte le risposte precedenti!

Nel mio caso, la ricerca funzionava perfettamente. Avevo solo bisogno di filtrare la query per cercare esclusivamente i post di tipo Corso Learndash. Ecco come ho fatto:
// Filtra la query di ricerca per includere solo i post di tipo 'sfwd-courses'
function fn_search_courses_only($query) {
if( $query->is_search && ! is_admin() ) {
$query->set( 'post_type', 'sfwd-courses' );
}
}
add_action( 'pre_get_posts', 'fn_search_courses_only' );
