Cum să creezi o căutare personalizată pentru un tip de postare customizat?
Am un câmp de căutare pentru articolele de blog, dar am nevoie de unul pentru un tip de postare personalizat. Cum pot crea acest formular de căutare personalizat cu un aspect diferit pentru rezultatele căutării?

Iată ce am încercat și am găsit o soluție în 3 pași. Să zicem că tipul tău personalizat de postare este "products"
1 . Adaugă Codul Funcției aici poți specifica 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'); // redirecționează către archive-search.php
}
return $template;
}
add_filter('template_include', 'template_chooser');
2 . Creează șablonul pentru rezultatele căutării pentru tipul de postare personalizat ( archive-search.php )
<?php
/* Template Name: Custom Search */
get_header(); ?>
<div class="contentarea">
<div id="content" class="content_right">
<h3>Rezultatul căutării pentru : <?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(); ?>">Citește mai mult</a></p>
<span class="post-meta"> Postat de <?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(); ?>
Construiește Formularul de Căutare
În acest Formular de Căutare, valoarea "products" este ascunsă și va căuta doar postări de tip product.<div> <h3>Caută Produse</h3> <form role="search" action="<?php echo site_url('/'); ?>" method="get" id="searchform"> <input type="text" name="s" placeholder="Caută Produse"/> <input type="hidden" name="post_type" value="products" /> <!-- // valoare ascunsă 'products' --> <input type="submit" alt="Caută" value="Caută" /> </form> </div>
pentru mai multe detalii, aș dori să vă direcționez aici
http://www.wpbeginner.com/wp-tutorials/how-to-create-advanced-search-form-in-wordpress-for-custom-post-types/

Sfat: când înregistrați tipul de postare, argumentul publicly_queryable trebuie setat la true. Dacă nu, get_query_var('post_type') nu va returna niciodată valoarea post_type dată în argumentul url. https://codex.wordpress.org/Function_Reference/register_post_type#Arguments

Alt sfat/sugestie de editare: get_query_var('post_type')
a returnat un array (în loc de un șir de caractere) așa că nu putea fi comparat direct. Deoarece caut doar un tip de postare odată, am schimbat simplu variabila mea $post_type
în $post_type[0]
.

există vreo modalitate de a rescrie URL-ul de la http://localhost:3000/?s=cloud%27&post_type=product
la http://localhost:3000/search/cloud/product

@YarGnawh Îmi cer scuze pentru răspunsul întârziat, verifică acest link https://wordpress.stackexchange.com/questions/15418/pretty-permalinks-for-search-results-with-extra-query-var. Există și un plugin numit rewrite https://wordpress.org/plugins/rewrite/

filtrul search_template
pare să fie o alternativă mai potrivită față de template_include

Codul de mai sus a funcționat pentru mine. A trebuit doar să modific <?php the_exerpt(); ?> și să-l schimb cu <?php the_excerpt(); ?>

Iată ce funcționează pentru mine. Nu este la fel de elegant, dar nu am reușit să fac să funcționeze niciuna dintre celelalte soluții.
Formular de căutare pentru Tipul de Postare Personalizat:
<form role="search" method="get" class="search-form" action="<?php echo home_url( '/' ); ?>">
<label>
<span class="screen-reader-text"><?php echo _x( 'Caută:', 'etichetă' ) ?></span>
<input type="search" class="search-field" placeholder="<?php echo esc_attr_x( 'Caută …', 'placeholder' ) ?>" value="<?php echo get_search_query() ?>" name="s" title="<?php echo esc_attr_x( 'Caută:', 'etichetă' ) ?>" />
<input type="hidden" name="post_type" value="book" />
</label>
<input type="submit" class="search-submit" value="<?php echo esc_attr_x( 'Caută', 'buton submit' ) ?>" />
</form>
În 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');
În 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') {?>
/* Format pentru tipul de postare personalizat "book" */
<?php } else { ?>
/* Format pentru tipurile de postări personalizate care nu sunt "book,"
sau puteți folosi elseif pentru a specifica un al doilea tip de postare
în același mod ca mai sus. Copiați formatul implicit aici dacă
aveți doar un singur tip de postare personalizat. */
<?php } ?>
<?php } else { ?>
/* Format de afișare când parametrul post_type
nu este setat (adică formatul implicit) */
<?php } ?>
<?php endwhile; else: ?>
/* Ce să afișezi dacă nu există rezultate. */
<?php endif; ?>
Bineînțeles, în toate cele trei locuri va trebui să înlocuiți "book" cu tipul dvs. de postare personalizat.
Sper că acest lucru ajută pe cineva!

Un cod scurt mai actualizat
function template_chooser($template)
{
global $wp_query;
$post_type = $wp_query->query_vars["pagename"];
if( isset($_GET['s']) && $post_type == 'products' )
{
return locate_template('archive-search.php'); // redirecționează către archive-search.php
}
return $template;
}
add_filter('template_include', 'template_chooser');

