Как создать пользовательский поиск для пользовательского типа записи?

Вопрос или проблема

У меня есть поле для поиска по записям в блоге, но мне нужно другое для пользовательского типа записи. Как я могу создать эту пользовательскую поисковую форму с другим макетом результатов поиска?

Вот что я попробовал и нашел решение в 3 шага. Предположим, ваш пользовательский тип записи – “продукты

1. Добавьте код функции, здесь вы можете указать 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');  //  переадресация на archive-search.php
  }   
  return $template;   
}
add_filter('template_include', 'template_chooser');    

2. Создайте шаблон результата поиска для пользовательского типа записи (archive-search.php)

        <?php
        /* Шаблон Название: Пользовательский Поиск */        
        get_header(); ?>             
        <div class="contentarea">
            <div id="content" class="content_right">  
                     <h3>Результат поиска для: <?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(); ?>">Читать далее</a></p>    
                    <span class="post-meta"> Запись от <?php the_author(); ?>    
                     | Дата: <?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. Создайте поисковую форму
    В этой поисковой форме значение “products” скрыто и она будет искать только продукты.

     <div>   
        <h3>Поиск продуктов</h3>
        <form role="search" action="<?php echo site_url("https://wordpress.stackexchange.com/"); ?>" method="get" id="searchform">
        <input type="text" name="s" placeholder="Поиск продуктов"/>
        <input type="hidden" name="post_type" value="products" /> <!-- // скрытое значение 'products' -->
        <input type="submit" alt="Поиск" value="Поиск" />
      </form>
     </div>
    

для дополнительной информации, я хотел бы ссылаться на это
http://www.wpbeginner.com/wp-tutorials/how-to-create-advanced-search-form-in-wordpress-for-custom-post-types/

Вот что работает для меня. Не так чисто, но я не смог заставить ни один из этих других ответов работать.

Поисковая форма для пользовательского типа записи:

<form role="search" method="get" class="search-form" action="<?php echo home_url( "https://wordpress.stackexchange.com/" ); ?>">
    <label>
        <span class="screen-reader-text"><?php echo _x( 'Поиск по:', 'label' ) ?></span>
        <input type="search" class="search-field" placeholder="<?php echo esc_attr_x( 'Поиск …', 'placeholder' ) ?>" value="<?php echo get_search_query() ?>" name="s" title="<?php echo esc_attr_x( 'Поиск по:', 'label' ) ?>" />
        <input type="hidden" name="post_type" value="book" />
    </label>
    <input type="submit" class="search-submit" value="<?php echo esc_attr_x( 'Поиск', 'submit button' ) ?>" />
</form>

В 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');

В 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') {?>

               /* Формат для пользовательского типа записи "book" */

           <?php } else { ?>

               /* Формат для пользовательских типов записей, которые не являются "book,"
               или вы можете использовать elseif, чтобы определить второй тип записи таким же образом, как выше. Копируйте формат по умолчанию здесь, если у вас 
               только один пользовательский тип записи. */

           <?php } ?>
    <?php } else { ?>

              /* Формат для отображения, когда параметр post_type
              не установлен (т.е. формат по умолчанию) */
<?php } ?>
<?php endwhile; else: ?>

/* Что отображать, если результатов нет. */

<?php endif; ?>

Естественно, во всех трех местах вам нужно будет заменить “book” на ваш пользовательский тип записи.

Надеюсь, это поможет кому-то!

Краткий код более актуален

 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');  //  переадресация на archive-search.php
  }   
  return $template;   
}
add_filter('template_include', 'template_chooser'); 

Я хотел использовать две разные формы для обычных поисков и моих поисков по пользовательскому типу записи.

Мой пользовательский тип записи использует другой заголовок, чем обычные страницы, на моей обычной странице вызов моей поисковой формы выглядит так:

<?php get_search_form(true); ?>

А вызов моей поисковой формы в заголовке пользовательского типа записи выглядит так:

<?php get_template_part('search','library'); ?>

В которой есть дополнительное поле:

<input type="hidden" name="post_type" value="library" /> //Где "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');  //  переадресация на archive-search.php
  }   
  return $template;   
}
add_filter('template_include', 'search_library');

Который проверяет, ищет ли поисковая форма по пользовательским полям, тем самым показывая поиск в пользовательском шаблоне, в противном случае используется обычный шаблон.

Правка: исправил вызов функции get_search_form(), который всегда возвращал бы true.

Чтобы исправить проблему с пустым вводом поиска, вы можете заменить код функции на этот:

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');  //  переадресация на archive-search.php
 }   
 return $template;   
}
add_filter('template_include', 'template_chooser');

У меня 10 пользовательских типов записей, у каждого из которых есть своя страница результатов поиска (разные макеты) и использование этого решения не работало для меня.

После дальнейших поисков я нашел этот подход, где вы условно загружаете шаблон search.php на основе наличия пользовательского типа записи в URL.

В основном в search.php вы вставляете это:

<?php

// проверьте, есть ли в URL тип записи + nonce для безопасности
if ( isset( $_GET['post_type'], $_GET['custom_search_nonce_field'] ) && wp_verify_nonce( $_GET['custom_search_nonce_field'], 'custom_search_nonce_action' ) ) {

// сохраняем это для последующего использования
$post_type = $_GET['post_type'];

// проверьте, существует ли шаблон поиска
if ( locate_template( 'search-' . $post_type . '.php' ) ) {
    // загрузите его и выйдите
    get_template_part( 'search', $post_type );
    exit;
}

}

?>

А поисковая форма будет выглядеть примерно так:

<form class="search" action="<?php echo home_url( "https://wordpress.stackexchange.com/" ); ?>">
  <input type="search" name="s" placeholder="Поиск&hellip;">
  <input type="submit" value="Поиск">
  <input type="hidden" name="post_type" value="kb_article">
<?php wp_nonce_field( 'custom_search_nonce_action', 'custom_search_nonce_field' ); ?>
</form>

В случае поиска по WooCommerce (тип записи продукта),
просто скопируйте файл woocommerce/templates/archive-product.php в вашу дочернюю тему и затем настройте его… 1 час на это!! 🙁

Я знаю, что это старая тема, но я использую пользовательские шорткоды в своем файле functions.php, чтобы включить поиск, привязанный к конкретным типам записей и, в моем случае, пользовательским таксономиям. Я использую Pods для архива видео-лекций по годам и хотел, чтобы поиск был только в пределах этого года. Это в настоящее время работает (в моем functions.php):

/*Пользовательский поиск для архива видео 2020 - добавляет шорткод [2020search] для поиска*/
function video2020searchform( $form ) {

    $form = '<form role="search" method="get" id="searchform" action="' . home_url( "https://wordpress.stackexchange.com/" ) . '" >
    <div class="my-custom-search"><label class="screen-reader-text" for="s">' . __('Поиск по:') . '</label>
    <input type="hidden" name="video_year" value="video-archive-2020" />
    <input type="text" value="' . get_search_query() . '" name="s" id="s" placeholder="Поиск по архивам 2020 года по спикеру или ключевому слову..." />
    <input type="submit" id="searchsubmit" value="'. esc_attr__('Поиск') .'" />
    </div>
    </form>';

    return $form;
}

add_shortcode('2020search', 'video2020searchform');
// конец формы поиска 2020.   

Затем у меня есть страница с основными видео за 2020 год, на которой выше нее находится шорткод формы поиска, чтобы пользователи могли искать по остальной части 2020 года. name="video_year" – это пользовательская таксономия, созданная Pods, тип записи также создается Pods и называется “видео”, а value="video-archive-2020" – это слуг, который мне нужен из года видео Pods. Если бы у вас был пользовательский тип записи “книги”, таксономия “жанр книги” и вы пытались бы ограничить поиск “приключениями”, “жанр книги” был бы ‘name’ и “приключения” был бы ‘value’. Надеюсь, это поможет кому-то, и спасибо всем за вышеуказанные ответы!

