Каталог на WordPress + Magic Fields. Поиск по каталогу и фильтры. Часть 2

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

И то и другое, в готовом варианте, вы можете видеть в блоге, который я уже упоминал в первой заметке о Magic Fields. К сожалению, с тех пор я так и не удосужился уделить этому блогу сколько-нибудь достаточное количество времени, поэтому и форма и фильтры там находятся в зачаточном состоянии. Тем не менее, они отлично демонстрируют результат, являющийся логичным завершением использования данного WordPress плагина.

Единственным минусом плагина Magic Fields является невозможность создавать поля с парами ключ – значение. Быть может для вас это и не является минусом, но мне данный подход не слишком нравится. В любом случае, вариантов нет, поэтому мы будем фильтровать публикации в каталоге по строковым значениям дополнительных полей.

Допустим, помимо прочих, у нас есть дополнительное поле «Производитель». Список производителей строго регламентирован и при создании публикации он представляет собой selectbox. В пользовательской части наша публикации может иметь следующий вид (скриншот с упомянутого блога):




Элемент каталога на WordPress

Все характеристики заданы дополнительным полями Magic Fields. Те значения, что подсвечиваются синим цветом являются ссылками, выполняющими роль фильтров.

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

<?php if (is_category(3) || in_category(3) && !is_home() && !is_single()) {
    $x_params = array();

    if (isset($_REQUEST["device_type"]) && $_REQUEST["device_type"] != '') {
        $x_params['x_device_type'] = $_REQUEST["device_type"];
    }
    if (isset($_REQUEST["device_producer"]) && $_REQUEST["device_producer"] != '') {
        $x_params['x_device_producer'] = $_REQUEST["device_producer"];
    }
    if (isset($_REQUEST["device_os"]) && $_REQUEST["device_os"] != '') {
        $x_params['x_device_os'] = $_REQUEST["device_os"];
    }
    
    if (sizeof($x_params)) {
        global $query_string;
        $x_string = null;
    
        foreach ($x_params as $key => $value) {
            $x_string .= '&' . $key . '=' . $value;
        }
    
        query_posts($query_string . $x_string);
    }
} ?>

Код простой и не требует каких-то особых комментариев, кроме отдельных моментов.

Первый условный оператор банально предотвращает обработку данного кода вне требуемой категории. По моим планам, плагин должен был работать лишь для одной категории – устройства. В ней же мы фильтруем позиции, осуществляем поиск по дополнительным полям и прочему. Следовательно, нет смысла пытаться получить значения фильтров в других категориях. Из этих же соображений можно было вынести данный код в шаблон вывода постов, так как для страниц, например, он уже не актуален. Но я влепил его в header.php и так он там и остался.

Далее собираем все полученные значения дополнительных полей в массив $x_params. Если полей будет очень много, то не следует делать так, как сделал я, а именно писать блок условия для каждого поля. Иначе у вас будет много некрасивого и бестолкового кода. Лучше вынести имена полей в массив, а затем обходить его циклом, проверяя, пришло ли от пользователя значение для каждого поля. Но речь не об этом.

Собрали все значения в массив ключ =>значение и циклом конкатенируем их в строку вида &x_field_name=field_value. Обратите внимание, на то, что имена дополнительных полей должны иметь префикс x_. После этого регистрируем наш обновленный запрос функцией query_posts(). Естественно, не забываем выполнить конкатенацию уже существующей строки запроса, которая храниться в переменной $query_string и наших добавленных параметров.

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

Ниже привожу код, который будет выводить форму поиска по дополнительным полям Magic Fields. У меня она лежит в файле шаблона archive.php, но не факт, что у вас также (зависит от шаблона и способов его реализации).

<?php if (in_category(3)) {
    $device_producers = array(
    	'HTC',
    	'Sony Ericsson',
    	'Sumsung',
    	'Motorola',
    	'Wexler'
    );
?>

<form method="post" action="/devices/">
<table>
	<tr>
		<td>Производитель:</td>
		<td>
			<select name="device_producer">
				<option value="">-</option>
				<?php foreach($device_producers as $d_producer) { ?>
				<option<? if (@$_REQUEST["device_producer"] == $d_producer) echo ' selected="selected"';  ?> value="<?=$d_producer?>"><?=$d_producer?></option>
				<? } ?>
			</select>
		</td>
	</tr>
	<tr>
		<td colspan="2"><input type="submit" value="Показать" /></td>
	</tr>
</table>
</form>
<? } ?>

У меня в блоге, на момент написания статьи, она выглядела примерно так:

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

Успехов!

P.S: Пример реализации поиска с помощью класса WP_Query

