Вопрос или проблема
У меня есть CPT “Инвентаризация”, и я пытаюсь отобразить выпадающий список всех производителей. У меня есть форма и функция pre_get_posts, так что когда пользователь выбирает производителя, страница обновляется и показывает только инвентарь с этим производителем.
ПРОБЛЕМА: После выбора производителя и обновления страницы только этот производитель отображается как вариант! Независимо от того, что я пробую (я не буду перечислять все здесь, потому что пробовал около 10 разных циклов) для создания вариантов выбора, я не могу сделать так, чтобы всегда отображались ВСЕ производители.
Я прочитал несколько десятков статей (буквально) и не могу найти решение, которое работает.
Вот что у меня сейчас:
FUNCTIONS.PHP
function my_pre_get_posts( $query ) {
// не изменять запросы в админке
if( is_admin() ) {
return $query;
}
// изменять только запросы для типа поста 'inventory'
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'inventory' ) {
// разрешить URL изменять запрос
if( isset($_GET['item_oem']) ) {
$query->set('meta_key', 'item_oem');
$query->set('meta_value', $_GET['item_oem']);
$query->set( 'meta_compare', '=' );
}
}
// вернуть
return $query;
}
add_action('pre_get_posts', 'my_pre_get_posts');
ЦИКЛ:
<?php // использую get прямо сейчас, чтобы увидеть строку запроса и подтвердить функциональность ?>
<form method="get" action="" onchange="submit();">
<?php
$posts = get_posts( array(
'post_type' => 'inventory',
'posts_per_page' => -1,
'orderby' => 'date',
'order' => 'DESC',
));
if ( $posts ): ?>
<select name="item_oem" id="select-oem">
<?php foreach( $posts as $post ): ?>
<option value="<?php the_field('item_oem'); ?>"> <?php the_field('item_oem'); ?> </option>
<?php endforeach; ?>
</select>
<?php endif; ?>
<?php wp_reset_postdata(); ?>
</form>
Так что это ДАЕТ мне полный список производителей. Но, как только вы выберете один и перезагрузите страницу, чтобы показать только инвентарь с этим производителем, выбранный производитель становится единственным вариантом в выборе.
Как мне переопределить это и всегда показывать ВСЕ мета-значения для ключа мета ‘item_oem’??
Большое спасибо!
Вот решение, которое я придумал, и оно работает должным образом.
<form method="get" action="" onchange="submit();">
<div class="input-group">
<?php
global $wpdb;
$meta_key = 'item_oem';
$data = $wpdb->get_results($wpdb->prepare( "SELECT DISTINCT meta_value FROM $wpdb->postmeta WHERE meta_key = %s", $meta_key) , ARRAY_N ); ?>
<select class="custom-select" id="oems" aria-label="oems" name="item_oem" >
<option selected>Поиск по OEM</option>
<?php foreach( $data as $value ): ?>
<option value="<?php echo $value[0]; ?>"><?php echo $value[0]; ?> </option>
<?php endforeach; ?>
</select>
<div class="input-group-append">
<a href="/inventory" class="btn btn-secondary" type="button">Сбросить фильтр</a>
</div>
</div>
</form>
Ответ или решение
Заполнение выпадающего списка с мета-значениями всех записей пользовательского типа записи
Введение
Ваша задача заключается в создании выпадающего списка, который будет отображать всех производителей (Mfrs) из пользовательского типа записи (Custom Post Type) "Инвентарь" в WordPress. Проблема в том, что после выбора одного из производителей и обновления страницы, выпадающий список показывает только выбранного производителя, вместо всех доступных опций. В этой статье мы рассмотрим, как правильно реализовать данную функциональность, используя запросы к базе данных WordPress.
Проблема
Ваша текущая реализация использует функцию pre_get_posts
для фильтрации записей по установленному значению мета-ключа item_oem
. Однако, когда пользователь выбирает производителя и страница обновляется, выпадающий список запрашивает записи, отфильтрованные по этому значению, тем самым отображая только один вариант в списке.
Решение
Для решения данной проблемы можно использовать прямые SQL-запросы к базе данных, чтобы получить все уникальные значения мета-ключа item_oem
— это позволит избежать проблемы с необходимостью фильтрации элементов выпадающего списка.
Вот шаги, которые нужно выполнить:
-
Создание формы с выпадающим списком для выбора Mfr:
Используйте глобальный$wpdb
для получения всех уникальных значенийitem_oem
и корректного отображения их в выпадающем списке. -
Использование запроса к базе данных:
Для извлечения уникальных значений мета-ключаitem_oem
, выполните SQL-запрос через$wpdb
.
Пример реализации
Ознакомьтесь с обновленным кодом для вашей формы:
<form method="get" action="" onchange="submit();">
<div class="input-group">
<?php
global $wpdb;
$meta_key = 'item_oem';
$data = $wpdb->get_results($wpdb->prepare(
"SELECT DISTINCT meta_value FROM $wpdb->postmeta WHERE meta_key = %s",
$meta_key
), ARRAY_N);
?>
<select class="custom-select" id="oems" aria-label="Mfrs" name="item_oem">
<option selected>Поиск по OEM</option>
<?php foreach ($data as $value): ?>
<option value="<?php echo esc_attr($value[0]); ?>"><?php echo esc_html($value[0]); ?></option>
<?php endforeach; ?>
</select>
<div class="input-group-append">
<a href="/inventory" class="btn btn-secondary" type="button">Сбросить фильтр</a>
</div>
</div>
</form>
Объяснение кода
- Глобальный доступ к $wpdb: Используем переменную
$wpdb
, чтобы получить доступ к таблицам базы данных. - SQL-запрос: Запрос
SELECT DISTINCT
извлекает все уникальные значения мета-ключаitem_oem
из таблицыpostmeta
. - Заполнение выпадающего списка: Каждый элемент выпадающего списка создается динамически с помощью цикла
foreach
, обеспечивая отображение всех производителей. - Экранирование данных: Использование функций
esc_attr()
иesc_html()
гарантирует безопасность и корректное отображение данных.
Заключение
Данное решение позволит вам создать выпадающий список с производителями, который будет всегда показывать все доступные значения, независимо от выбранного пользователя. Это улучшит пользовательский опыт и облегчит навигацию по вашему сайту. Не забывайте тестировать изменения в стеке WordPress, чтобы убедиться, что все функции работают корректно и без ошибок.