Поиск постов среди всех сайтов сети 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;
    }
}

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

Источник: misha.blog

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

Путешествует по миру и рассказывает всем о WordPress лично, у себя в блогах и на курсах в Санкт-Петербурге. Умеет просто объяснять сложные вещи, делает это красиво. Организовывает неплохие WordCamp's, но совсем не умеет слушать чужие доклады.

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

%d такие блоггеры, как: