Добавление поста череp ajax на WordPress

Добавление поста произвольного типа с фронтэнда на ajax’е в WP

ajax-spray-uniwersalny-750-mlВсем йоханга!
Сегодня будем решать не простую задачу добавления поста с лицевой части сайта на WordPress, да еще и с помощью ajax, и не просто поста, а поста произвольного типа. В одной из прошлых статей мы разобралиськак быстро создать таксономии, посты произвольного типа, запилить к ним шаблоны и форму добавления, но этот случай добавления очень простой, работает на API плагина PODS и не освещает кучу подводных камней и сейчас мы это исправим и заодно разберемся как правильно юзать аякс в WordPress.

Итак, задача:

  • Сделать возможность добавления поста произвольного типа с фронт-энда, минуя админку.
  • Все должно работать без перезагрузки страницы, т.е. на аяксе.
  • Посты, помимо стандартных полей, имеют дополнительные поля, а также поле множественной загрузки картинок.
  • При добавлении, посты должны привязываться к терминам(элементам) таксономии, тоже произвольной.
  • Использовать можно только нативные механизмы WP.

У нас есть произвольный тип постов с полями:

  • заголовок(стандартное поле — post_title),
  • текст(стандартное — post_content),
  • миниатюра(стандартное поле типа файл, потом будем получать id загруженного файла — _thumbnail_id),
  • обычная строка(произвольное поле типа строка — string_field),
  • форматированный текст(произвольное, текстарея — text_field),
  • поле множественной загрузки файлов(произвольное типа файл, дополнительные поля добавляются с помощью jQuery — multifile_field).

Так же посты привязаны к двум произвольным таксономиям:

  • простая таксономия без вложенности, как тэги — custom_tax_like_tag,
  • таксономия с иерархией/вложенностью как у категорий — custom_tax_like_cat.

Причем если пост принадлежит к дочернему термину — он должен принадлежать и к родителю.
Жирным выделено название полей и слаги таксономий.

Решение: сделаем обычную форму со всеми полями, обработаем её отправку с помощью jQuery и плагинаjQuery-forms, примем полученные данные по всем правилам работы ajax в WordPress, все проверим, добавим пост с полями и медиафайлами, привяжем к таксономиям и вернем ответ.

Начнем.

0. Подготовим WP для использования аякса:
В WP существует свой механизм работы с аяксом и раз мы используем только стандартное API, то будем делать все по правилам.
Суем это в functions.php нашей темы:

add_action('wp_print_scripts','include_scripts'); // действие в котором прикрепим необходимые js скрипты и передадим данные 
function include_scripts(){
        wp_enqueue_script('jquery'); // добавим основную библиотеку jQuery
        wp_enqueue_script('jquery-form'); // добавим плагин jQuery forms, встроен в WP
        wp_enqueue_script('jquery-chained', '//www.appelsiini.net/projects/chained/jquery.chained.min.js'); // добавим плагин для связанных селект листов

        wp_localize_script( 'jquery', 'ajaxdata', // функция для передачи глобальных js переменных на страницу, первый аргумент означет перед каким скриптом вставить переменные, второй это название глобального js объекта в котором эти переменные будут храниться, последний аргумент это массив с самими переменными
			array( 
   				'url' => admin_url('admin-ajax.php'), // передадим путь до нативного обработчика аякс запросов в wp, в js можно будет обратиться к ней так: ajaxdata.url
   				'nonce' => wp_create_nonce('add_object') // передадим уникальную строку для механизма проверки аякс запроса, ajaxdata.nonce
			)
		);
}

Теперь у нас подключены нужные плагины и определены глобальные js переменные для граммотной работы с аяксом.

1. Запиливаем форму добавления:
Так как у нас есть вложенная таксономия, для удобства воспользуемся плагином jQuery chained, это для того, чтобы после выбора родительского термина, в следующий селектлист нам добавились только дочерние термины к выбранному. Еще сделаем ссылку, которая будет добавлять нам поля типа файл, для мультизагрузки картинок.
Пусть поля тайтл, постконтент и выборы терминов таксономий будут обязательны.

