Вопрос или проблема
На моём сайте есть пользовательский тип записи.
Я хотел бы предоставить пользователям возможность искать в рамках этого пользовательского типа записи. Поэтому я хочу, чтобы результаты поиска включали только записи этого конкретного типа.
Я также хотел бы предложить обычный поиск.
То есть, я хотел бы, чтобы на сайте были формы, содержащие стандартный поиск WordPress, позволяя пользователям искать в родных типах записей (Запись и Страница).
Поскольку я хочу предложить обычный поиск наряду с индивидуальным поиском, я не могу фильтровать запрос поиска с помощью хука ‘pre_get_posts’. Поэтому лучший вариант — настроить форму поиска.
Для типа записи mypost
со слагом myposts
у меня есть эта форма:
<form role="search" method="get"
id="searchform block"
class="search-form"
action="<?php echo esc_url(home_url("https://wordpress.stackexchange.com/")); ?>"
>
<div class="relative">
<label class="screen-reader-text" for="s"><?php esc_html_e('Поиск:', 'text-domain'); ?></label>
<input id="search-field"
type="search"
class="search-field outline-none"
value="<?php echo esc_html(get_search_query()); ?>" name="s" />
<input type="hidden" name="post_type" value="myposts" />
<button class="search-button cursor-pointer absolute right-0 top-0 bottom-0 m-auto py-5 px-4 ml-4" type="submit" id="searchsubmit">
<span class="sr-only"><?php esc_html_e('Поиск', 'text-domain'); ?></span>
</button>
</div> </form>
В параметре ввода value
я пробовал как mypost
, так и myposts
.
В любом случае, поиск вернёт ноль результатов.
Экземпляры пользовательского типа записи существуют.
Итак, как я могу создать рабочую форму, которая будет искать только результаты в целевом пользовательском типе записи?
Во-первых, убедитесь, что ваш пользовательский тип записи является общедоступным и доступным для поиска.
Во-вторых, вы не можете использовать переменную URL post_type
, она будет удалена, её зарезервировано для архива пользовательского типа записей.
Тем не менее, вы можете просто сделать поиск по пользовательскому типу записей с URL, подобным этому.
domain.com/custom-post-type-rewrite-slug/?s=My+Search+Term
Таким образом, в вашей форме действие должно быть
<?php echo esc_url(home_url('/custom-post-type-rewrite-slug/')); ?>
Добавьте и удалите этот скрытый ввод для post_type
<input type="hidden" name="post_type" value="myposts" />
Кроме того, вы также можете установить свою собственную переменную запроса, а затем изменить запрос через хук действия pre_get_posts
, чтобы вы могли выполнять поиск по tld с одним или несколькими поддерживаемыми post_type
.
Просто добавьте переменную запроса первой
add_filter( 'query_vars', function( $vars ) {
$vars[] = 'ptype';
return $vars;
});
Теперь измените запрос, если ptype
присутствует в URL
add_action('pre_get_posts', function( $query) {
if ( !is_admin() && isset( $query->query['s'] ) && isset( $query->query['ptype'] ) ) {
$query->set('post_type', $query->query['ptype']);
}
return $query;
});
После добавления вы можете выполнить поиск, как ниже;
для поиска по единственному типу записи
domain.com/?ptype=whatever&s=search+term
для поиска по нескольким типам записи
domain.com/?ptype[]=whatever&ptype[]=post&s=search+term
Таким образом, если вы хотите поддерживать несколько типов записей в вашей форме поиска, вы можете просто добавить несколько скрытых вводов
<input type="hidden" name="ptype[]" value="whatever" />
<input type="hidden" name="ptype[]" value="post" />
.
Ответ или решение
Чтобы создать форму поиска, которая ищет только в вашем пользовательском типе записи в WordPress, вам понадобится внести несколько небольших, но важных изменений. Мы рассмотрим, как реализовать эту функциональность без необходимости использовать хук pre_get_posts
, поскольку вы хотите сохранить возможность стандартного поиска по записям и страницам.
Шаги для создания формы поиска по пользовательскому типу записи
-
Обеспечение публичности пользовательского типа записи: Убедитесь, что ваш пользовательский тип записи (например,
mypost
) публичный и поддерживает поиск. Это можно сделать, когда вы регистрируете пользовательский тип записи через функциюregister_post_type()
, установив аргументpublic
вtrue
иexclude_from_search
вfalse
. -
Создание формы поиска: Ваша форма поиска должна отправлять запросы непосредственно к архиву кастомного типа записи. Убедитесь, что в форме указано правильное действие (
action
), чтобы запросы обрабатывались правильно. Пример кода формы может выглядеть следующим образом:
<form role="search" method="get" id="searchform" class="search-form" action="<?php echo esc_url(home_url('/myposts/')); ?>">
<div class="relative">
<label class="screen-reader-text" for="s"><?php esc_html_e('Search for:', 'text-domain'); ?></label>
<input id="search-field" type="search" class="search-field outline-none" value="<?php echo esc_html(get_search_query()); ?>" name="s" />
<button class="search-button cursor-pointer absolute right-0 top-0 bottom-0 m-auto py-5 px-4 ml-4" type="submit" id="searchsubmit">
<span class="sr-only"><?php esc_html_e('Search', 'text-domain'); ?></span>
</button>
</div>
</form>
В данном случае мы убрали скрытое поле для post_type
, так как оно может быть удалено из URL-адреса.
-
Настройка обработки запросов: Вам также может потребоваться дополнительно изменить запрос через хук
pre_get_posts
, если вы хотите добавить возможность поиска по нескольким пользовательским типам записей. Однако в вашем случае это может не понадобиться, поскольку вы хотите отдельный поиск для каждого типа записи. -
Альтернативный метод с использованием пользовательских переменных запроса: Если вы хотите сохранить возможность поиска по разным типам записей, вы можете добавить пользовательскую переменную запроса и затем обрабатывать ее в хуке
pre_get_posts
. Пример кода для получения пользовательской переменной:
add_filter('query_vars', function($vars) {
$vars[] = 'ptype';
return $vars;
});
add_action('pre_get_posts', function($query) {
if (!is_admin() && isset($query->query['s']) && isset($query->query['ptype'])) {
$query->set('post_type', $query->query['ptype']);
}
return $query;
});
Теперь, если вы будете отправлять поисковый запрос, вы можете использовать такую структуру URL:
-
Для поиска по одному пользовательскому типу:
domain.com/?ptype=mypost&s=search+term
-
Для поиска по нескольким типам:
domain.com/?ptype[]=mypost&ptype[]=post&s=search+term
Заключение
Создание отдельной формы поиска для пользовательского типа записи в WordPress требует правильной настройки HTML формы и обработки запросов. Данный подход позволяет эффективно обрабатывать запросы без путаницы с другими стандартными записями. Убедитесь, что вы тестируете форму после всех изменений, чтобы убедиться в её корректной работе.
Эта реализация также оптимизирована для SEO, так как улучшает индексируемость специализированного контента для поисковых систем. Убедитесь, что структура ссылок и названия меток соответствуют нуждам вашего веб-сайта и его целевой аудитории.