Căutam să folosesc două formulare diferite pentru căutările normale și pentru căutările într-un tip de postare personalizat.
Tipul meu de postare personalizat folosește un antet diferit față de paginile normale. Pe pagina mea normală, apelul către formularul de căutare este:
<?php get_search_form(true); ?>
Iar apelul către formularul de căutare în antetul tipului de postare personalizat este:
<?php get_template_part('search','library'); ?>
Care are un câmp suplimentar:
<input type="hidden" name="post_type" value="library" /> //Unde "library" este tipul meu de postare personalizat.
În fișierul functions am următorul cod pe care l-ați furnizat.
/** Căutare personalizată pentru Bibliotecă */
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'); // redirecționează către archive-search.php
}
return $template;
}
add_filter('template_include', 'search_library');
Care detectează dacă formularul de căutare efectuează o căutare în câmpurile personalizate, afișând astfel căutarea într-un șablon personalizat, în caz contrar folosește șablonul normal.
Editare: am corectat apelul funcției get_search_form() care ar fi returnat true indiferent de situație.

Merită menționat că get_search_form('true')
ar trebui să fie get_search_form(true)
. get_search_form
caută o valoare booleană de intrare, deci fie true
sau false
. Prin încadrarea în ghilimele, îi furnizați un șir de caractere, nu un parametru boolean. În modul în care este configurată această funcție, atât 'true'
cât și 'false'
ar returna același rezultat, deoarece ambele sunt șiruri de caractere non-goale (ceea ce face ca funcția să returneze true în ambele cazuri).

Pentru a rezolva problema căutării cu input gol, poți înlocui codul funcției cu acesta:
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'); // redirecționare către archive-search.php
}
return $template;
}
add_filter('template_include', 'template_chooser');

Am 10 CPT-uri (Custom Post Types) fiecare cu propria pagină de rezultate de căutare (cu layout-uri diferite) și folosind această metodă nu funcționa pentru mine.
După mai multe cercetări, am găsit această abordare unde condiționezi șablonul search.php să încarce un alt șablon dacă există un CPT în URL.
practic în search.php introduci acest cod:
<?php
// verificăm dacă există un tip de postare în URL + nonce pentru securitate
if ( isset( $_GET['post_type'], $_GET['custom_search_nonce_field'] ) && wp_verify_nonce( $_GET['custom_search_nonce_field'], 'custom_search_nonce_action' ) ) {
// îl salvăm pentru mai târziu
$post_type = $_GET['post_type'];
// verificăm dacă există un șablon de căutare
if ( locate_template( 'search-' . $post_type . '.php' ) ) {
// îl încărcăm și ieșim
get_template_part( 'search', $post_type );
exit;
}
}
?>
iar formularul de căutare ar arăta cam așa:
<form class="search" action="<?php echo home_url( '/' ); ?>">
<input type="search" name="s" placeholder="Caută…">
<input type="submit" value="Caută">
<input type="hidden" name="post_type" value="kb_article">
<?php wp_nonce_field( 'custom_search_nonce_action', 'custom_search_nonce_field' ); ?>
</form>

Știu că acest thread este vechi, dar folosesc shortcode-uri personalizate în fișierul meu functions.php pentru a activa căutări legate de tipuri specifice de postări și, în cazul meu, taxonomii personalizate. Folosesc Pods pentru o arhivă de prelegeri video organizată pe ani și am dorit ca căutările să fie doar în cadrul acelui an. Următorul cod funcționează în prezent (în fișierul meu functions.php):
/*Căutare personalizată pentru Arhiva Video An 2020 - adaugă shortcode [2020search] pentru căutare*/
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">' . __('Caută:') . '</label>
<input type="hidden" name="video_year" value="video-archive-2020" />
<input type="text" value="' . get_search_query() . '" name="s" id="s" placeholder="Caută în arhivele 2020 după speaker sau cuvinte cheie..." />
<input type="submit" id="searchsubmit" value="'. esc_attr__('Caută') .'" />
</div>
</form>';
return $form;
}
add_shortcode('2020search', 'video2020searchform');
// sfârșitul formularului de căutare 2020.
Apoi am o pagină cu videoclipurile evidențiate din 2020, cu shortcode-ul formularului de căutare deasupra, astfel încât utilizatorii să poată căuta în restul conținutului din 2020. name="video_year"
este taxonomia personalizată creată de Pods, tipul de postare este de asemenea creat de Pods și se numește "videos", iar value="video-archive-2020"
este slug-ul din anul video Pods de care am nevoie. Dacă aveți un tip de postare personalizat numit "books", o taxonomie "book-genre" și încercați să restricționați căutarea la "adventure", "book-genre" ar fi intrarea 'name' și "adventure" ar fi 'value'. Sper că acest lucru ajută pe cineva și mulțumesc tuturor pentru răspunsurile de mai sus!

În cazul meu, căutarea funcționa perfect. Trebuia doar să filtrez query-ul pentru a căuta exclusiv tipul de postări pentru Cursuri Learndash. Iată ce am făcut:
// Filtrează query-ul de căutare pentru a include doar tipul de postare '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' );
