Вопрос или проблема
У меня есть поле для поиска по записям в блоге, но мне нужно другое для пользовательского типа записи. Как я могу создать эту пользовательскую поисковую форму с другим макетом результатов поиска?
Вот что я попробовал и нашел решение в 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(); ?>
-
Создайте поисковую форму
В этой поисковой форме значение “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="Поиск…">
<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>
Дополнительные советы
-
Фильтрация поискового запроса: Чтобы убедиться, что запрос поиска будет включать только записи заданного типа, добавьте следующий код в файл
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');
-
Безопасность данных: При работе с пользовательскими полями и запросами всегда учитывайте безопасность данных. Возможно, вам потребуется реализовать валидацию и экранирование, чтобы предотвратить XSS-атаки.
-
Оптимизация для SEO: Не забывайте, что правильная структура заголовков и описание метатегов также важны для SEO. Убедитесь, что страницы результатов поиска используют соответствующие заголовки и метаданные для улучшения индексации.
Следуя вышеизложенной инструкции, вы сможете создать функциональный и эстетически приятный пользовательский поиск для вашего пользовательского типа записей в WordPress.