Ахтунг! Нельзя чтобы атрибут name у контроллов выбора терминов таксономии был таким же как слаг таксономии — вордпресс может пытаться отфильтровать контент по этой таксономии вместо того, что мы хотим.

Код формы:

<?php
// подготовим актуальные данные таксономий
$cats = get_terms('custom_tax_like_cat', 'orderby=name&hide_empty=0&parent=0'); // получим все термины(элементы) таксономии с иерархией
foreach ($cats as $cat) { // пробежим по каждому полученному термину
    $parents.="<option value='$cat->term_id' />$cat->name</option>"; // суем id и название термина в строку для вывода внутри тэга select
    $childs_array = get_terms('custom_tax_like_cat', 'orderby=name&hide_empty=0&parent='.$cat->term_id); // возьмем все дочерние термины к текущему
	foreach ($childs_array as $child){
		$childs.="<option value='$child->term_id' class='$cat->term_id' />$child->name</option>"; // делаем то же самое, класс должен быть равным id родительского термина чтобы плагин chained работал
	}
}
$tags_array = get_terms('custom_tax_like_tag', 'orderby=none&hide_empty=0&parent=0'); // получим все термины таксономии без вложенности
foreach ($tags_array as $tag) { // пробежим по каждому
  $tags .= '<label><input type="radio" name="tag" value="'.$tag->term_id.'">'.$tag->name.'</label>'; // суем все в radio баттоны
}
?>
<?php // Выводим форму ?>
<form method="post" enctype="multipart/form-data" id="add_object">
	<label>Кастом категории-родители:
		<select id="parent_cats" name="parent_cats" required>
			<option value="">Не выбрано</option>
			<?php echo $parents; // выводим все родительские термины ?>
		</select>
	</label>

	<label>Кастом категории-дети:
		<select id="child_cats" name="child_cats" required>
			<option value="">Не выбрано</option>
			<?php echo $childs; // выводим все дочерние термины, плагин chained сам покажет только нужные элементы в зависимости от выбранного родительского термина ?>
		</select>
	</label>

	Кастом тэги
  	<?php echo $tags; // выводим термины таксономии без иерархии в radio ?>

	<label>Тайтл(стандартное) <input type="text" name="post_title" required/></label>
	<label>Пост контент(стандартное) <textarea name="post_content" required/></textarea></label>
	<label>Поле типа строка(произвольное) <input type="text" name="string_field"/></label>
	<label>Пост типа текст(произвольное) <textarea name="text_field"/></textarea></label>
	<label>Миниатюра(стандартное): <input type="file" name="img"/></label>
	<label id="first_img" class='imgs'>Дополнительные фото(произвольное): <input type='file' name='imgs[]'/></label>
	<a href="#" id="add_img">Загрузить еще фото</a>
	<input type="submit" name="button" value="Отправить" id="sub"/>
	<div id="output"></div> <?php // сюда будем выводить ответ ?>

2. Перехват отправки формы и подготовка данных:
Суньте это куда удобнее: прямо на страницу или в специальный js файл для кастом скриптов =)

