Как выполнить поиск только по заголовкам постов?
Есть скрипт, который ищет записи содержащие определенное слово.
Как доработать скрипт, чтобы поиск был только по заголовкам записей?
Текущий скрипт:
$args = array( 'posts_per_page' => -1, 'post_type' => array( 'jobs', 'services' ), 's' => 'инже', ); $search = new WP_Query( $args ); |
$args = array( 'posts_per_page' => -1, 'post_type' => array( 'jobs', 'services' ), 's' => 'инже', ); $search = new WP_Query( $args );
Результат, который мне нужен SQL запросом:
SELECT * FROM posts WHERE post_title LIKE '%инже%'
Дополнительно:
https://wordpress.stackexchange.com/questions/1870...
https://stackoverflow.com/questions/62350261/how-t...
Решение:
Спасибо Dymok за наводку)
1. Добавляем в functions.php темы
// find_posts_by_title_part — название функции, можно заменить на любое свое название // title_part — название нового параметра для WP_Query() function find_posts_by_title_part( $where, &$wp_query ){ global $wpdb; if ( $title_part = $wp_query->get( 'title_part' ) ) { $param = esc_sql( $wpdb->esc_like( $title_part ) ); $sql .= " AND " . $wpdb->posts . ".post_title LIKE '%" . $param . "%'"; } return $sql; } add_filter( 'posts_where', 'find_posts_by_title_part', 10, 2 ); |
// find_posts_by_title_part — название функции, можно заменить на любое свое название // title_part — название нового параметра для WP_Query() function find_posts_by_title_part( $where, &$wp_query ){ global $wpdb; if ( $title_part = $wp_query->get( 'title_part' ) ) { $param = esc_sql( $wpdb->esc_like( $title_part ) ); $sql .= " AND " . $wpdb->posts . ".post_title LIKE '%" . $param . "%'"; } return $sql; } add_filter( 'posts_where', 'find_posts_by_title_part', 10, 2 );
2. Пишем запрос к базе данных через WP_Query()
$args = array( 'posts_per_page' => -1, 'post_type' => array('projects', 'jobs', 'services'), 'order' => 'ASC', 'title_part' => 'инже', ); $query = new WP_Query( $args ); |
$args = array( 'posts_per_page' => -1, 'post_type' => array('projects', 'jobs', 'services'), 'order' => 'ASC', 'title_part' => 'инже', ); $query = new WP_Query( $args );
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Чтобы поиск WordPress искал только по заголовкам, нужно изменить SQL-условие поиска через фильтр
posts_search. Стандартный поиск ищет поpost_title,post_excerptиpost_content, поэтому простого параметра вWP_Queryдля «только заголовки» нет.Пример для основного поиска на фронтенде:
add_filter('posts_search', function ($search, WP_Query $query) { global $wpdb; if (is_admin() || ! $query->is_main_query() || ! $query->is_search()) { return $search; } $search_term = $query->get('s'); if ($search_term === '') { return $search; } $like = '%' . $wpdb->esc_like($search_term) . '%'; return $wpdb->prepare(" AND {$wpdb->posts}.post_title LIKE %s ", $like); }, 10, 2);
Если поиск должен работать только для конкретного типа записи, добавьте условие по
post_type:add_action('pre_get_posts', function (WP_Query $query) { if (! is_admin() && $query->is_main_query() && $query->is_search()) { $query->set('post_type', ['post']); } });
Для точного совпадения заголовка вместо
LIKEможно использовать=, но тогда частичные запросы перестанут находить записи. Код лучше держать в дочерней теме или mu-plugin. После внедрения проверьте поиск по слову, которое есть только в контенте: такая запись больше не должна появляться в результатах.Глобально такой фильтр лучше подключать только на время конкретного запроса, иначе вы измените поиск на всём сайте: в админке, виджетах, REST API и других местах. Поэтому безопаснее сделать отдельный параметр, например
title_part, и реагировать только на него.add_filter('posts_where', function ($where, WP_Query $query) { global $wpdb; $title_part = $query->get('title_part'); if ($title_part === '') { return $where; } $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_title LIKE %s", '%' . $wpdb->esc_like($title_part) . '%' ); return $where; }, 10, 2); $search = new WP_Query([ 'post_type' => ['jobs', 'services'], 'posts_per_page' => -1, 'title_part' => 'инже', ]);
Параметр
sздесь лучше не использовать, потому что WordPress ищет не только по заголовку, но и по контенту. Если записей много, не ставьтеposts_per_page => -1: добавьте пагинацию или лимит. Для точного поиска по началу заголовка замените шаблон на$wpdb->esc_like($title_part) . '%'.