Сортировка get_terms с использованием произвольного поля

12 сент. 2014 г., 19:57:44
Просмотры: 29.8K
Голосов: 7

У меня есть произвольная таксономия "crb_issues" с привязанным к ней произвольным полем "issue_date", которое выводит значение даты для каждого термина в формате "20140601" (год, месяц, день).

Я пытаюсь вывести все термины таксономии с помощью get_terms и отсортировать их по этому произвольному полю. Ниже приведен код, над которым я работаю - он правильно выводит название термина и значение "issue_date", но у меня возникли сложности с сортировкой результатов по этому произвольному полю.

$args = array(
    'meta_key'          => 'issue_date',
    'orderby'           => 'meta_value_num', 
    'order'             => 'DESC',
    'hide_empty'        => true,
    'number'            => '4', // количество выводимых терминов
    'fields'            => 'all', // получить все поля
); 

$terms = get_terms("crb_issues", $args);

 if ( !empty( $terms ) && !is_wp_error( $terms ) ){
    echo "<ul>";
    foreach ( $terms as $term ) {
        echo "<li>" . $term->name . "</li>";
        the_field('issue_date', $term);
    }
    echo "</ul>";
 }

Буду благодарен за любую помощь.

2
Комментарии

Примечание: Я нашел плагинные решения, такие как Advanced Taxonomy Terms Order, которые позволяют перетаскивать термины в нужном порядке, но я бы предпочел, чтобы это решалось через orderby или какой-то автоматический способ сортировки.

Phil Hoyt Phil Hoyt
12 сент. 2014 г. 20:45:14

Вы можете обратиться к следующей теме: http://wordpress.stackexchange.com/questions/117147/order-get-terms-by-custom-field

Или этой ссылке: http://www.wphub.com/sorting-categories-custom-sort-order/

Надеюсь, это вам поможет.

Domain Domain
12 сент. 2014 г. 21:00:22
Все ответы на вопрос 6
1
10

Более короткое решение, просто добавьте это перед foreach:

usort($terms, function($a, $b) {
    return get_field('issue_date', $a) - get_field('issue_date', $b);
});
9 янв. 2016 г. 21:23:52
Комментарии

Лучший вариант, так как не имеет значения, идентичны ли значения для сортировки или нет, и является самым элегантным решением.

Picard Picard
30 нояб. 2021 г. 01:31:11
5

Вместо вывода терминов в первоначальном цикле, я бы использовал его для создания нового массива, где ключом будет issue_date:

$my_new_array = array( );
foreach ( $terms as $term ) {
    $issue_date = get_field( 'issue_date', $term );
    $my_new_array[$issue_date] = $term->name;
}

Затем вы можете пройтись по этому новому массиву в нужном порядке:

ksort( $my_new_array, SORT_NUMERIC );

foreach ( $my_new_array as $issue_date => $term_name ) {
   echo "<li>" . $term_name . " " . $issue_date . "</li>";
}

Код не тестировался.

12 сент. 2014 г. 21:41:49
Комментарии

Мне нравится идея, к сожалению, я недостаточно разбираюсь, чтобы заставить это работать правильно. Этот код действительно выводит все термины и прочее, но не в порядке issue_date.

Phil Hoyt Phil Hoyt
12 сент. 2014 г. 21:57:06

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

vancoder vancoder
12 сент. 2014 г. 22:06:53

Это именно то, что я гуглил, когда увидел твой пост! Ха. У меня получилось заставить это работать, немного изменив под свои нужды, и я сейчас выложу свой код.

Phil Hoyt Phil Hoyt
12 сент. 2014 г. 22:18:10

Хороший вопрос... Странно, что в get_terms() есть orderby meta_value_num... но у меня это не сработало

GDY GDY
23 дек. 2016 г. 10:37:21

Имейте в виду, что если у одного или нескольких терминов одинаковые даты выпуска, они будут перезаписывать друг друга

uruk uruk
27 апр. 2017 г. 15:28:08
2

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

Получаем термины:

$terms = get_terms('your-taxonomy');

Затем создаем новый массив, сохраняя термины по значению моего пользовательского поля, которое в данном случае было числовым:

$newterms = array(); 
foreach($terms as $term) {
    $order = get_field('order', $term); //ЭТО ЗНАЧЕНИЕ МОЕГО ПОЛЬЗОВАТЕЛЬСКОГО ПОЛЯ                
    $newterms[$order] = (object) array(
            'name' => $term->name,
            'slug' => $term->slug,
            'term_id' => $term->term_id
    );
}

