Сортировка терминов по term_order

25 мар. 2013 г., 02:28:40
Просмотры: 35.1K
Голосов: 5

Контекст

  • Тип записи: Resources
  • Таксономия: Media Type, Термин: Audio
  • Таксономия: Series

Следующий код отображает уникальный список пользовательской таксономии "Series"

Я хочу отсортировать список по term_order, но это не работает. Есть предложения?

Сайт. В настоящее время сортировка идет по ID

    <?php
                // Массив для данных записей
                $post_data = array();

                $my_query = new WP_Query( array( 
                        'post_type' => 'resource',
                        'posts_per_page' => -1,
                        'media_type' => 'audio'

                    ) 
                );

                if ( $my_query->have_posts() ) {
                    while ( $my_query->have_posts() ) {
                        $my_query->the_post();
                        $post_data[] = get_the_ID();
                    }
                }

                // Начать с любого ID, который вы хотите получить из Media Type
                $audio = 16;

                // Получить все ID записей для этого термина
                $post_ids = get_objects_in_term( $audio, 'media_type', array('post_status' => 'publish') );

                // Затем получить термины series для этих ID записей
                $terms = wp_get_object_terms( $post_data, 'series', array('fields' => 'ids', 'orderby' => 'menu_order' ) );
                $result = array_values( array_unique($terms) );

                ?>


            <?php
        $a = $result;

        foreach ($a as $v) {
        $term = get_term( $v, 'series' );
        $name = $term->name;
        $slug = $term->slug;
        echo '<div class="resource-item"><a href="'.get_term_link($slug, 'series').'" title="'.$name.'"><div class="play"></div><li>'.$name.'</li></a></div>';      
        } 

        ?>
0
Все ответы на вопрос 6
2

Так как это один из топовых результатов в Google, и ни один из вышеперечисленных вариантов мне не подошел, этот способ действительно возвращает термины в порядке, соответствующем их отображению в админке...

get_terms([
  'taxonomy'   => 'whatever_you_want',
  'meta_key'   => 'order',
  'orderby'    => 'meta_value_num'
]);

Если кому-то пригодится: WordPress сохраняет значение в таблице termmeta с ключом order, которое соответствует позиции отображения в меню админки. Очевидно, его нужно адаптировать, если вы хотите одновременно делать запросы по другим метаполям.

22 февр. 2019 г. 15:52:41
Комментарии

Лучший ответ здесь!

Warface Warface
23 февр. 2021 г. 16:52:55

у меня это вообще не дает результатов

Chris Pink Chris Pink
10 июл. 2024 г. 19:09:44
4

Вместо menu_order попробуйте использовать term_order.

Согласно документации в Codex, функция wp_get_object_terms поддерживает следующие параметры:

  • name (название)
  • count (количество)
  • slug (ярлык)
  • term_group (группа терминов)
  • term_order (порядок терминов)
  • term_id (ID термина)
26 мар. 2013 г. 02:09:06
Комментарии

Кажется, это не сработало.

izharbuen izharbuen
26 мар. 2013 г. 07:17:55

@izharbuen Пожалуйста, отметьте этот ответ как верный, нажав на галочку рядом с ним. Спасибо :-)

Pieter Goosen Pieter Goosen
19 дек. 2014 г. 09:00:49

@PieterGoosen izharbuen сказал, что это не работает, поэтому будет неправильно отмечать это как правильный ответ. Я могу подтвердить, что установка orderby в term_order не работает. Ломаю голову, пытаясь понять, почему.

Greg Perham Greg Perham
3 июл. 2018 г. 21:40:45

Проблема в том, что wp_term_query не принимает term_order в качестве одного из параметров orderby, и это сделано преднамеренно. Это просто не будет работать по задумке. Почему? WP иногда делает вещи плохо, из-за чего мне хочется разрабатывать для другой платформы.

Greg Perham Greg Perham
3 июл. 2018 г. 22:09:34
0

term_order не предназначен для упорядочивания терминов внутри таксономии. Он используется для упорядочивания терминов внутри объекта (записи).

https://developer.wordpress.org/reference/classes/wp_term_query/__construct/ гласит:

Если $object_ids не пуст, 'term_order' обрабатывается так же, как 'term_id'.

Для тех, кто пытается упорядочить термины для объекта по term_id, необходимо передать object_ids в запрос.

Для всех остальных, кто задаётся этим вопросом и хочет упорядочить список терминов, не используйте term_id. Вместо этого добавьте мета-значение термина и сортируйте по нему.

get_terms([
  'taxonomy'   => 'my_taxonomy',
  'meta_key'   => 'order',
  'orderby'    => 'meta_value_num'
]);
7 янв. 2022 г. 19:55:39
0

wp_term_query не принимает term_order в качестве одного из параметров сортировки. Поэтому вам нужно принудительно добавить эту опцию в переменную запроса терминов, добавив следующий код в файл functions.php.

function wpcf_filter_terms_order( $orderby, $query_vars, $taxonomies ) {
    return $query_vars['orderby'] == 'term_order' ? 'term_order' : $orderby;
}

add_filter( 'get_terms_orderby', 'wpcf_filter_terms_order', 10, 3 );

После добавления этого кода, если вы выполните что-то вроде следующего, вы получите термины, отсортированные по term_order.

$terms = get_terms('category', array(
                    'orderby'  => 'term_order',
                    'order'    => 'ASC'
                ));

Второй подход: если вы хотите получать термины, отсортированные по term_order глобально и во всех частях WordPress, просто добавьте следующий код в functions.php.