function ajax_go(data, jqForm, options) { //ф-я перед отправкой запроса
  	jQuery('#output').html('Отправляем...'); // в див для ответа напишем "отправляем.."
  	jQuery('#sub').attr("disabled", "disabled"); // кнопку выключим
}
function response_go(out)  { // ф-я обработки ответа от wp, в out будет элемент success(bool), который зависит от ф-и вывода которую мы использовали в обработке(wp_send_json_error() или wp_send_json_success()), и элемент data в котором будет все что мы передали аргументом к ф-и wp_send_json_success() или wp_send_json_error()
	console.log(out); // для дебага
	jQuery('#sub').prop("disabled", false); // кнопку включим
	jQuery('#output').html(out.data); // выведем результат
}
jQuery(document).ready(function(){ // после загрузки страницы
	jQuery("#child_cats").chained("#parent_cats");  // подключаем плагин для связи селект листов с терминами вложенной таксономии
  	add_form = jQuery('#add_object'); // запишем форму в переменную
  	var options = { // опции для отправки формы с помощью jquery form
  		data: { // дополнительные параметры для отправки вместе с данными формы
  			action : 'add_object_ajax', // этот параметр будет указывать wp какой экшн запустить, у нас это wp_ajax_nopriv_add_object_ajax
        	nonce: ajaxdata.nonce // строка для проверки, что форма отправлена откуда надо
    	},
      	dataType:  'json', // ответ ждем в json формате
      	beforeSubmit: ajax_go, // перед отправкой вызовем функцию ajax_go()
      	success: response_go, // после получении ответа вызовем response_go()
      	error: function(request, status, error) { // в случае ошибки
        	console.log(arguments); // напишем все в консоль
      	},
      	url: ajaxdata.url // куда слать форму, переменную с url мы определили вывели в нулевом шаге     
  }; 
  add_form.ajaxForm(options); // подрубаем плагин jquery form с опциями на нашу форму 

  jQuery('#add_img').click(function(e){ // по клику на ссылку "Добавить еще фото"
    e.preventDefault(); // выключим стандартное поведение ссылки
    jQuery(this).before("<label class='imgs'>Дополнительные фото(произвольное) <input type='file' name='imgs[]'/></label>"); // добавим перед ссылкой еще один инпут типа файл с таким же нэймом
  });  
});

3. Обработка данных и добавление поста:
Это тоже в functions.php