Сортируем их численно:

ksort( $newterms, SORT_NUMERIC );

Затем используем цикл foreach для получения значений каждого объекта:

foreach ( $newterms as $newterm ) {     
        echo '<a href="#' . $newterm->slug . '">' . $newterm->name . '</a>';
}

По сути, я переписываю массив, чтобы использовать ключ моего пользовательского порядка, но в этом случае мне нужны были slug, имя и ID термина, поэтому я сохранил их как объект, а не использовал метод, описанный выше.

Моя конечная цель заключалась в том, чтобы настроить Advanced Custom Field, чтобы при создании термина таксономии пользователь мог задать числовой порядок, и затем я мог перебирать термины в соответствии с желаемым порядком.

Надеюсь, это кому-то поможет!

14 окт. 2015 г. 21:22:10
Комментарии

Это должно быть принятым ответом. Хорошая работа.

Christine Cooper Christine Cooper
6 мар. 2016 г. 17:34:40

Я могу работать с этим, но, как прокомментировал uruk решение vancoder, если 2 или более элемента имеют одинаковое значение в поле order, они будут перезаписывать друг друга и отобразится только последний.

David Rhoden David Rhoden
9 июл. 2019 г. 00:12:27
0

Спасибо, Vancoder, за вашу помощь!!! Я весь день рвал на себе волосы, пытаясь разобраться. Забавно, что ваше решение было одним из полудюжины, которые я написал на своей доске, НО я понятия не имел, как создать массив с этим в качестве ключа. Я новичок в этом. Ниже приведен код, который я в итоге использовал, с комментариями для тех, кто тоже пытается это сделать!

<?php
$terms = get_terms("crb_issues");
$issue_archive = array( ); // создает массив для всех терминов внутри таксономии crb_issues, используя пользовательское поле "issue_date" в качестве ключа
foreach ( $terms as $term ) {
    $issue_date = get_field( 'issue_date', $term );
    $issue_archive[$issue_date] = $term->name;
}

krsort( $issue_archive, SORT_NUMERIC ); // сортирует массив issue_archive от большего к меньшему

foreach ( $issue_archive as $issue_date => $term_name ) {
    echo "<li>" . $term_name . " " . $issue_date . "</li>"; // выводит название термина и пользовательское поле issue_date
    if (++$i == 4) break; // Останавливает цикл после 4 итераций
}
?>

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

12 сент. 2014 г. 22:25:59
0

Спасибо, Фил Хойт, это именно то, что я искал. Однако, к сожалению, у меня не получилось заставить это работать в моей конфигурации. Вот что сработало в моем случае:

    <?php
    // Решение для сортировки категорий треков по пользовательскому полю ACF
    // http://support.advancedcustomfields.com/forums/topic/sorting-categories-list-by-custom-field/
    $categories = get_categories('taxonomy=tracks');
    $sorted_cats = array();
    foreach($categories as $cat){
    //$ordr = get_field('track_order', 'tracks_'.$cat>term_id); // не работало, поэтому использовал строку ниже
        $ordr = get_field( 'track_order', $cat );
        $sorted_cats[$ordr] = $cat;
    }
    krsort($sorted_cats);// ksort сортирует по возрастанию, krsort — в обратном порядке (от большего к меньшему)
    ?>

Удачи

9 мая 2015 г. 04:30:13
0

Сортировка терминов по значению 'order' в массиве вместо ключа массива. Если у вас есть 2 элемента с одинаковым ключом, последний перезапишет первый. Это предотвратит перезапись и сделает все элементы видимыми:

$sorted = array();
$args   = array( 'hide_empty' => false );
$terms  = get_terms( 'my-tax', $args );

if( $terms ) : 

    foreach ( $terms as $term ) {

        $sorted[]  = array(
            'order' => get_field( 'order', $term ), // Получаем поле из ACF
            'name'  => $term->name,
        );
    }

    function sortByOrder($a, $b) {
        return $a['order'] - $b['order'];
    }

    usort($sorted, 'sortByOrder');

    foreach( $sorted as $t ) :?>
        <span>
            <?php echo $t['name']; ?>
        </span>
    <?php endforeach;
endif;
12 февр. 2016 г. 05:01:01