Вопрос или проблема
Я пытаюсь перечислить записи из пользовательского типа записей (CPT) под названием “exposition” и сгруппировать их по произвольной таксономии под названием “date-exposition” (которые предназначены для годов, таких как 2010, 2015, 2017 и т.д.) в следующем формате :
2019
- запись 1
- запись 2
2018
- запись 3
- запись 4
и т.д…
Ближайший код, который я сумел скомпилировать, это (он показывает только одну дату/значение таксономии, а не записи…) :
<?php
// Получить текущую категорию
$get_current_cat = get_term_by('name', single_cat_title('',false), 'category');
$current_cat = $get_current_cat->term_id;
// Перечислить записи по терминам для произвольной таксономии любого типа записей
$post_type="exposition";
$tax = 'date-exposition';
$tax_terms = get_terms( $tax, 'orderby=name&order=ASC');
if ($tax_terms) {
foreach ($tax_terms as $tax_term) {
$args = array(
'post_type' => $post_type,
"$tax" => $tax_term->slug,
'post_status' => 'publish',
'posts_per_page' => -1,
'category__in' => $current_cat // Только записи в текущей категории (category.php)
);
$my_query = null;
$my_query = new WP_Query($args);
if( $my_query->have_posts() ) : ?>
<h2><?php echo $tax_term->name; // Название группы (таксономия) ?></h2>
<?php while ( $my_query->have_posts() ) : $my_query->the_post(); ?>
<?php $term_list = wp_get_post_terms($post->ID, 'category', array("fields" => "ids")); // Получить ID категорий записей?>
<?php if (in_array($current_cat, $term_list) ): // Отобразить только записи, имеющие текущий ID категории ?>
<h3><?php the_title(); ?></h3>
<?php endif; // if in_array ?>
<?php endwhile; // конец цикла ?>
<?php endif; // if have_posts()
wp_reset_query();
} // конец foreach #tax_terms
} // конец if tax_terms
?>
Спасибо за помощь. Пожалуйста, обратите внимание, что я действительно не очень силен в PHP.
Я переписал ваш код, было достаточно много частей, которые казались чрезмерно сложными или использовали устаревшие методы.
В приведенном ниже коде я перебираю ваши термины, и в этом цикле я нахожу записи, относящиеся к этому термину. Возможно, есть более эффективный способ, поскольку это использует несколько запросов, но он должен достичь желаемого результата.
<?php
// получить термины, упорядоченные по имени
// https://developer.wordpress.org/reference/functions/get_terms/
// https://developer.wordpress.org/reference/classes/wp_term_query/__construct/
$taxonomy = 'date-exposition';
$tax_terms = get_terms(
array(
'taxonomy' => $taxonomy,
'hide_empty' => false, // изменить на true, если вы не хотите пустых терминов
'orderby' => 'name',
'order' => 'DESC',
'fields' => 'names', // возвращать только названия терминов
)
);
foreach($tax_terms as $tax_term) { // проход по терминам
echo '<h2>' . $tax_term . '</h2>'; // выводим название термина как h2
$term_posts = get_posts( // находим записи с правильным термином
array(
'no_found_rows' => true, // для производительности
'ignore_sticky_posts' => true, // для производительности
'post_type' => 'exposition',
'posts_per_page' => -1, // возвращаем все результаты
'tax_query' => array( // https://developer.wordpress.org/reference/classes/wp_tax_query/
array(
'taxonomy' => $taxonomy,
'field' => 'name',
'terms' => array( $tax_term )
)
),
'fields' = 'ids', // возвращаем только ID записей
)
);
echo '<ul>'; // открываем маркированный список
foreach($term_posts as $term_post_id) { // перебираем записи
$post_title = get_the_title($term_post_id); // получаем название записи
$post_permalink = get_the_permalink($term_post_id); // получаем ссылку на запись
echo '<li>'; // открываем элемент списка
echo '<a href="' . $post_permalink . '">' . $post_title . '</a>'; // добавляем ссылку на запись с названием записи в качестве текста ссылки
echo '</li>'; // закрываем элемент списка
}
echo '</ul>'; // закрываем маркированный список
}
?>
Ответ или решение
Вопрос, который вы задаете, о необходимости группировки записей постов по пользовательской таксономии в WordPress, представляет интерес для многих разработчиков и администраторов сайтов. Давайте рассмотрим, как можно эффективно реализовать данную задачу с помощью PHP и встроенных возможностей WordPress.
1. Определение задачи
Вы хотите вывести записи из пользовательского типа постов (CPT) «exposition», сгруппировав их по пользовательской таксономии «date-exposition», которая соответствует годам (например, 2010, 2015, 2017 и т.д.). Вывод должен быть устроен в виде заголовков для каждого года с подсписком публикаций, относящихся к этому году.
2. Оптимизация кода
Предоставленный вами код требует несколько улучшений для достижения желаемого результата. Мы можем сократить количество запросов к базе данных и упростить логику.
3. Возможное решение
Вот оптимизированный код, который позволит вам достигнуть поставленной цели:
<?php
// Задаем необходимые параметры
$taxonomy = 'date-exposition';
// Получаем термины для пользовательской таксономии
$tax_terms = get_terms(array(
'taxonomy' => $taxonomy,
'hide_empty' => false, // если поставите true, будут возвращены только термины с записями
'orderby' => 'name',
'order' => 'DESC',
));
foreach ($tax_terms as $tax_term) { // Проходим по каждому термину
echo '<h2>' . esc_html($tax_term->name) . '</h2>'; // Выводим название термина (года) в заголовке h2
// Получаем записи, соответствующие текущему термину
$term_posts = get_posts(array(
'post_type' => 'exposition',
'posts_per_page' => -1, // Получить все записи
'tax_query' => array(
array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $tax_term->slug,
),
),
));
echo '<ul>'; // Открываем список
foreach ($term_posts as $post) { // Проходим по записям
setup_postdata($post); // Настраиваем данные для текущего поста
echo '<li><a href="' . esc_url(get_permalink($post->ID)) . '">' . esc_html(get_the_title($post->ID)) . '</a></li>'; // Выводим заголовок поста как ссылку
}
echo '</ul>'; // Закрываем список
wp_reset_postdata(); // Сбрасываем глобальные данные поста после работы с запросами
}
?>
4. Пояснение ключевых элементов кода
- get_terms: Получает термины для заданной таксономии. Опция
hide_empty
позволяет управлять выводом пустых терминов. - get_posts: Используется для извлечения постов, соответствующих конкретной таксономии, без лишних запросов к базе данных.
- esc_html & esc_url: Важно использовать эти функции для обеспечения безопасности вывода, что предотвращает возможные уязвимости (например, XSS-атаки).
- wp_reset_postdata: Позволяет сбросить глобальные данные поста после выполнения циклов. Это важно для предотвращения конфликтов с другими запросами WordPress.
5. Заключение
Этот подход не только позволяет выводить записи по группам, основанным на вашей пользовательской таксономии, но и делает код более читаемым и производительным. Регулярно анализируйте ваш код на наличие оптимизаций и следуйте лучшим практикам программирования. Если у вас возникнут дополнительные вопросы, не стесняйтесь обращаться за помощью!