Come creare una ricerca personalizzata per un custom post type?

7 mar 2013, 23:56:29
Visualizzazioni: 242K
Voti: 55

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?

1
Commenti

In un caso di ricerca WooCommerce (product post type), basta copiare il file woocommerce/templates/archive-product.php nel tuo tema child e poi personalizzarlo... 1 ora per questo!! :(

gtamborero gtamborero
2 dic 2020 13:19:05
Tutte le risposte alla domanda 8
7
79

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(); ?>
 
  1. 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/

8 mar 2013 11:04:14
Commenti

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

Gustavo Daniel Gustavo Daniel
21 mag 2015 20:46:45

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

indextwo indextwo
8 apr 2016 18:51:24

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 YarGnawh
6 nov 2017 18:33:07

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

Ronald Ronald
13 nov 2017 13:20:43

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

Alexey Kosov Alexey Kosov
19 lug 2018 16:02:55

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

Cypher Cypher
2 feb 2021 06:02:43

Per una risposta scritta 9 anni fa, posso confermare nel 2022 che funziona ancora e con grande precisione! Ottimo lavoro @Ronald sei fantastico!

Periklis Kakarakidis Periklis Kakarakidis
5 mar 2022 12:24:01
Mostra i restanti 2 commenti
0

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!

12 gen 2016 23:46:15
0

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'); 
16 nov 2015 06:18:12
1

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.

2 mar 2017 09:20:17
Commenti

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

Mike Mike
22 feb 2018 03:29:40
1

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');
16 set 2014 13:33:32
Commenti

Sarebbe fantastico se potessi spiegare come funziona il tuo codice e rivelare la fonte del codice

Pieter Goosen Pieter Goosen
16 set 2014 14:00:22
2

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&hellip;">
  <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>
2 feb 2021 18:01:37
Commenti

Ci dovrebbe essere un controllo nonce qui?

Adrian B Adrian B
4 ott 2023 14:23:53

sì, specialmente su un form pubblico, ma dipende molto dalla configurazione; l'ho aggiunto in questo esempio sperando che renderà le persone più consapevoli.

RwkY RwkY
23 feb 2024 19:32:30
0

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!

14 lug 2021 15:39:51
0

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' );
18 nov 2024 08:59:04