Вопрос или проблема
Я использую плагин ACF.
Я создал поле выбора custom_select
в ACF, которое включается в каждое вложение.
ACF записывает эти значения в таблицу postmeta.
Теперь я хочу отфильтровать свои вложения в библиотеке медиа по этому полю custom_select
.
Я нашел много статей о включении таксономий, но ни одной по postmeta.
Мне пришлось реализовать следующее:
- Изменить интерфейс администратора, чтобы включить мои пользовательские фильтры
add_action('wp_enqueue_media', function () {
wp_enqueue_script('media-library-taxonomy-filter', get_stylesheet_directory_uri() . '/assets/js/custom-media-filter.js', array('media-editor', 'media-views'));
});
- В custom-media-filter.js я добавляю HTML для пользовательского выбора, и каждый раз, когда мой пользовательский выбор изменяется, добавляю параметры запроса в URL и перенаправляю с этим параметром и значением
jQuery(document).ready(function () {
jQuery('.filter-items').append('<select class="form-select" aria-label="Пользовательский фильтр document_category" id="page-document_category"><option>-Выбрать-</option><option value="document">Документ</option><option value="template">Шаблон</option></select>');
jQuery('#page-document_category').change(function (e) {
insertParam('document_category', this.value)
});
// вставить и перенаправить с новым значением
function insertParam(key, value) {
key = encodeURIComponent(key);
value = encodeURIComponent(value);
// удалить все остальные параметры
var kvp = [];
kvp.push(key + '=' + value);
document.location.search = params;
}
});
- Добавить действие в мой functions.php, связанное с
pre_get_posts
add_action('pre_get_posts', 'my_custom_filter');
и создать мою пользовательскую функцию my_custom_filter
, которая изменяет мета-запрос только тогда, когда мои пользовательские фильтры отправляются в URL
if (!function_exists('my_custom_filter')) {
function my_custom_filter($wp_query_obj)
{
$url_query = explode('&', $_SERVER['QUERY_STRING']);
$params = array();
foreach ($url_query as $param) {
if (isset($param) && $param[0] !== '') {
// предотвращает уведомление об explode(), если $param не содержит '='
if (strpos($param, '=') === false) $param += '=';
list($name, $value) = explode('=', $param, 2);
$params[urldecode($name)][] = urldecode($value);
urldecode_deep($params);
}
}
$found = false;
if (isset($params['document_category'])) {
$meta_key = 'document_category';
$meta_value = $params['document_category'][0];
$found = true;
}
// здесь я могу добавить больше фильтров
// else if ($params['document_type']) {
// $meta_key = 'document_type';
// $meta_value = $params['document_type'][0];
// $found = true;
// }
if ($found) {
$meta_query = array(
array(
'key' => $meta_key,
'value' => $meta_value,
'compare' => '=',
),
);
$wp_query_obj->set('meta_query', $meta_query);
$wp_query_obj->set('orderby', 'meta_value_num');
$wp_query_obj->set('order', 'ASC');
}
return;
}
}
.
Ответ или решение
Фильтрация медиатеки по пользовательским полям постов (postmeta) с использованием ACF
Если вы используете плагин ACF (Advanced Custom Fields) и хотите реализовать возможность фильтрации вложений в медиатеке WordPress по пользовательскому полю custom_select
, вам предстоит выполнить несколько шагов, чтобы существенно улучшить функциональность вашей медиатеки. Этот процесс включает в себя изменение интерфейса администратора, добавление JavaScript для управления фильтрами и настройку PHP-кода для модификации запроса. Посмотрим на все шаги подробно.
1. Изменение интерфейса администратора с помощью wp_enqueue_media
Первый шаг — подключить пользовательский JavaScript, который будет добавлять HTML-код для вашего фильтра. Это можно сделать с помощью хука wp_enqueue_media
. В файле functions.php
вашей темы добавьте следующий код:
add_action('wp_enqueue_media', function () {
wp_enqueue_script('media-library-taxonomy-filter', get_stylesheet_directory_uri() . '/assets/js/custom-media-filter.js', array('media-editor', 'media-views'));
});
Этот код подключает ваш JavaScript-файл custom-media-filter.js
, в котором будет реализована логика фильтрации элементов.
2. Реализация логики фильтрации на стороне клиента
В файле custom-media-filter.js
реализуйте логику для отображения выпадающего списка и управления его изменениями. Вот пример кода:
jQuery(document).ready(function () {
jQuery('.filter-items').append('<select class="form-select" aria-label="Custom filter document_category" id="page-document_category"><option>-Choose-</option><option value="document">Document</option><option value="template">Template</option></select>');
jQuery('#page-document_category').change(function (e) {
insertParam('document_category', this.value);
});
function insertParam(key, value) {
key = encodeURIComponent(key);
value = encodeURIComponent(value);
var params = key + '=' + value;
document.location.search = params;
}
});
Этот код добавляет выпадающий список в интерфейс медиатеки и перенаправляет пользователя на страницу с обновленными параметрами URL при выборе элемента.
3. Изменение запроса с помощью pre_get_posts
Последний шаг — это изменение WP-запроса с помощью хука pre_get_posts
. Добавьте следующий код в ваш файл functions.php
:
add_action('pre_get_posts', 'my_custom_filter');
if (!function_exists('my_custom_filter')) {
function my_custom_filter($wp_query_obj) {
$url_query = explode('&', $_SERVER['QUERY_STRING']);
$params = array();
foreach ($url_query as $param) {
if (isset($param) && $param[0] !== '') {
if (strpos($param, '=') === false) $param .= '=';
list($name, $value) = explode('=', $param, 2);
$params[urldecode($name)][] = urldecode($value);
}
}
$found = false;
if (isset($params['document_category'])) {
$meta_key = 'document_category';
$meta_value = $params['document_category'][0];
$found = true;
}
if ($found) {
$meta_query = array(
array(
'key' => $meta_key,
'value' => $meta_value,
'compare' => '=',
),
);
$wp_query_obj->set('meta_query', $meta_query);
$wp_query_obj->set('orderby', 'meta_value_num');
$wp_query_obj->set('order', 'ASC');
}
return;
}
}
Этот код проверяет наличие параметров URL и, если они присутствуют, изменяет запрос, добавляя соответствующий фильтр по мета-данным.
Заключение
С помощью приведенных выше шагов вы сможете успешно фильтровать ваши вложения в медиатеке WordPress по пользовательскому полю, определенному с помощью ACF. Реализация этого функционала не только улучшает пользовательский интерфейс, но и позволяет эффективно управлять ресурсами вашего сайта.
Не забывайте тестировать изменения на различных этапах, чтобы убедиться, что ваша фильтрация работает корректно. Таким образом, вы сможете экспериментировать с различными значениями и расширять функциональность при необходимости.