Поиск постов среди всех сайтов сети WordPress Multisite

В этой статье я покажу вам, как реализовать поиск по всей сети WordPress Multisite:

  • стандартный поиск постов, но не для одного сайта, а для всех одновременно,
  • поиск по значениям (части значений) произвольных полей,
  • поиск рубрик/меток по части их названия или описания.

Поиск постов через параметр s= функции network_query_posts() (аналог query_posts()).

Посмотрите на этот пример ниже, он позволяет вывести все посты, которые найдены по запросу «вордпресс».

$args = array(
	's' => 'вордпресс', // поисковой запрос
	'posts_per_page' => -1
);
$nposts = network_query_posts( $args ); // или network_query_posts('s=вордпресс&posts_per_page=-1');
foreach ( $nposts as $npost ):
	echo '<p>' . $npost->post_title . '</p>';
endforeach;

Как переделать стандартный поиск WordPress, чтобы он искал по всем сайтам сети

Вообще тут есть два варианта — простой и сложный. Простой вариант — когда все результаты поиска отображаются на одной странице (ну или вы потом сможете сделать, чтобы подгружались новые при скролле), сложный вариант — это сделать рабочей стандартную вордпрессовскую постраничную навигацию.

Постараюсь предоставить вам подробнейший алгоритм на оба случая.

Простой вариант.

  1. Заходите во «Внешний вид > Виджеты» и вставляйте стандартный виджет поиска, куда вам нужно, для простого варианта его переделывать не придётся.
    Вставляем виджет поиска на сайт.
  2. В папке с темой находим файл search.php, отвечающий за вывод результатов поиска, открываем его.
    Файл search.php, отвечающий за вывод результатов поиска.

    В самое начало файла вам понадобится вставить:

    $args = array(
    	's' => get_search_query(), // или $_GET['s'] это и есть наш поисковой запрос
    	'posts_per_page' => -1
    );
    $network_posts = network_query_posts( $args );
  3. И последний шаг — в нём же выполнить несколько замен.
    В оригинале Заменить на
    if ( have_posts() ) : if( $network_posts ) :
    while ( have_posts() ) : foreach( $network_posts as $nw_post ) :
    the_post(); switch_to_blog( $nw_post->BLOG_ID );
    endwhile; restore_current_blog(); endforeach;

    Обратите внимание, файл search.php в каждой теме имеет абсолютно разное содержимое, чаще всего в него подгружаются другие файлы шаблонов, которые отвечают скажем, за отображение одной записи в результатах поиска, поэтому тут вам придётся поразбираться.

Сложный вариант.

  1. Для начала в папке с темой создайте файл шаблона с произвольным названием.
    Файл нового шаблона страниц.

    В самое начало файла вставьте что-то типа:

    <?php
    /*
     * Template name: Шаблон поиска по сети
     */
    $current_page = ( get_query_var('paged') ) ? get_query_var('paged') : 1; // или $wp_query->query['paged']
    $args = array(
    	's' => $_GET['s'], 
    	'posts_per_page' => get_option('paged'),
    	'paged'	=> $current_page
    );
    $network_posts = network_query_posts( $args );
    // далее содержимое файла search.php
    ?>

    После этих строчек кода смело вставляете всё содержимое файла search.php.

  2. Затем создаем новую страницу (в админке: Страницы > Добавить новую) и применяем для неё свой шаблон.
    Шаблон поиска по сети.
  3. Теперь в этом файле выполняем замены из таблицы выше.
  4. Перед функцией постраничной навигации (это может быть  wp_pagenavi();) вставляем $wp_query = $GLOBALS['network_query'];.
  5. В вашей форме поиска меняем атрибут action на ссылку на созданную вами страницу, приблизительный пример:
    <form action="http://ваш-сайт/poisk-multisite" method="GET">
    	<input type="text=" name="s" />
    	<button>Поиск</button>
    </form>

Рекомендую сначала разобраться с простым вариантом, тогда у вас уже точно не будет никаких проблем со сложным.

Поиск по значениям произвольных полей

Если этот заголовок вам ни о чем не говорит, рекомендую почитать про произвольные поля, про WP_Query и про meta_query.

$args = array(
	'posts_per_page'  => -1, // для удобства пусть выводятся все посты
	'meta_query' => array(
		'relation' => 'OR',
		array(
			'key'     => 'key1', // значение произвольного поля key1 должно содержать "wordcamp"
			'value'   => 'wordcamp',
			'compare' => 'LIKE'
		),
		array(
			'key'     => 'key2', // ИЛИ значение key2 должно содержать wp
			'value'   => 'wp'
			'compare' => 'LIKE'
		)
	)
);
$network_q_posts = network_query_posts( $args ); // то же самое можно реализовать и для одного сайта, заменив network_query_posts() на query_posts()
foreach( $network_q_posts as $network_q_post ) :
	echo '<p>' . $network_q_post->post_title . '</p>';
endforeach;
network_reset_query();

Поиск рубрик и элементов других таксономий

Вообще тут всё сводится к функции network_get_terms() и двум её аргументам: name_like (поиск по части названия) и description_like (поиск по части описания). Теперь примеры:

// ищем рубрики, описание которых содержит wordcamp
$network_cats = network_get_terms('category', 'description_like=wordcamp');
 
if( $network_cats ){
	foreach ( $network_cats as $network_cat ){
		echo $network_cat->name;
	}
}
// ищем метки, название которых содержит wp
$network_post_tags = network_get_terms('post_tag', 'name_like=wp');
 
if( $network_post_tags ){
	foreach ( $network_post_tags as $network_post_tag ){
		echo $network_post_tag->name;
	}
}

Тема не самая простая, поэтому пожалуйста, если у вас возникли вопросы, оставляйте их в комментариях.

Миша

Впервые познакомился с WordPress в 2009 году. Организатор и спикер на конференциях WordCamp. Преподаватель в школе Нетология.

Пишите, если нужна помощь с сайтом или разработка с нуля.

Чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или войдите.

Миша Рудрастых и WordPress

Полезности из мира WordPress и жизни студии.

Мой телеграм-канал