function uc_get_terms_orderby($orderby, $args){
        return 't.term_order';
}
add_filter('get_terms_orderby', 'uc_get_terms_orderby', 10, 2);
28 мая 2019 г. 01:53:28
0

Много лет спустя,

Вы можете добавить этот код в свой functions.php:

function wpcf_filter_terms_order( $orderby, $query_vars, $taxonomies ) {
    return $query_vars['orderby'] == 'term_order' ? 'term_order' : $orderby;
}

add_filter( 'get_terms_orderby', 'wpcf_filter_terms_order', 10, 3 );

Этот код заставляет WordPress использовать аргумент orderby => term_order в запросе терминов.

30 авг. 2018 г. 13:17:57
0

Это идея
Но я реализовал её с мыслью о сортировке списка на фронтенде
Необходимо изменить таблицу "{prefix}term_taxonomy", создав поле "term_order". Смотрите функцию O_term_update_db():

В вашем function.php

<?php
function O_term_update_db(){
    global $wpdb;
    global $term_db_version;
    $term_db_version = "1";

    $charset_collate = $wpdb->get_charset_collate();

    if(get_site_option( 'O_term_db_version' ) < $term_db_version):

        require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );

        $wpdb->query( "ALTER TABLE $wpdb->prefix .'term_taxonomy' ADD `term_order` INT (11) NOT NULL DEFAULT 0;" );

        update_site_option( 'O_term_db_version', $term_db_version);
    endif;
}
add_action('init','O_term_update_db');
?>

Эта функция обращается к базе данных:
В вашем functions.php

<?php
function O_taxonomy_filter_by_order($taxonomy){
    global $wpdb;
    $terms = $wpdb->get_results(" 
        SELECT t.*, tt.*
        FROM ".$wpdb->prefix."term_taxonomy AS tt
        JOIN ".$wpdb->prefix."terms AS t
        ON t.term_id = tt.term_id
        WHERE tt.taxonomy = '".$taxonomy."'
        ORDER BY tt.term_order ASC
    ",ARRAY_A);
    return $terms;
}
?>

Эта функция используется для обновления таблицы через Ajax:
В вашем function.php

<?php
if(!function_exists('O_updating_data_term_reorder')){ 
    function O_updating_data_term_reorder() {

        check_ajax_referer('o-nonce', 'security');

        global $wpdb;
        $terms_ID = $_POST['each_term'];

        $new_order = 0;

        foreach($terms_ID as $key => $ID):

            $term_ID = $ID['term'];

            $new_order++;

            $result = $wpdb->update($wpdb->prefix.'term_taxonomy', array('term_order' => $new_order), array('term_id' => $term_ID));

            if(is_wp_error($result)) {
                echo json_encode(array('save'=>false, 'message'=> 'ОШИБКА: '.$result->get_error_message()));
                exit();
            }

        endforeach;

        echo json_encode(array('save'=>true, 'count'=>$new_order));

        die();
    }
    add_action( 'wp_ajax_o_update_term_reorder', 'O_updating_data_term_reorder' );
}
?>

draggable-ajax.js:

(function($) {
    "use strict";

     //jQuery Sortable необходим http://api.jqueryui.com/sortable/
     //Вызовите "wp_enqueue_script('jquery-ui-sortable');" в вашем wp_enqueue_scripts
     $('.js-draggable-items > .draggable-column').sortable({
        connectWith: '.draggable-column',
        items: '.draggable-item',
        dropOnEmpty: true,
        opacity: .75,
        handle: '.draggable-handler',
        placeholder: 'draggable-placeholder',
        tolerance: 'pointer',
        start: function(e, ui){
            ui.placeholder.css({
                'height': ui.item.outerHeight(),
                'margin-bottom': ui.item.css('margin-bottom')
            });
        }
    });

    $(document).on( "click","#btn-reorder-terms", function() {
        var each_term_list = [];
        $('.draggable-item').each(function(){
            each_term_list.push({
                term: $(this).attr('data-draggable-id'),
            });
        });
        var data = {
            'action' : 'o_update_term_reorder',
            'each_term' : each_term_list,
            'security' : actions_vars.nonce
        };
        $.ajax({
            type: 'POST',
            dataType: 'json',
            cache: false,
            url: actions_vars.ajaxurl,
            data: data,
            success: function(data) {
                if(data.save === true){
                    //сообщение об успехе
                    alert('Готово');
                }else{
                    //сообщение об ошибке
                    alert('Что-то пошло не так');
                }
            },
            error: function(errorThrown) {
               console.log(data);
            }
        });
    });

})(jQuery);

На фронтенде попробуйте так:

<?php
$terms = O_taxonomy_filter_by_order('ваша_таксономия');
?>
<button type="button" class="btn btn-primary" id="btn-reorder-terms">Сохранить</button>

<div class="col-md-12 js-draggable-items">
    <div class="row draggable-column">
    <?php
    foreach($terms as $key => $term):
        $ID = $term['term_id'];
        $name = $term['name'];
        $order = $term['term_order'];
        $description = $term['description'];
        $link = get_category_link($ID);
        ?>
        <div class="draggable-item" data-draggable-id="<?php echo $ID;?>" data-term-order="<?php echo $order;?>">
            <div class="col-md-2 draggable-handler"><i class="si si-cursor-move"></i></div>
            <div class="col-md-10"><?php echo $name;?></div>
        </div>
        <?php
    endforeach;
    ?>
    <div>
<div>
5 янв. 2020 г. 18:56:35