Перейти к содержанию

Поиск и ограничения выборки WordPress

Публичный REST-список показывает карточки курсов, но обычному посетителю сайта нужен поиск. Он может помнить название технологии, а не знать, к какой сущности относится материал. Согласуем поиск «Веб-мастерской»: он выбирает опубликованные записи и курсы, показывает небольшие страницы результата и ясно сообщает отсутствие совпадений. Служебные страницы в эту учебную выборку не включаем. Результат урока — определённая область поиска и изменение основного запроса без случайного воздействия на панель редактора.

Поиск WordPress не является готовым поисковым движком по любой связанности данных. Основной запрос имеет параметры и правила отбора, а отдельные вторичные WP_Query могут работать иначе. Чтобы изменить именно пользовательский результат, используем action pre_get_posts и проверяем область применения. Справочник hook обращает внимание на различие основного запроса и других выборок. Без такого ограничения небольшая правка поиска легко меняет неожиданные списки.

Основной запрос и два вида материалов

Добавьте в Tools после REST-поля следующий полный фрагмент. Он не регистрирует отдельный API endpoint и не изменяет запрос клиента предыдущего урока:

function pw_workshop_search_scope(WP_Query $query): void {
    if (is_admin() || !$query->is_main_query() || !$query->is_search()) {
        return;
    }
    $query->set('post_type', ['post', 'pw_course']);
    $query->set('post_status', 'publish');
    $query->set('posts_per_page', 2);
    $query->set('orderby', ['date' => 'DESC', 'ID' => 'DESC']);
    $query->set('ignore_sticky_posts', true);
}
add_action('pre_get_posts', 'pw_workshop_search_scope');

Методы вызываются у переданного $query, чтобы определить состояние именно этого запроса. Условие is_admin() отделяет обычную административную область, но не является проверкой прав пользователя и не означает «пользователь администратор». Остальные проверки оставляют вторичные выборки и запросы других видов без изменения. Плагин не должен неожиданно ограничить редактору список всех записей двумя строками только потому, что так удобно показывать публичный поиск.

post_type выражает договор: посетитель ищет объяснения и карточки обучения, не «Контакты». Это можно изменить, если пользовательская задача требует служебных страниц. Однако расширение до «всех типов» может включить сущности, созданные сторонними плагинами, назначение которых мы не анализировали. Явный список проще сопровождать. Явное post_status: publish сохраняет публичный характер этого списка и для вошедшего редактора. Регистрация ещё одного типа в будущем не заставит наш поиск автоматически показать его без редакционного решения.

Сортировка использует дату и ID как дополнительный устойчивый порядок для одинаковых дат. Это не сортировка по педагогической значимости и не утверждение о лучшем ранжировании. Маленький posts_per_page: 2 выбран для наблюдения пагинации на учебных данных. У рабочего сайта размер должен соответствовать интерфейсу и стоимости запроса. Нельзя делать вывод о скорости поиска по одному списку из четырёх курсов и трёх записей без измерений.

Поле запроса и шаблон ответа

В parts/header.html основной темы добавьте перед закрытием header блок Search:

<!-- wp:search {"label":"Поиск материалов","showLabel":true,"buttonText":"Найти"} /-->

Это точная вставка, а не полный файл. В архиве после урока 20 есть целый header с прежней навигацией и новым поиском. У поля есть видимая подпись; placeholder не заменяет label, поскольку исчезает при вводе. Действительный вывод формы выполняет WordPress. Не создаём ручной JavaScript, который отправляет запрос в REST и оставляет URL браузера без состояния: текущий шаг использует обычную серверную поисковую страницу.

Создайте templates/search.html как отдельный шаблон. Полный снимок в архиве состоит из подключения header, main, Query Title типа search и того же наследующего Query со списком заголовков, выдержек, пагинацией и сообщением «Материалы не найдены», что использовался в index. У него нет самостоятельного фиксированного списка курсов. Query наследует уже изменённый основной запрос. Если установить независимую выборку только pw_course, страница может показывать курсы вместо результатов введённого слова.

Что именно считается совпадением

В исходных данных слово JavaScript встречается в названии соответствующего курса и в тексте страницы study. Наш поиск выбирает типы post и pw_course, поэтому служебная страница не должна добавиться лишь из-за совпадения текста. Это конкретный способ проверить область выборки. Поиск по словам стандартных полей не означает поиск по числу pw_lessons, любой таксономии и произвольной внешней базе. Если посетитель вводит «20», отсутствие курса может быть правильной границей текущего механизма.

Слово HTML встречается в названии курса и записи html-request. Ожидается результат из этих двух объектов, если их опубликованный текст и заголовки сохранены по серии. Слово, которое нигде не встречается, должно дать понятное отсутствие материалов. Это не серверная авария. Блок Query No Results позволяет объяснить состояние в оболочке страницы и сохранить общую навигацию. Не перенаправляйте любое отсутствие совпадений на главную, лишая человека возможности исправить запрос.

Добавьте в учебный набор ещё три опубликованные записи с уникальными слагами: css-layout «Как выбирать компоновку CSS», javascript-events «События JavaScript» и markdown-preview «Предварительный просмотр Markdown». В их первом абзаце укажите слово «мастерская», а в первоначальных трёх записях добавьте его также. Запрос этого слова даст шесть записей, если оно не присутствует в курсах. С размером два ожидаются три страницы; переходы должны сохранять поисковый контекст, а не превращаться в общую ленту.

Ошибки области и стоимости

Если в результатах появилась страница «Как учиться», сначала выясните, действует ли наш основной callback и не заменяет ли его другой код. Если число элементов отличается, проверьте статус записей, вхождения в курсах и источник выбранного шаблона. Эти наблюдения полезнее, чем увеличение количества копий запроса. Отдельный новый WP_Query может показать желаемые строки, но скрыть неправильную работу основной страницы и сломать ожидаемую пагинацию.

Стандартный поиск не обещает исправление опечаток, морфологию русского языка, синонимы и поиск по закрытому прогрессу. При росте материалов нужно анализировать реальные запросы посетителей, качество результатов и стоимость SQL, затем выбирать индекс или специализированное расширение. Внешний поисковый сервис также требует договора о передаваемых данных. Не отдавайте ему черновики или персональные сведения только ради расширения поиска по публичным урокам.

Ожидаемый итог — форма с подписью, ограниченная область post и pw_course, две строки на странице и сохранение поискового слова при пагинации. WordPress, запросы и просмотры здесь не запускались. Учебный архив содержит код и сценарии с not_run, а не подтверждённый поисковый индекс. Следующий урок оценит стоимость темы, расширений и запросов отдельно от правильности найденных материалов, чтобы ускорение не стало причиной потерянного содержания.

Оглавление серии