add_action( 'wp_ajax_nopriv_add_object_ajax', 'add_object' ); // крепим на событие wp_ajax_nopriv_add_object_ajax, где add_object_ajax это параметр action, который мы добавили в перехвате отправки формы, add_object - ф-я которую надо запустить
add_action('wp_ajax_add_object_ajax', 'add_object'); // если нужно чтобы вся бадяга работала для админов
function add_object() {
	$errors = ''; // сначала ошибок нет

	$nonce = $_POST['nonce']; // берем переданную формой строку проверки
	if (!wp_verify_nonce($nonce, 'add_object')) { // проверяем nonce код, второй параметр это аргумент из wp_create_nonce
		$errors .= 'Данные отправлены с левой страницы '; // пишим ошибку
	}

	// запишем все поля
	$parent_cat = (int)$_POST['parent_cats']; // переданный id термина таксономии с вложенностью (родитель)
	$child_cat = (int)$_POST['child_cats']; // id термина таксономии с вложенностью (его дочка)
	$tag = (int)$_POST['tag']; // id обычной таксономии
	$title = strip_tags($_POST['post_title']); // запишем название поста
	$content = wp_kses_post($_POST['post_content']); // контент
	$string_field = strip_tags($_POST['string_field']); // произвольное поле типа строка
	$text_field = wp_kses_post($_POST['text_field']); // произвольное поле типа текстарея

	// проверим заполненность, если пусто добавим в $errors строку
	if (!$parent_cat) $errors .= 'Не выбрано "Кастом категория-родитель"';
    if (!$child_cat) $errors .= 'Не выбрано "Кастом категория-ребенок xD"';				    
    if (!$tag) $errors .= 'Не выбрано "Кастом тэг"';
    if (!$title) $errors .= 'Не заполнено поле "Тайтл"';
    if (!$content) $errors .= 'Не заполнено поле "Пост контент"';

    // далее проверим все ли нормально с картинками которые нам отправили
    if ($_FILES['img']) { // если была передана миниатюра
   		if ($_FILES['img']['error']) $errors .= "Ошибка загрузки: " . $_FILES['img']['error'].". (".$_FILES['img']['name'].") "; // серверная ошибка загрузки
    	$type = $_FILES['img']['type']; 
		if (($type != "image/jpg") && ($type != "image/jpeg") && ($type != "image/png")) $errors .= "Формат файла может быть только jpg или png. (".$_FILES['img']['name'].")"; // неверный формат
	}

	if ($_FILES['imgs']) { // если были переданны дополнительные картинки, пробежимся по ним в цикле и проверим тоже самое
		foreach ($_FILES['imgs']['name'] as $key => $array) {
			if ($_FILES['imgs']['error'][$key]) $errors .= "Ошибка загрузки: " . $_FILES['imgs']['error'][$key].". (".$key.$_FILES['imgs']['name'][$key].") ";
    		$type = $_FILES['imgs']['type'][$key]; 
			if (($type != "image/jpg") && ($type != "image/jpeg") && ($type != "image/png")) $errors .= "Формат файла может быть только jpg или png. (".$_FILES['imgs']['name'][$key].")"; 
		}
	}  

	if (!$errors) { // если с полями все ок, значит можем добавлять пост
		$fields = array( // подготовим массив с полями поста, ключ это название поля, значение - его значение
			'post_type' => 'my_custom_post_type', // нужно указать какой тип постов добавляем, у нас это my_custom_post_type
	    	'post_title'   => $title, // заголовок поста
	        'post_content' => $content, // контент
	    );
	    $post_id = wp_insert_post($fields); // добавляем пост в базу и получаем его id

	    update_post_meta($post_id, 'string_field', $string_field); // заполняем произвольное поле типа строка
	    update_post_meta($post_id, 'text_field', $text_field); // заполняем произвольное поле типа текстарея

	    wp_set_object_terms($post_id, $parent_cat, 'custom_tax_like_cat', true); // привязываем к пост к таксономиям, третий параметр это слаг таксономии
	    wp_set_object_terms($post_id, $child_cat, 'custom_tax_like_cat', true);
	    wp_set_object_terms($post_id, $tag, 'custom_tax_like_tag', true);

	    if ($_FILES['img']) { // если основное фото было загружено
   			$attach_id_img = media_handle_upload( 'img', $post_id ); // добавляем картинку в медиабиблиотеку и получаем её id
   			update_post_meta($post_id,'_thumbnail_id',$attach_id_img); // привязываем миниатюру к посту
		}

		if ($_FILES['imgs']) { // если дополнительные фото были загружены
			$imgs = array(); // из-за того, что дефолтный массив с загруженными файлами в пхп выглядит не так как нужно, а именно вся инфа о файлах лежит в разных массивах но с одинаковыми ключами, нам нужно создать свой массив с блэкджеком, где у каждого файла будет свой массив со всеми данными
			foreach ($_FILES['imgs']['name'] as $key => $array) { // пробежим по массиву с именами загруженных файлов
				$file = array( // пишем новый массив
					'name' => $_FILES['imgs']['name'][$key],
					'type' => $_FILES['imgs']['type'][$key], 
					'tmp_name' => $_FILES['imgs']['tmp_name'][$key], 
					'error' => $_FILES['imgs']['error'][$key],
					'size' => $_FILES['imgs']['size'][$key]
				);
				$_FILES['imgs'.$key] = $file; // записываем новый массив с данными в глобальный массив с файлами
				$imgs[] = media_handle_upload( 'imgs'.$key, $post_id ); // добавляем текущий файл в медиабиблиотека, а id картинки суем в другой массив
			}
			update_post_meta($post_id,'multifile_field',$imgs); // привязываем все картинки к посту
		}  
	}

	if ($errors) wp_send_json_error($errors); // если были ошибки, выводим ответ в формате json с success = false и умираем
	else wp_send_json_success('Все прошло отлично! Добавлено ID:'.$post_id); // если все ок, выводим ответ в формате json с success = true и умираем
	
	die(); // умрем еще раз на всяк случ
}

