¿Cómo crear una búsqueda personalizada para un tipo de publicación personalizada?

7 mar 2013, 23:56:29
Vistas: 242K
Votos: 55

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?

1
Comentarios

En un caso de búsqueda de WooCommerce (tipo de post de producto), simplemente copia el archivo woocommerce/templates/archive-product.php a tu tema hijo y luego personalízalo... ¡1 hora para esto! :(

gtamborero gtamborero
2 dic 2020 13:19:05
Todas las respuestas a la pregunta 8
7
79

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

8 mar 2013 11:04:14
Comentarios

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

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

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

indextwo indextwo
8 abr 2016 18:51:24

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

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

Ronald Ronald
13 nov 2017 13:20:43

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

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

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

Cypher Cypher
2 feb 2021 06:02:43

¡Para ser una respuesta escrita hace 9 años, puedo confirmar que en 2022 todavía funciona y con gran precisión! ¡Excelente trabajo @Ronald, eres increíble!

Periklis Kakarakidis Periklis Kakarakidis
5 mar 2022 12:24:01
Mostrar los 2 comentarios restantes
0

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!

12 ene 2016 23:46:15
0

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

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

2 mar 2017 09:20:17
Comentarios

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

Mike Mike
22 feb 2018 03:29:40
1

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

Sería genial si explicas cómo funciona tu código y revelas la fuente del código

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

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

¿Debería haber una verificación de nonce aquí?

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

sí, especialmente en un formulario público, pero depende mucho de la configuración; lo agregué en este ejemplo esperando que haga que las personas sean más conscientes.

RwkY RwkY
23 feb 2024 19:32:30
0

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!

14 jul 2021 15:39:51
0

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