Сортировка get_terms с использованием произвольного поля
У меня есть произвольная таксономия "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>";
}
Буду благодарен за любую помощь.

Вместо вывода терминов в первоначальном цикле, я бы использовал его для создания нового массива, где ключом будет 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>";
}
Код не тестировался.

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

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

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

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

Я использовал похожий метод, но хотел сохранить больше значений из таксономии, чем просто имя и значение пользовательского поля, поэтому в итоге сохранил их как 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, чтобы при создании термина таксономии пользователь мог задать числовой порядок, и затем я мог перебирать термины в соответствии с желаемым порядком.
Надеюсь, это кому-то поможет!

Спасибо, 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 итераций
}
?>
Если у кого-то есть лучшие комментарии к этому коду, дайте мне знать, или если есть более эффективные способы что-то реализовать. Но я думаю, это довольно крутое решение.

Спасибо, Фил Хойт, это именно то, что я искал. Однако, к сожалению, у меня не получилось заставить это работать в моей конфигурации. Вот что сработало в моем случае:
<?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 — в обратном порядке (от большего к меньшему)
?>
Удачи

Сортировка терминов по значению '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;