После того как форму отправят, по переданному параметру action вордпресс поймет какой экшн запустить, а именно wp_ajax_add_object_ajax и выполнит нашу функцию add_object(), а дальше все просто.

Ахтунг! Если вы создавали тип постов с помощью плагина Pods, убедитесь что тип постов не имеетобязательных дополнительных полей, иначе функция wp_insert_post вернет кусок несчастья, пост добавится не полностью и ответ в нужном формате тоже не придет.

4. Примечания:

  • Я специально усложнил все насколько смог, чтобы были примеры на все случаи жизни. Очевидно, что для добавления простого поста все проще, но по аналогии.
  • Все таксономии и произвольный тип постов были созданы с помощью плагина Pods Framework за 5 минут. Как работать с этим плагином и какие кнопки нажимать читайте здесь. Если обязательные поля нужны, то для добавления используйте api плагина pods.
  • Очень полезно будет прочитать про ajax в wordpress у Камы.

Ну вот и все. Мы запилили супер добавление кастом постов с произвольными полями, картинками и привязкой к таксономиям через ajax. оО

Шарьте статью, плюсуйте, спрашивайте, всем мир, развлекайтесь)

Создание формы-фильтра записей WordPress по произвольным полям и другим параметрам

Создание формы-фильтра записей WordPress по произвольным полям и другим параметрам

Взято из (http://wppost.ru/postroenie-filtra-zapisej-wordpress-po-proizvolnym-polyam-i-ne-tolko/)

В нашей предыдущей статье мы рассмотрели возможность построения get-запроса к базе данных Worpress и рассмотрели варианты использования этой возможности для формирования фильтра записей, страниц и тд. Как вы помните в прошлой статье нам удалось избежать процесса создания скрипта-обработчика данных с формы и мы целиком возложили этот процесс на  сам WordPress, ограничившись только построением правильного запроса через форму фильтра. Но как мы выяснили, этот способ имеет один существенный недостаток — невозможность поиска по произвольным полям этих страниц или записей.

Сегодня мы попробуем пойти другим путем и научимся формировать фильтры с использованием произвольных полей.

Скажу сразу, чтобы хотя мы и будем полагаться на функциональные возможности WordPress по выборке и поиску у нас все же не получиться обойтись без необходимости написания своего скрипта обрабатывающего запрос с формы фильтра для получения нужного результата.

Итак, начнем подготовку к реализации нашего фильтра.

Для начала подготовим шаблон страницы, где и будет происходить вывод результатов выборки.

Для этого в админке нашего сайта создадим новую пустую страницу, назовем ее «Результаты поиска» и назначим ей URL «customsearch»

02.10

Далее связываемся с нашим сервером с помощью FTP-клиента, находим файл page.php, делаем с него копию и переименовываем в page-customsearch.php. Таким образом, мы сообщаем, что все обращения к нашей созданной в админке странице будут обрабатываться именно в этом файле, не затрагивая другие, а обращаться мы к ней будем через наш фильтр записей.

02.102

После этого, мы можем приступать к формированию HTML-кода нашего фильтра. Основные принципы построения фильтра описаны в предыдущей статье, поэтому я приведу пример формы фильтра, описав подробно только моменты связанные с использованием произвольных полей в этой форме:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<form action="/customsearch/" method="get">
//выборка по отдельному слову
<p><label>Поисковый запрос</label><br />
<input type="text" name="word" value=""></p>
//выборка по терминам определенной таксономии, в нашем случае prodcat
<p><label>Укажите товарную категорию:</label><br />
<select name="prodcat">
<option value="">--------</option>
<option value="148">Плагины WordPress</option>
<option value="199">Изображения</option>
</select>
</p>
//Выборка по значениям цены, которые указаны произвольными полями
<p><label>Диапазон цены</label><br />
от <input type="text" name="min-price" size="3" value="">
до <input type="text" name="max-price" size="3" value=""></p>
//Указание сортировки результатов выборки
//Тут мы можем отсортировать и по значению цены, заданного
//произвольным полем
<p><label>Сортировка по</label><br />
<select name="orderby">
<option value="date">дате добавления</option>
<option value="title">заголовку</option>
<option value="meta_value_num">цене</option>
</select>
</p>
//Указание направление результатов сортировки
<p><label>Направление сортировки:</label><br />
<input type="radio" name="order" value="DESC"> по убыванию<br />
<input type="radio" name="order" value="ASC"> по возрастанию </p>
//Указание количества записей на одну страницу
<p><label>Получить:</label><br />
<select name="num">
<option value="-1">Все товары</option>
<option value="2">2 товара</option>
<option value="4">4 товара</option>
<option value="6">6 товаров</option>
</select>
</p>
<p><input type="submit" value="Получить товары"></p>
//так как мы можем производить сортировку и по произвольным полям, то
//в запросе следует указывать ключ этого поля.
//В нашем случае это цена товара "price-products"
<input type="hidden" name="meta_key" value="price-products">
</form>

Обратите внимание на атрибут action тега form, в нем мы указываем адрес именно той страницы, которую создали в админке и для которой мы создали отдельный шаблон на сервере. Метод передачи данных мы можем использовать любой, POST или GET.

Собственно, когда мы имеем на руках код формы мы можем переходить к этапу обработки данных, передаваемых этой формой. Здесь следует отметить, что нам не придется писать какой то большой скрипт, мы лишь будем максимально использовать возможности WordPress по обоработке переданных с формы данных. Поэтому мы ограничимся лишь построением массива данных, который затем передадим в цикл WordPress для вывода результата.

Обратимся к стандартной функции query_posts(), именно в эту функцию мы и должны передать сформированный нами массив. Эта функция распологается перед началом цикла записей и влияет на него, заставляя его выводить именно те записи, которые нам нужны и в том порядке который мы указали, лишь получив сформированный массив.

Как же формировать этот массив? Для этого мы можем обратиться к обширному описанию этой функции в кодексе Worpress. Это описание я дублировать тут не буду, но постараюсь подробно описать логику построения массива данных именно для нашей формы.

Итак, перейдем к построению массива данных для функции query_posts(). Для этого мы должны открыть для редактирования созданный нами ранее файл page-customsearch.php, где и будет происходить обработка и вывод результатов обработки нашего запроса.

Находим в нем начало цикла, которое выглядит примерно так:

1
if (have_posts()) : while (have_posts()) : the_post();

и ставим перед этой строкой функцию query_posts() и заготовку для нашего массива. Должно получиться примерно следующее:

1
2
3
4
5
<?php $args = array
);
query_posts( $args ); ?>        
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>