В моем случае поиск работал отлично. Мне просто нужно было отфильтровать запрос, чтобы искать только по типу записи Learndash Courses. Вот что я сделал:

// Фильтрует поиск, чтобы включать только тип записи 'sfwd-courses'
function fn_search_courses_only($query) {
 if ($query->is_search && !is_admin()) {
  $query->set('post_type', 'sfwd-courses');
 }
 return $query;
}
add_filter('pre_get_posts', 'fn_search_courses_only');

.

Ответ или решение

Чтобы создать пользовательский поиск для пользовательского типа записей (CPT) в WordPress, следуйте подробной инструкции, которую вы найдете ниже. Этот процесс охватывает три основных шага и предоставляет вам возможность настроить макет результатов поиска в соответствии с вашим дизайном.

Шаг 1: Добавление функции для выбора шаблона

Этот код позволяет сайту определить, какой шаблон использовать для вывода результатов поиска в зависимости от типа записей. Например, если пользователь ищет записи типа «продукты», шаблон будет перенаправлен на 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'); // Перенаправление на archive-search.php
    }
    return $template;
}
add_filter('template_include', 'template_chooser');

Шаг 2: Создание шаблона результатов поиска

Создайте файл archive-search.php в директории вашей темы. Это будет шаблон, который отображает результаты поиска для вашего пользовательского типа записей. Ниже приведен пример основного кода, который вы можете использовать:

<?php
/* Шаблон: Пользовательский поиск */        
get_header(); ?>
<div class="contentarea">
    <div id="content" class="content_right">  
        <h3>Результаты поиска для: <?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(); ?>">Читать далее</a></p>    
                    <span class="post-meta"> Автор: <?php the_author(); ?> | Дата: <?php echo date('j F Y'); ?></span>    
                </article><!-- #post -->    
            </div>
        <?php endwhile; endif; ?>
    </div><!-- content -->    
</div><!-- contentarea -->   
<?php get_sidebar(); ?>
<?php get_footer(); ?>

Шаг 3: Создание формы поиска

Теперь создайте HTML-код для вашей поисковой формы. Обратите внимание, что мы добавляем скрытое поле для указания типа записей, который будет использоваться для поиска.

<div>   
    <h3>Поиск продуктов</h3>
    <form role="search" action="<?php echo home_url('/'); ?>" method="get" id="searchform">
        <input type="text" name="s" placeholder="Поиск продуктов"/>
        <input type="hidden" name="post_type" value="products" /> <!-- Скрытое значение для 'products' -->
        <input type="submit" alt="Поиск" value="Поиск" />
    </form>
</div>

Дополнительные советы

  1. Фильтрация поискового запроса: Чтобы убедиться, что запрос поиска будет включать только записи заданного типа, добавьте следующий код в файл functions.php вашей темы:

    function searchfilter($query) {
        if ($query->is_search && !is_admin()) {
            if (isset($_GET['post_type'])) {
                $type = $_GET['post_type'];
                if ($type == 'products') {
                    $query->set('post_type', array('products'));
                }
            }
        }
        return $query;
    }
    add_filter('pre_get_posts', 'searchfilter');
  2. Безопасность данных: При работе с пользовательскими полями и запросами всегда учитывайте безопасность данных. Возможно, вам потребуется реализовать валидацию и экранирование, чтобы предотвратить XSS-атаки.

  3. Оптимизация для SEO: Не забывайте, что правильная структура заголовков и описание метатегов также важны для SEO. Убедитесь, что страницы результатов поиска используют соответствующие заголовки и метаданные для улучшения индексации.

Следуя вышеизложенной инструкции, вы сможете создать функциональный и эстетически приятный пользовательский поиск для вашего пользовательского типа записей в WordPress.

Оцените материал
Добавить комментарий

Капча загружается...