¿Cómo crear una búsqueda personalizada para un tipo de publicación personalizada?
Tengo un campo de búsqueda para las entradas del blog, pero necesito otro para un tipo de publicación personalizada. ¿Cómo puedo crear este formulario de búsqueda personalizado con un diseño de resultados de búsqueda diferente?
Aquí está lo que he probado y obtuve una solución en 3 pasos. Digamos que tu tipo de entrada personalizada es "products"
1 . Agregar código de función aquí puedes especificar el 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'); // redirigir a archive-search.php
}
return $template;
}
add_filter('template_include', 'template_chooser');
2 . Crear plantilla de resultados de búsqueda para tipo de entrada personalizada ( archive-search.php )
<?php
/* Nombre de la Plantilla: Búsqueda Personalizada */
get_header(); ?>
<div class="contentarea">
<div id="content" class="content_right">
<h3>Resultados de búsqueda para: <?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(); ?>">Leer Más</a></p>
<span class="post-meta"> Publicado por <?php the_author(); ?>
| Fecha: <?php echo date('j F Y'); ?></span>
</article><!-- #post -->
</div>
<?php endwhile; ?>
<?php endif; ?>
</div><!-- content -->
</div><!-- contentarea -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>
Construir Formulario de Búsqueda
En este Formulario de Búsqueda, el valor "products" está oculto y solo buscará entradas de tipo product.<div> <h3>Buscar Productos</h3> <form role="search" action="<?php echo site_url('/'); ?>" method="get" id="searchform"> <input type="text" name="s" placeholder="Buscar Productos"/> <input type="hidden" name="post_type" value="products" /> <!-- // valor oculto 'products' --> <input type="submit" alt="Buscar" value="Buscar" /> </form> </div>
para más información, me gustaría dirigirte a
http://www.wpbeginner.com/wp-tutorials/how-to-create-advanced-search-form-in-wordpress-for-custom-post-types/

Consejo: al registrar el tipo de entrada, el argumento publicly_queryable debe establecerse en true. De lo contrario, get_query_var('post_type') nunca devolverá el valor post_type proporcionado en el argumento url. https://codex.wordpress.org/Function_Reference/register_post_type#Arguments

Otro consejo/sugerencia de edición: get_query_var('post_type')
devolvió un array (en lugar de una cadena) por lo que no se podía comparar directamente. Como solo estoy buscando un tipo de entrada a la vez, simplemente cambié mi variable $post_type
a $post_type[0]
.

¿hay alguna manera de reescribir la url de http://localhost:3000/?s=cloud%27&post_type=product
a http://localhost:3000/search/cloud/product

@YarGnawh Disculpa la respuesta tardía, revisa esto https://wordpress.stackexchange.com/questions/15418/pretty-permalinks-for-search-results-with-extra-query-var. También hay un plugin llamado rewrite https://wordpress.org/plugins/rewrite/

el filtro search_template
parece ser una alternativa más apropiada que template_include

El código anterior funcionó para mí. Solo necesité editar <?php the_exerpt(); ?> y cambiarlo por <?php the_excerpt(); ?>

Aquí está lo que funciona para mí. No es tan limpio pero no pude hacer funcionar ninguna de las otras respuestas.
Formulario de búsqueda para Tipo de Entrada Personalizada:
<form role="search" method="get" class="search-form" action="<?php echo home_url( '/' ); ?>">
<label>
<span class="screen-reader-text"><?php echo _x( 'Buscar:', 'etiqueta' ) ?></span>
<input type="search" class="search-field" placeholder="<?php echo esc_attr_x( 'Buscar …', 'placeholder' ) ?>" value="<?php echo get_search_query() ?>" name="s" title="<?php echo esc_attr_x( 'Buscar:', 'etiqueta' ) ?>" />
<input type="hidden" name="post_type" value="book" />
</label>
<input type="submit" class="search-submit" value="<?php echo esc_attr_x( 'Buscar', 'botón enviar' ) ?>" />
</form>
En 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');
En 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 para tipo de entrada personalizada "book" */
<?php } else { ?>
/* Formato para tipos de entrada personalizados que no son "book",
o puedes usar elseif para especificar un segundo tipo de entrada
de la misma manera que arriba. Copia el formato predeterminado aquí
si solo tienes un tipo de entrada personalizada. */
<?php } ?>
<?php } else { ?>
/* Formato a mostrar cuando el parámetro post_type
no está establecido (es decir, formato predeterminado) */
<?php } ?>
<?php endwhile; else: ?>
/* Qué mostrar si no hay resultados. */
<?php endif; ?>
Naturalmente, en los tres lugares necesitarás reemplazar "book" con tu tipo de entrada personalizada.
¡Espero que esto ayude a alguien!

Un código corto más actualizado
function template_chooser($template)
{
global $wp_query;
$post_type = $wp_query->query_vars["pagename"];
if( isset($_GET['s']) && $post_type == 'products' )
{
// Redirigir a archive-search.php
return locate_template('archive-search.php');
}
return $template;
}
add_filter('template_include', 'template_chooser');

Estaba buscando usar dos formularios diferentes para mis búsquedas normales y mis búsquedas en un tipo de entrada personalizada.
Mi tipo de entrada personalizada usa un encabezado diferente al de las páginas normales. En mi página normal, la llamada a mi formulario de búsqueda es:
<?php get_search_form(true); ?>
Y la llamada a mi formulario de búsqueda en el encabezado del tipo de entrada personalizada es:
<?php get_template_part('search','library'); ?>
El cual tiene un campo adicional:
<input type="hidden" name="post_type" value="library" /> //Donde "library" es mi tipo de entrada personalizada.
En el archivo functions.php tengo el siguiente código que has proporcionado.
/** Búsqueda personalizada para Biblioteca */
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'); // redirige a archive-search.php
}
return $template;
}
add_filter('template_include', 'search_library');
El cual detecta si el formulario de búsqueda está realizando una búsqueda dentro de campos personalizados, mostrando así la búsqueda en una plantilla personalizada; de lo contrario, usa la plantilla normal.
Edición: se corrigió la llamada a la función get_search_form() que habría devuelto true sin importar qué.

Vale la pena señalar que get_search_form('true')
debería ser get_search_form(true)
. get_search_form
está buscando una entrada booleana, por lo que debe ser true
o false
. Al envolverlo entre comillas, estás proporcionando una cadena de texto, no un parámetro booleano. Por la forma en que está configurada esta función, tanto 'true'
como 'false'
devolverían el mismo resultado, ya que ambos son cadenas no vacías (lo que hace que la función devuelva true en ambos casos).

Para solucionar el problema de la búsqueda con entrada vacía, puedes sustituir el código de la función por este:
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'); // redirigir a archive-search.php
}
return $template;
}
add_filter('template_include', 'template_chooser');

Tengo 10 CPT (Custom Post Types) cada uno con su propia página de resultados de búsqueda (con diferentes diseños) y usar esto no me estaba funcionando.
Después de investigar más, encontré este enfoque donde condicionas la plantilla search.php para cargar otra plantilla si hay un CPT en la URL.
básicamente en search.php insertas esto:
<?php
// verificar si hay un tipo de post en la URL + nonce para seguridad
if ( isset( $_GET['post_type'], $_GET['custom_search_nonce_field'] ) && wp_verify_nonce( $_GET['custom_search_nonce_field'], 'custom_search_nonce_action' ) ) {
// guardarlo para después
$post_type = $_GET['post_type'];
// verificar si existe una plantilla de búsqueda
if ( locate_template( 'search-' . $post_type . '.php' ) ) {
// cargarla y salir
get_template_part( 'search', $post_type );
exit;
}
}
?>
y el formulario de búsqueda sería algo así:
<form class="search" action="<?php echo home_url( '/' ); ?>">
<input type="search" name="s" placeholder="Buscar…">
<input type="submit" value="Buscar">
<input type="hidden" name="post_type" value="kb_article">
<?php wp_nonce_field( 'custom_search_nonce_action', 'custom_search_nonce_field' ); ?>
</form>

Sé que este es un tema antiguo, pero utilizo shortcodes personalizados en mi archivo functions.php para habilitar búsquedas vinculadas a tipos de contenido específicos y, en mi caso, taxonomías personalizadas. Uso Pods para un archivo de videoconferencias por año y quería que las búsquedas se realizaran solo dentro de ese año. Esto es lo que actualmente está funcionando (en mi functions.php):
/*Búsqueda personalizada para Archivo de Videos Año 2020 - agrega el shortcode [2020search] para la búsqueda*/
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">' . __('Buscar por:') . '</label>
<input type="hidden" name="video_year" value="video-archive-2020" />
<input type="text" value="' . get_search_query() . '" name="s" id="s" placeholder="Buscar en archivos 2020 por orador o palabra clave..." />
<input type="submit" id="searchsubmit" value="'. esc_attr__('Buscar') .'" />
</div>
</form>';
return $form;
}
add_shortcode('2020search', 'video2020searchform');
// fin del formulario de búsqueda 2020.
Luego tengo una página con los videos destacados de 2020, con el shortcode del formulario de búsqueda encima para que los usuarios puedan buscar el resto del contenido de 2020. name="video_year"
es la taxonomía personalizada creada por Pods, el tipo de contenido también está creado por Pods y se llama "videos", y value="video-archive-2020"
es el slug del año de video de Pods que necesito. Si tuvieras un tipo de contenido personalizado "books", una taxonomía "book-genre" y estuvieras tratando de restringir la búsqueda a "adventure", "book-genre" sería la entrada 'name' y "adventure" sería el 'value'. Espero que esto ayude a alguien, ¡y gracias a todas las respuestas anteriores!

En mi caso, la búsqueda funcionaba perfectamente. Solo necesitaba filtrar la consulta para buscar únicamente en el tipo de publicación de Cursos de Learndash. Esto es lo que hice:
// Filtra la consulta de búsqueda para incluir solo el tipo de publicación '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' );