Теперь основываясь на описание функции query_posts в кодексе,  данные которые форма передает и метод передачи этих данных начинаем наполнение массива. Смотрим на нашу форму и идем по порядку:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$args = array(
//Для начала укажем тип записей по которым осуществляем поиск
//В нашем случае это products
    'post_type' => 'products',
//Передадим поисковый запрос из первого текстового поля
    's' => $_GET['word'],
//Тут передаем ключ произвольного поля по которому осуществляем
//сортировку, если сортировка идет по произвольному полю
    'meta_key' => $_GET['meta_key'],
//Здесь передаем количество записей выводимых на одной странице
    'posts_per_page' => $_GET['num'], // "-1" - получаем все
//Эти данные нужны для правильной работы постраничной навигации
//в результатах поиска
    'paged' => get_query_var( 'paged' ),
//Тут передаем направление сортировки, указанное пользователем
    'order' => $_GET['order'], //DESC,ASC
//Здесь указываем по чему именно производим сортировку
    'orderby' => $_GET['orderby'], //title, ID, author, name, date, meta_value
//В этом параметре передаем идентификатор термина таксономии prodcat, в котором ищем
//записи. Ограничиваем область поиска в пределах одного пользовательского термина
    'tax_query' => array
        array
            'taxonomy' => 'prodcat'
            'field' => 'id'
            'terms' => array($_GET['prodcat']) 
        
    ),
