Как переделать фильтр (нужен пример) по произвольным полям wp через get_posts?
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 );

}
Для произвольных полей используй wp-query, подробнее тут.
Вот пример $query = new WP_Query( array(
    'post_type' => 'post',
    'meta_query' => array(
        array(
            'key' => 'mood',
            'value' => 'happy',
        ),
    ),
) );
Собственно, в meta_query и передаёшь ключ и значение.