Группировать и перечислять записи по пользовательской таксономии

Вопрос или проблема

Я пытаюсь перечислить записи из пользовательского типа записей (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>'; // закрываем маркированный список
}
?>

https://codeshare.io/Jbyqvd

Ответ или решение

Вопрос, который вы задаете, о необходимости группировки записей постов по пользовательской таксономии в 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. Заключение

Этот подход не только позволяет выводить записи по группам, основанным на вашей пользовательской таксономии, но и делает код более читаемым и производительным. Регулярно анализируйте ваш код на наличие оптимизаций и следуйте лучшим практикам программирования. Если у вас возникнут дополнительные вопросы, не стесняйтесь обращаться за помощью!

Оцените материал
Добавить комментарий

Капча загружается...