//Здесь передаем минимальную и максимальную цены в диапазоне которых производим поиск.
//т.е. осуществляем поиск в пределах значений определенного произвольного поля.
//В нашем случае 'price-products'
    'meta_query' => array
        array
            'key' => 'price-products'
            'value' => array( $_GET['min-price'], $_GET['max-price'] ),
            'type' => 'numeric',
            'compare' => 'BETWEEN'
        )
    
);

Остановлюсь более подробно на указании значений произвольного поля в этом массиве. В нашем случае, мы указали диапазон значений цены «от и до», поэтому значение параметра compare мы установили, согласно документации к функции, как BETWEEN, что означает, что выборку будем делать в диапазоне значений. Но поиск по произвольным полям может быть очень разнообразным и в зависимости от нужного нам результата будет менять и порядок формирования этих значений в массиве функции query_posts.

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

1
2
3
4
5
6
7
//Ищем по ключу произвольного поля
'meta_key'=>'color'
//или только по значению
'meta_value'=>'green'
//Если ищем и по значению и по ключу, то выглядит так
'meta_key'=>'color',
'meta_value'=>'green'

А для поиска уже нескольким произвольным полям придется использовать параметр meta_query, который мы использовали в нашем примере

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'meta_query' => array(
//здесь мы указали что производим поиск по произвольным полям
//с ключом color, значения которых не равны blue
        array
            'key' => 'color'
            'value' => 'blue'
            'compare' => 'NOT LIKE'
        ),
//тут мы указали диапазон значений произвольного поля price,
//в котором производим поиск
//type - параметр уточняющий тип передаваемых данных
        array
            'key' => 'price'
            'value' => array( 20, 100 ), 
            'type' => 'numeric'
            'compare' => 'BETWEEN'
        
    )

Следует отметить, что параметр compare — определяет сравнение и может быть: =, !=, >, >=, <, <=, LIKE, NOT LIKE, IN, NOT IN, BETWEEN, NOT BETWEEN. По умолчанию =;

Итак, после более подробного экскурса в принципы построения массива при использовании в них произвольных полей, вернемся к нашему примеру формы фильтра.

Разместив код сформированного массива в наш файл page-customsearch.php, мы получаем примерно такой конечный код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
/*Выше распологается какой то код*/
/*********************************/
    $args = array
        'post_type' => 'products',
        's' => $_GET['word'],
        'meta_key' => $_GET['meta_key'],
        'posts_per_page' => $_GET['num'],
        'paged' => get_query_var( 'paged' ),
        'order' => $_GET['order'],
        'orderby' => $_GET['orderby'],
        'tax_query' => array
            array
                'taxonomy' => 'prodcat'
                'field' => 'id'
                'terms' => array($_GET['prodcat']) 
            
        ),
        'meta_query' => array
            array
                'key' => 'price-products'
                'value' => array( (int)$_GET['min-price'], (int)$_GET['max-price'] ),
                'type' => 'numeric',
                'compare' => 'BETWEEN'
            )
        
    );
    query_posts( $args ); ?>
    <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
/*********************************/
/*Ниже распологается какой то код*/

Получилось очень коротко и понятнее, чем если бы вам кто то писал функцию обработчик данных с вашей формы не используя возможности функции query_posts.

И теперь отправив запрос из нашей формы в этот файл, мы получим результат в виде списка записей который подходят под условия выборки указанные в фильтры.

Нам осталось лишь облагородить нашу форму с помощью CSS и разместить ее в любом месте нашего шаблона.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#customsearch{
    width:250px;
    margin:15px auto;
    border:1px solid #ccc;
    border-radius:10px;
    padding:10px;
}
#customsearch label{
    font-weight:bold;
    display:block;
}
#customsearch input[type="text"],
#customsearch input[type="submit"],
#customsearch select{
    padding:5px;