WordPress как на ладони
wordpress jino

Поиск по ключевому слову в мета поле. Как добавить произвольное поле в стандартный поиск WordPress

Есть стандартный поиск wordpress, который ищет посты по заголовку.

Мне нужно чтобы искал и по заголовку и по произвольному мета полю.

0
Гость 2 года назад
  • 0
    Kama4696

    Вариант 1

    Вот такой фильтр вам поможет:

    add_filter( 'pre_get_posts', 'dc_custom_search_query');
    function custom_search_query( $query ) {
    	if ( is_admin() || ! $query->is_main_query() || ! $query->is_search )
    		return;
    
    	$meta_key  = 'META_KEY'; // название ключа
    
    	$query->set('meta_query', array(
    		'relation' => 'OR',
    		array(
    			'key'     => $meta_key,
    			'value'   => $query->query_vars['s'],
    			'compare' => 'LIKE',
    		),
    		array(
    			'key'     => $meta_key,
    			'compare' => 'NOT EXISTS',
    		),
    	));
    
    	// $query->set('post_type', '__your_post_type__'); // необязательно
    
    }
    

    Измените META_KEY на название вашего метаполя и __your_post_type__ на название типа записи.

    Вариант 2

    add_action('posts_where_request', function( $where ){
    	if( ! is_admin() && is_main_query() && is_search() ) {
    		global $wpdb, $wp;
    		$where = preg_replace('/('. $wpdb->posts .'.post_title (LIKE \'%'. $wp->query_vars['s'] .'%\'))/i',
    			"$0 OR ($wpdb->postmeta.meta_key = 'META_KEY' AND $wpdb->postmeta.meta_value $1)",
    			$where
    		);
    	}
    	return $where;
    });
    add_filter('posts_join_request', function( $join ){
    	global $wpdb;
    	return $join .= " LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id) ";
    } );

    Не уверен в его работоспособности, нашел в сети, по идее должен работать. Он лишен недостатка первого варианта.

    Вариант 3

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

    $q1 = get_posts(array(
    	'post_type' => 'post',
    	'posts_per_page' => -1,
    	's' => $query,
    ));
    
    $q2 = get_posts(array(
    	'post_type' => 'post',
    	'posts_per_page' => -1,
    	'meta_query' => array(
    		array(
    		   'key'     => 'speel',
    		   'value'   => $query,
    		   'compare' => 'LIKE'
    		)
    	 ),
    ));
    
    $merged = array_merge( $q1, $q2 );
    
    if( $merged ){
    	// оставим только уникальные записи
    	$posts = array();
    	foreach( $merged as $post ){
    		$posts[ $post->ID ] = $post;
    	}
    
    	foreach( $posts as $post ){
    		setup_postdata($post);
    
    		// вывод через функции the_title() и т.д.
    	}
    }
    else
    	echo 'Не найдено...';
    Albinos 1.2 года назад

    Зачем в третьем варианте заново получать посты? Или они вытянутся из кеша?

    Kama 1.2 года назад

    Поправил, там чет ерунда какая-то ненужная была...

    Комментировать
На вопросы могут отвечать только зарегистрированные пользователи. Регистрация. Вход.