Комментарии (32)

  1. А могли бы Вы привести реализацию фильтра (поиска) по выборке записей с различными видами, а не только с полем select, но и с checkbox-ами, полями ввода (например для мин. и макс. цены) и чтобы они были взаимодополняющими. Например выбор нескольких типов производителей.

  2. Михаил

    Большое спасибо за материал! Как раз нужен каталог для WordPress

  3. Елена

    Помогите разобраться!)
    Делаю все точно по вашему уроку.. но в раскрывающемся списке выбора производителя нет ни одной позиции.
    Хотя в самих настройках полей я их задавала.
    Заранее, спасибо!)

    • У меня список производителей формируется не на основе тех значений, что вы задаете при создании поля, а на основе массива $device_producers. Это сделано с целью избавиться от дополнительного запроса в БД.

      Мне кажется, вы не там ищете источник проблемы.

  4. Артем

    Подскажите, пожалуйста, что означают параметры полей required (this field is required)
    Can be duplicated (this field is duplicable?)

  5. Виталий

    Здравствуйте Олег. Сделал все как описано в статье (из первой статьи все получилось) но сделать сортировку по каталогу как у вас в первом примере не получается. Вставляю в single.php код и подставляю свои значения но данные из доп. полей даже не подсвечиваются как ссылки. Можете подсказать что я делаю не так?

    • Виталий

      и сразу дополню свой вопрос. Как выводить дополнительные поля в каталоге к каждому посту если у меня в категории выводятся только заголовки. Ну то есть я в категории хочу построить таблицу в которой напротив каждого названия(заголовка поста) будут выводиться доп. поля.

      • Для получения значения полей необходимо использовать функцию get() внутри цикла while (have_posts()). И неважно, в категории это или в одиночной записи.

        Это же относится к вашему первому вопросу. В заметке данный момент опускается. Но ссылки для фильтров формируются именно с помощью get().

  6. Олег

    Здравствуйте.
    Не могли б вы объяснить что означает это: action=»/devices/»
    Получается форму обрабатывает страница devices. Какую мне страницу задать. У меня на все логично выдает Нет такой страницы

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

  7. Александр

    Подскажите пожалуйста как делать сортировку или поиск, если данные в таблице храняться в серилизованном виде?

    • Есть модуль для MySQL https://github.com/junamai2000/mysql_unserialize_php

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

      Без него сортировка по сериализованной строке невозможна. А вот поиск, в принципе, можно осуществлять с помощью LIKE %%, например.

  8. Ярослав

    Здраво.
    Отфильтрованные посты выводятся с пагинацией, первая страница показывает отфильтрованные, но стоит перейти на другую страницу пагинации, выводятся все посты без фильтрации.
    Как полечить?
    Спасибо

    • Реализуйте свою функцию пагинации или можно использовать какой-нибудь плагин, который позволит передавать дополнительные параметры.

      Я, как правило, делал вывод результатов фильтрации через ajax, поэтому базовая пагинация WP меня не беспокоила.

  9. Назарий

    Вроде и понятно, но не получается … буду тренироватся)

  10. Подскажите пожалуйста, как можно интегрировать в стандартный поиск wp magic-fields, чтобы искало хотябы по заголовкам и по возможности по текстовым полям

    • По заголовкам он должен искать и так. Как раз неделю назад проверял это на живом проекте. Если поиск по заголовкам не происходит, значит что-то не так с таксономиями.

      А вот относительно полей подсказать не могу, так как подобных задач не решал. Попробуйте погуглить. В топе выдачи можно найти вот эту тему на офф. форуме, где поднимают ваш вопрос http://wordpress.org/support/topic/include-custom-field-values-in-search

  11. Сергей

    Простите, тема старая, но вроде никто подобного вопроса не касался: если доп. поля не одного уровня, как у вас (производители), а хотя бы двух (оружие — танки — танки гусеничные и танки колесные, предположим такое) Как в таком случае организовать ввод данных, чтобы танки колесные были и в категории «танки колесные» и в то же время в категории «танки»? (Делаю для людей неискушенных, поэтому важно сделать просто и доступно, самому-то можно и на коленке забацать )

  12. Множественный выбор полей не поможет, т.к. кроме танков там есть и самолеты и автоматы, есть риск выбрать по ошибке не ту категорию. Идеальным было бы вложение категорий, но такого в этом плагине я не нашел пока.

    • А зачем вам дополнительные поля? Ведь есть обычные категории WP или можно создать свою таксономию.

      • Сергей

        Категории есть, они для постов, а в каталоге логичнее (на мой взгляд, конечно) страницы использовать. Своя таксономия, насколько я понял, тоже создается или на основе постов или на основе страниц. Если у нас страницы, то есть ли возможность сделать вложение таксономий, или придется переходить на посты с категориями?
        Есть еще один путь сделать каталог — через плагин Page list, там есть все возможности для реализации искомого, но ввод новых позиций в каталог не очевиден. А в Magic Fields как раз ввод достаточно прост, но с вложенностью затык…

        • Страницы могут быть вложены друг в друга. Я делал нечто подобное и для схожей тематики — стрелковое вооружение.
          Вот прототип http://pro-arms.ru/

          • Сергей

            Там страницы и Magic Fields?

            • Это кастомные post_type на основе page. Ну по сути все верно — страницы. Выстроены в дерево, чтобы можно было формировать хлебные крошки и ограничивать область поиска родительской страницей при различных фильтрах. Созданы и управляются с помощью MF.

  13. Елена

    Но, как оказалось, работает крайне быстро. В худшем случае вся страница каталога со всеми выбранными фильтрами для всех категорий генерировалась за 600мс, если не ошибаюсь.

Добавить комментарий для Ярослав Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *