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

    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 );
    
    }
    Ответ написан
    21 комментарий