Как изменить поиск в теме WordPress для отображения только результатов WooCommerce?
Я совсем новичок и учусь по ходу дела.
Купил премиум-тему на Themeforest, не проверив функциональность различных страниц. Обращался в их поддержку, но решение не предложили.
Сейчас разбираюсь в коде с минимальными знаниями. Продолжаю учиться.
Может кто-то помочь мне с этим:
1- Я определил три файла (код ниже), которые могут решить эту проблему, думаю первый из них наиболее подходящий.
2- Поскольку я новичок, может кто-то указать, какое именно поле нужно редактировать? Это "( get_post_type() === 'job_listing') что нужно изменить?
Спасибо.
searchform.php
<form class="search-form" method="get" action="<?php echo esc_url( home_url( '/' ) );
?>" role="search">
<?php if ( get_post_type() === 'job_listing' ) {
echo '<input type="hidden" name="post_type" value="job_listing" />';
} ?>
<input class="search-field" type="text" name="s" id="s" placeholder="<?php esc_html_e
( 'Что вы ищете?', 'listable' ); ?>" autocomplete="off"
value="<?php the_search_query(); ?>"/>
<button class="search-submit" name="submit" id="searchsubmit"></button>
search.php:
<?php
/**
* Архив результатов поиска
*
* @link https://codex.wordpress.org/Template_Hierarchy
*
* @package Listable
*/
get_header(); ?>
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<header class="page-header">
<h1 class="page-title"><?php printf( esc_html__( 'Результаты поиска для: %s', 'listable' ), '<span>' . get_search_query() . '</span>' ); ?></h1>
</header>
<?php if ( have_posts() ) : ?>
<?php /* Начало цикла */ ?>
<div class="postcards">
<div class="grid">
<?php /* Начало цикла */ ?>
<?php while ( have_posts() ) : the_post(); ?>
<div class="grid__item postcard">
<?php
/*
* Подключение шаблона контента для конкретного формата записи.
* Если вы хотите переопределить это в дочерней теме, включите файл
* content-___.php (где ___ - название формата записи) и он будет использован вместо этого.
*/
get_template_part( 'template-parts/content', get_post_format() );
?>
</div>
<?php endwhile; ?>
</div>
<?php the_posts_navigation(); ?>
</div>
<?php else : ?>
<?php get_template_part( 'template-parts/content', 'none' ); ?>
<?php endif; ?>
</main><!-- #main -->
search-job_listings.php
<?php
/**
* Архив результатов поиска только по объявлениям
*
* @link https://codex.wordpress.org/Template_Hierarchy
*
* @package Listable
*/
get_header(); ?>
<div id="primary" class="content-area">
<div class="entry-content">
<main id="main" class="site-main" role="main">
<?php
global $current_jobs_shortcode;
$shortcode = '[jobs keywords="'. get_search_query() .'" show_filters="true"';
//получаем параметр show_map шорткода объявлений на странице объявлений (указанный в настройках WPJM)
//применим его здесь также
$show_map = listable_listings_page_shortcode_get_show_map_param();
if ( false === $show_map ) {
$shortcode .= ' show_map="false"';
} else {
$shortcode .= ' show_map="true"';
}
//получаем параметр orderby шорткода объявлений на странице объявлений (указанный в настройках WPJM)
//применим его здесь также
$orderby = listable_listings_page_shortcode_get_orderby_param();
$shortcode .= ' orderby="' . $orderby . '"';
//получаем параметр order шорткода объявлений на странице объявлений (указанный в настройках WPJM)
//применим его здесь также
$order = listable_listings_page_shortcode_get_order_param();
$shortcode .= ' order="' . $order . '"';
$shortcode .= ']';
//сохраняем шорткод для использования позже в фильтрах
//это нужно, потому что WPJM не передает параметры в некоторые фильтры
$current_jobs_shortcode = $shortcode;
echo do_shortcode( $shortcode );
$current_jobs_shortcode = null;
?>
</main><!-- #main -->
</div>
</div><!-- #primary -->
<?php
get_sidebar();
get_footer(); ?>

Я не уверен, что означает тип записи job_listing
— вероятно, это часть функционала вашей темы — но для ограничения результатов поиска по типу записи стандартным способом является подключение к действию pre_get_posts
WordPress в файле functions.php
вашей темы.
Поскольку вы новичок в этом, сначала вам стоит ознакомиться с несколькими другими ответами:
Затем, вооружившись этими знаниями, мы подключимся к действию pre_get_posts
в нашем functions.php
(для тестирования вы можете сделать это в текущей теме, но, как объяснено в ответе о дочерних темах выше, ваш код будет перезаписан при обновлении темы, поэтому лучше использовать дочернюю тему для его сохранения).
Откройте ваш functions.php
и добавьте:
add_action( 'pre_get_posts', 'wpse223576_search_woocommerce_only' );
function wpse223576_search_woocommerce_only( $query ) {
if( ! is_admin() && is_search() && $query->is_main_query() ) {
$query->set( 'post_type', 'product' );
}
}
Подробнее о том, как это работает, вы можете узнать в документации по pre_get_posts
. Как объяснено в первом ответе, действия и фильтры (известные вместе как «хуки») позволяют изменять работу ядра WordPress, плагинов и тем, либо выполняя код в нужный момент, либо принимая входные данные, изменяя их и возвращая. Так работает вся подключаемая архитектура WordPress.
В этом коде мы изменяем запрос WordPress перед его выполнением, чтобы он искал только записи типа product
. Так как WooCommerce использует этот тип записи для хранения товаров, в результатах поиска будут только товары WooCommerce (мы также проверяем, что это именно поисковый запрос, что мы не в админке и что это основной запрос — т.е. не меню или другой запрос — чтобы не затронуть лишнее).
И вот так вы можете ограничить поиск, чтобы показывались только результаты товаров WooCommerce.

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

@MojtabaRezaeian Вы имеете в виду из-за is_admin()
? Эта проверка нужна, чтобы код выполнялся только на фронтенде сайта, а не в админ-панели (поскольку хуки темы могут срабатывать и там). Она не влияет на то, залогинен ли администратор при просмотре фронтенда (для этого нужно использовать is_user_logged_in()
, возможно, с дополнительными проверками уровня пользователя).

@TimMalone Да, ты прав, мой друг. Это была моя ошибка, и, возможно, мне стоит удалить тот комментарий, так как он неверный. Но используя твой код, я не увидел никаких изменений, пока не убрал часть $query->is_main_query()
, и тогда он возвращает только товары, но после этого изменения возникает новая проблема - я получаю результаты дважды вместо одного раза. Я также поискал и добавил wp_reset_query();
и wp_reset_postdata();
в твой код, но всё равно получаю те же дублирующиеся результаты. Это очень странно и неожиданно.
