@CyMPuK

Как переделать фильтр (нужен пример) по произвольным полям wp через get_posts?

function go_filter() { // наша функция
  $args = array(); // подготовим массив 
  $args = array( 'posts_per_page' => $_GET['pages'] ); // вывод количества записей
  //$args = array( 'post_type' => 'demoshop' ); 
  $args['meta_query'] = array('relation' => 'AND'); // отношение между условиями, у нас это "И то И это", можно ИЛИ(OR)
  global $wp_query; // нужно заглобалить текущую выборку постов

  if ($_GET['тест'] != '') { // если передана фильтрация по разделу
    $args['meta_query'][] = array( // пешем условия в meta_query
      'key' => 'тест', // название произвольного поля
      'value' => $_GET['тест'] // переданное значение произвольного поля
      );
      
  }
    
  query_posts(array_merge($args,$wp_query->query)); // сшиваем текущие условия выборки стандартного цикла wp с новым массивом переданным из формы и фильтруем
}
  • Вопрос задан
  • 1861 просмотр
Решения вопроса 1
HeadOnFire
@HeadOnFire
PHP, Laravel & WordPress Evangelist
https://codex.wordpress.org/Class_Reference/WP_Query
https://codex.wordpress.org/Class_Reference/WP_Que...

UPDATE:

1. Создаем выпадающий список для фильтра со всеми уникальными значениями "брендов" (в соответствующем шаблоне - над Loop с постами, перед if( have_posts() ) ):
<?php
// Получаем все уникальные значения брендов
$brands = $wpdb->get_col(
	"SELECT DISTINCT meta_value FROM $wpdb->postmeta WHERE meta_key = 'brand'"
);

// Если бренды есть - строим блок с фильтром
if ( $brands ) : 
?>

<div class="filter">
	<span>Filter by brand:</span>
	<select name="brand" id="brand">
		<!-- Сброс фильтра в значение "все" (оно же по умолчанию)  -->
		<option value="All" 
				<?php echo ( empty( $_GET['brand'] ) || 'All' === $_GET['brand'] ) ? 'selected="selected"' : ''; ?>
		>All</option>
		<!-- Все бренды -->
		<?php foreach ( $brands as $brand ) : ?>
			<option value="<?php echo esc_html( $brand ); ?>" 
					<?php echo ( ! empty( $_GET['brand'] ) && $brand === $_GET['brand'] ) ? 'selected="selected"' : ''; ?>
			><?php echo esc_html( $brand ); ?></option>
		<?php endforeach; ?>
	</select>
</div>

<script>
jQuery('#brand').on('change', function(){
	window.location.href =  '<?php echo get_nopaging_url(); ?>' + '?brand=' + jQuery(this).val();
});
</script>
<?php endif; ?>

Конечно, этот кусочек javascript лучше перенести в свой файл скриптов, который подгружается через wp_enqueue_scripts(), данный пример для наглядности.

2. Хукаемся в основной запрос перед его выполнением, отлавливаем переменную и модифицируем запрос (это в functions.php):
/**
 * Меняем основной запрос по необходимости, непосредственно перед его выполнением, сохраняя все фичи (включая пагинацию)
 */
function my_filter_posts( $query ) {

	// Если это не главный запрос или админка - прекращаем выполнение
	if( ! $query->is_main_query() || is_admin() ) {
		return;
	}

	// Если есть GET-параметр brand с не пустым значением и оно не равно All - модифицируем запрос
	if( ! empty( $_GET['brand'] ) && 'All' != $_GET['brand'] ) {
		$query->set( 'meta_key', 'brand' );
		$query->set( 'meta_value', sanitize_text_field( $_GET['brand'] ) );
	}

}
add_action( 'pre_get_posts', 'my_filter_posts' );

3. И еще нам понадобится утилитарная функция get_nopaging_url() которую мы использовали в js (добавляем ее тоже в functions.php):
/**
 * Get current URL without /page/{pagenum}/ part if it's present
 */
function get_nopaging_url() {

	global $wp;

	$current_url =  home_url( $wp->request );
	$position = strpos( $current_url , '/page' );
	$nopaging_url = ( $position ) ? substr( $current_url, 0, $position ) : $current_url;

	return trailingslashit( $nopaging_url );

}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
OlegMifle
@OlegMifle
php-программист
Для произвольных полей используй wp-query, подробнее тут.
Вот пример
$query = new WP_Query( array(
    'post_type' => 'post',
    'meta_query' => array(
        array(
            'key' => 'mood',
            'value' => 'happy',
        ),
    ),
) );

Собственно, в meta_query и передаёшь ключ и значение.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы