yeope
  • 0
Новичок

Возможно ли с помощью wp_query упорядочивать по таксономии?

  • 0

Мой вопрос прост, я использую WP_Query фильтрацию некоторых сообщений пользовательского типа по таксономии с использованием tax_query .

Теперь моя проблема в том, что я хотел бы orderby, taxonomy но из документации и поиска в Интернете я не могу найти решение.

In позволяет упорядочивать orderby по WP_Query множеству полей даже настраиваемые метаполя, но, похоже, он не поддерживает таксономию.

Любые указатели в правильном направлении?

Спасибо вам всем.

Share
  1. Нет, упорядочить по таксономии невозможно, потому что с определенной точки зрения это не имеет особого смысла.

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

    То, что вы должны использовать в такой ситуации, — это post meta. Вы можете упорядочить по метаданным поста, и он уникален для каждого поста.

    Изменить: Тем не менее, вы можете упорядочить по таксономии, создав собственный SQL-запрос с использованием фильтра, вы просто не можете сделать это из немодифицированного WP_Query: http://scribu.net/wordpress/sortable-taxonomy-columns.html

    Однако, если вам приходится прибегать к подобным вещам, то ваша структура проектирования данных изначально неверна. «Термины» в таксономии не являются фактическими «данными». Сами по себе термины не имеют внутреннего значения, они просто ярлыки для конкретной группы, которую они описывают. Если вы рассматриваете их как значимые данные, то у вас есть основной недостаток дизайна.

    Таксономии группируют вещи, назначая им термины. В этой группировке и заключается весь смысл таксономии, термины — это просто красивые лица в группировке. Если у вас есть значимые метаданные для назначения сообщению, то вместо этого вы должны использовать для него метаданные сообщения. И это вы можете упорядочить, потому что метаданные сообщений используют как ключи, так и значения для хранения информации. С таксономией вы действительно храните только ключи, а их значения представляют собой сообщения, сгруппированные вместе по этому термину.

    В долгосрочной перспективе все становится проще, если вы используете правильный подход. Хотя я не говорю, что вы не можете сделать что-то странное с таксономией, вы просто усложняете себе жизнь в долгосрочной перспективе, используя ее неправильно.

    • 0
    • Привет Отто, спасибо за ответ. Я понимаю вашу точку зрения, и, возможно, я иду неправильным путем с этим. В моем примере на сайте телешоу у меня есть таксономия для серии 1, серии 2, серии 3 и т. д. Таким образом, я могу сгруппировать все различные телешоу по номеру серии. Тогда у меня то же самое для эпизодов, Эпизод 01, Эпизод 02 и т. Д. Я хотел бы, чтобы при отображении списка всех эпизодов они были упорядочены по эпизодам и сериям. Я проанализирую, а затем опубликую мета и настраиваемые поля. Спасибо, Отто.

      • 0
    • @yeope ваша таксономия должна быть серией, а ваши термины должны быть серией 1, серией 2 и т. д. Что касается эпизодов, я предполагаю, что сериал содержит несколько эпизодов, поэтому он может использовать одну и ту же таксономию, «серию», и если они иерархичны, тогда эпизод 1, эпизод 2 и т. д. будет иметь родительский термин «серия x». Затем вы можете запросить всю серию по порядку, чтобы эпизоды располагались там, где должны.

      • 0
    • На самом деле использование таксономии для эпизодов не имеет большого смысла, потому что группировка бесполезна. Подумайте об этом, если у вас есть термин «эпизод 1», то вы группируете эпизод 1 с каждым другим эпизодом 1 из любого другого телешоу. Номера эпизодов и серий имеют больше смысла как post_meta, потому что они специфичны для этого конкретного шоу и бесполезны как группа. Название телешоу было бы полезно в качестве термина в таксономии телешоу, потому что тогда вы группируете шоу как единое целое.

      • 0
    • Извините @Otto, я только сейчас заметил ваш ответ… Я полностью согласен с вашими смысловыми точками и логикой. Но в моем контексте «сортировка» была бы главным образом вопросом эргономики. Визуальное группирование прогнозов по «фестивалю» может, что немаловажно, помочь пользователю получить визуальное резюме, основанное на наиболее важном для него факторе, это с первого взгляда. Таким образом, не уверен, что смогу добиться этого как-то иначе, кроме как «сортировкой», что, я согласен, не является подходящим термином…

      • 0
    • Извините, но вы не правы. Заказ по таксономии также не имеет никакого смысла в вашем случае. Что вы хотите показать? Сначала все завтраки, затем все ужины, потом все обеды? Вы должны выбрать то, что вы хотите, и порядок, в котором вы хотите это сделать, но таксономия — это просто ярлык для группировки. Это не значимые «данные», по которым вы должны упорядочивать. Если это так, то это не должен быть термин в таксономии, вместо этого вы должны сделать его пост-мета.

      • 0
    • Да ладно, конечно, будут некоторые случаи, когда вы захотите упорядочить сообщения по термину таксономии. Другим примером является тип публикации Movie с таксономией Rating. В списке фильмов очень легко представить людей, желающих упорядочить список фильмов по рейтингу, чтобы все фильмы с рейтингом G, затем с рейтингом PG и т. д. отображались вверху. (В этом примере и в примере с едой они могут быть упорядочены по term_id, а не по имени.) Существует большая серая область случаев, когда вам, вероятно, лучше всего подходит таксономия, а не мета, но, вероятно, также полезно, чтобы эта таксономия была упорядочена. -способный.

      • 0
    • Рейтинги PG и G и тому подобное — хороший выбор таксономии, за исключением того, что это данные о конкретных фильмах. Таким образом, они являются мета. Это данные, а не категории. Просто наличие ограниченного числа вариантов не делает таксономию. Если требуется сортировка, то либо сделайте ее мета, либо принудительно выполните сортировку по таксономии с помощью специального кода таксономии. Кстати, NC17 идет после PG. Итак, вам в любом случае нужен код для выполнения этого заказа.

      • 0
    • Я знаю, что опаздываю на вечеринку с этим комментарием, но просто наткнулся на это. Упорядочивание по таксономии может иметь смысл в некоторых ситуациях. У нас есть списки вакансий в одном проекте в качестве типа сообщения, а затем штат и город, в котором находится работа, являются таксономиями. Мы хотим, чтобы их было легко группировать (показывать все вакансии в штате или показывать все вакансии в городе), поэтому таксономия была лучшим решением. В то же время есть общий поиск работы, где мы хотим отсортировать их сначала по названию, затем по штату, затем по городу.

      • 0
    • Другой вариант использования: у клиента есть куча статей, каждая из которых имеет категорию. Клиент хочет, чтобы была страница со списком всех статей, которые можно отсортировать по алфавиту, по дате или по категории. Категории также могут быть отфильтрованы, но перечисление всех статей по категориям в алфавитном порядке не так уж и безумно, и вы видите, что это всплывает довольно часто.

      • 0
    • Спасибо, Дрю, я попробую запустить этот SQL, нужно немного отредактировать, но это может сработать. Моя единственная проблема сейчас в том, что я могу идти не в том направлении, как указал Отто. Спасибо, Дрю. РЕДАКТИРОВАТЬ. Нет необходимости редактировать, я вижу, где это нуждается в настройке 🙂 Спасибо.

      • 0
    • Если вы схватили его в течение последних двух минут, он не сработает, давай, схвати его сейчас, я это исправил. Он был установлен для двух определенных таксономий, я улучшил код для работы со всеми зарегистрированными таксономиями.

      • 0
    • еще раз, спасибо. На всякий случай я попробовал ваше решение, и оно работает. Также, если кто-то еще хочет использовать его, вам нужно изменить add_filter('posts_clauses', 'orderby_tax_clauses', 10, 2 ); его на add_filter('posts_clauses', 'todo_tax_clauses', 10, 2 ); Спасибо 🙂

      • 0
    • Да, теперь это исправлено в блоке кода, я взял это из проекта, над которым работаю, и забыл изменить имя функции, хотя я изменил его в хуке.

      • 0
    • Знаете ли вы, можно ли упорядочить таксономии по идентификатору вместо имени? Я пытаюсь получить тот же результат, упорядочивая группы таксономии по идентификатору.

      • 0
    • Любая идея о том, как заказать по имени вместо term_taxonomy_id? изменение term_taxonomy_id в orderby_statement вызывает ошибки

      • 0
    • Это правильный ответ для всех, кто заинтересован!

      • 0
    • @tehlivi этот метод не работает для заказа по имени, потому что имя находится в wp_terms таблице. Похоже, что WordPress кэширует термины таксономии, поэтому, даже если ваш налоговый запрос выполняет поиск по слагу или имени, которые также находятся в wp_terms таблице, WordPress прогоняет их через свой кешированный список и обменивает их на идентификаторы, хранящиеся в term_relationships.term_taxonomy_id, поэтому ему не нужно запрашивать wp_terms таблицу как часть основного запроса. Это означает, что ни имя, ни слаг не включаются в результирующий SQL-запрос. Вы должны добавить соединения.

      • 0
    • @EthanC, чувак, спасибо за твой подробный ответ, и, надеюсь, если кто-нибудь найдет это в будущем, он найдет твой ответ полезным. Но лично мне, конечно, трудно вспомнить что-либо из 2016 года. Я думаю, что закончилось тем, что я пропустил массив через функцию сортировки после завершения запроса. Я уверен, что любой разработчик, взявший на себя этот проект после моего ухода из компании, ненавидит меня. Ха.

      • 0
    • @tehlivi Да, в итоге я полностью проигнорировал основной запрос, если некоторым сообщениям было присвоено более одного термина. Вместо этого решил запускать get_terms() и запускать get_posts для каждого термина. Добавил ~15 запросов на загрузку страницы, но дизайнер получает тот результат, который хотел.

      • 0
    • @yeope Почему это принятый ответ !? слава богу пролистал

      • 0
    • не мог заставить это работать. Можете ли вы указать сайт с некоторым объяснением этого? ничего здесь, что поддерживает ваш код

      • 0
    • Хорошая работа, смешно, что такое количество кода потребовалось для сортировки чего-то по таксономии. Огромная проблема с WP.

      • 0
    • Большое спасибо, это очень полезно. Здорово, что есть возможность сделать заказ визуально. Знаете ли вы, почему там есть часть «ИЛИ таксономия IS NULL»? Вроде бы что-то не нужное.

      • 0
    • Он правильно отображает первый термин, но после этих сообщений следующий термин логически не следует порядку меню, как указано в SCP Order. Мне интересно, потому что я пытаюсь сделать это с продуктами, а в WooCommerce уже есть порядок атрибутов… может быть, они конфликтуют. В БД идентификаторы в столбце term_order верны…

      • 0
    • Кажется, помогает изменение строки GROUP_CONCAT orderby на следующую: $clauses[‘orderby’] = «{$wpdb->terms}.term_order ASC»;

      • 0
    • Я тоже об этом думаю, хотя это дублирует данные.

      • 0
  2. Принятый ответ на этот вопрос неприемлем. Нелогично полагать, что упорядочение по налогам «не имеет смысла». Ответ, который он дал, не имеет смысла.

    Подумайте о типе поста меню. Тогда у вас есть пользовательский налог «FoodCategories». Налог на категории продуктов питания включает термины «завтрак», «обед» и «ужин». Если вы отправляете запрос с использованием параметра tax_query, теперь у вас есть набор результатов со всеми терминами, однако они упорядочены по дате публикации.

    Чтобы получить правильный порядок из них относительно их терминов, а затем правильно отобразить их во внешнем интерфейсе, разделив сообщения на их различные категории, вы должны пройтись по набору результатов, а затем запросить каждое отдельное сообщение в пределах набор результатов, чтобы найти его термины и сравнить с текущим термином, отфильтровать в массив и продолжить. Затем вам нужно снова просмотреть новый массив для отображения. Это не продуктивно.

    Было бы неплохо, если бы у WP была опция orderby «tax__in», как она делает «post__in», но поскольку ее нет, вам либо придется выполнить описанный выше нелепый процесс; настроить запрос самостоятельно с помощью фильтров ‘posts_orderby’ и ‘posts_join’, чтобы настроить метод orderby и добавить терм в результирующий набор соответственно; или вам нужно сделать новый запрос для каждого термина, который вы фильтруете, в разделах html относительно этих терминов.

    Наиболее эффективным было бы изменение строки запроса с помощью фильтров. Проще всего было бы сделать три отдельных запроса. API WP должен обрабатывать упорядочение по налогам или любым ограничительным параметрам запроса. Если вы ограничиваете запрос на основе определенных условий, существует высокая вероятность того, что многим придется упорядочивать те же самые условия.

    • 0
  3. Да, но это довольно сложно…

    Добавьте в functions.php вашей темы:

    function orderby_tax_clauses( $clauses, $wp_query ) {
        global $wpdb;
        $taxonomies = get_taxonomies();
        foreach ($taxonomies as $taxonomy) {
            if ( isset( $wp_query->query['orderby'] ) && $taxonomy == $wp_query->query['orderby'] ) {
                $clauses['join'] .=<<<SQL
    LEFT OUTER JOIN {$wpdb->term_relationships} ON {$wpdb->posts}.ID={$wpdb->term_relationships}.object_id
    LEFT OUTER JOIN {$wpdb->term_taxonomy} USING (term_taxonomy_id)
    LEFT OUTER JOIN {$wpdb->terms} USING (term_id)
    SQL;
                $clauses['where'] .= " AND (taxonomy = '{$taxonomy}' OR taxonomy IS NULL)";
                $clauses['groupby'] = "object_id";
                $clauses['orderby'] = "GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC) ";
                $clauses['orderby'] .= ( 'ASC' == strtoupper( $wp_query->get('order') ) ) ? 'ASC' : 'DESC';
            }
        }
        return $clauses;
    }
    
        add_filter('posts_clauses', 'orderby_tax_clauses', 10, 2 );
    

    Это Франкенштейн из некоторых найденных вещей и некоторых вещей, которые я сделал сам. Объяснить это довольно сложно, но суть в том, что при выполнении этого задания вы можете указать ?orderby=(taxonomy query var)&order=ASC (или DESC), и она сразу же уйдет!

    • 0
  4. Я опаздываю в эту игру, но есть более простой, более WordPress-способ сделать это.

    Создайте свой налоговый запрос, как обычно.

    $tax_query = array();
    $tax_query['relation']="OR";
    $tax_query[] = array(
        'taxonomy' => 'product_cat',
        'field'    => 'slug',
        'terms'    => $cat_terms,
    );
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    

    Настройте аргументы для query_posts или WP_Query.

    $args = array(
        'post_type'=>'post',
        'posts_per_page'=>12,
        'paged'=>$paged,
        'tax_query' => $tax_query,
    );
    

    Прежде чем сделать вызов query_posts/WP_Query, подключитесь к фильтру orderby и переопределите его.

    add_filter('posts_orderby', 'edit_posts_orderby');
    function edit_posts_orderby($orderby_statement) {
        $orderby_statement = " term_taxonomy_id ASC ";
        return $orderby_statement;
    }
    query_posts($args);
    remove_filter('posts_orderby', 'edit_posts_orderby');
    

    не забудь потом вынуть фильтр…

    это работает, потому что tax_query создает для вас соединения и т. д., вам просто нужно заказать одно из полей соединения.

    • 0
  5. Я не уверен, почему все решения здесь в значительной степени переполняют его. Хорошо, это было полвека назад, но сейчас я просто запускаю следующий код, и он работает:

       <?php // Default
        $wheels_args = array(
            'post_type' => 'wheels',
            'posts_per_page' => '96',
            'orderby' => 'taxonomy, name', // Just enter 2 parameters here, seprated by comma
            'order'=>'ASC'
        );
        $loop = new WP_Query($wheels_args);
        ?>
    

    Это отсортирует таксономии вашего CPT сначала по таксономии в алфавитном порядке, а внутри этих групп таксономии также по алфавитному порядку.

    • 0
  6. Что ж, я хотел бы поделиться своим опытом сортировки пользовательских типов сообщений по категориям/таксономии.

    ПАУТИНА

    1. Веб-сайт туристического агентства, работающий на WordPress.
    2. Основной контент пользовательского типа сообщений под названием «ruta».
    3. Таксономия с этой структурой Тип путешествия > континент > страна

    ДЕЛО

    На страницах списка архивных категорий клиент хотел, чтобы сообщения были отсортированы по

    1. Континент, упорядоченный по количеству маршрутов на каждом из них.
    2. Страна в алфавитном порядке.

    ШАГИ

    Во- первых, я перехватываю запрос из немодифицированного запроса страницы архива, который выглядит следующим образом:

    SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
    FROM wp_posts 
    INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) 
    WHERE 1=1 
    AND ( wp_term_relationships.term_taxonomy_id IN (5,6,7,8,9,10,11,12,13,15,16,17,18,19,20,21,22,23,25,26,28,29,31,32,33,35,38,95,101,102,193) )
    AND wp_posts.post_type IN ('ruta', 'nav_menu_item') 
    AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 45 
    AND wp_posts.post_status = 'private') 
    GROUP BY wp_posts.ID 
    ORDER BY wp_posts.post_date DESC LIMIT 0, 20
    

    Во- вторых, я отредактировал код sql в Sequel Pro для базы данных, чтобы он соответствовал моим потребностям. Я получаю это (да, возможно, это можно улучшить: мои знания о MySQL не являются выдающимися):

    SELECT SQL_CALC_FOUND_ROWS wp_posts.ID, tt1.parent AS pare,
        (
        SELECT COUNT(*) 
        FROM  wp_posts
        INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
        INNER JOIN wp_term_taxonomy AS tt1 ON ( tt1.term_taxonomy_id =      wp_term_relationships.term_taxonomy_id )
        INNER JOIN wp_term_taxonomy AS tt2 ON ( tt2.term_taxonomy_id =  tt1.term_taxonomy_id )
        WHERE 1=1  
        AND tt1.parent = pare
        ) AS Total
    FROM  wp_posts
    INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
    INNER JOIN wp_term_taxonomy AS tt1 ON ( tt1.term_taxonomy_id =      wp_term_relationships.term_taxonomy_id )
    INNER JOIN wp_terms ON ( tt1.term_id = wp_terms.term_id )
    WHERE 1=1  
    AND ( wp_term_relationships.term_taxonomy_id IN (5,6,7,8,9,10,11,12,13,15,16,17,18,19,20,21,22,23,25,26,28,29,31,32,33,35,38,95,101,102,193) ) 
    AND wp_posts.post_type IN ('ruta', 'nav_menu_item') 
    AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 45 
    AND wp_posts.post_status = 'private') 
    GROUP BY wp_posts.ID 
    ORDER BY
    total DESC,
    wp_terms.name  
    

    В- третьих, я подцепил запрос к файлу functions.php с тремя фильтрами: posts_fields, posts_join и posts_orderby.

    Код в functions.php:

    function xc_query_fields( $fields ) {
    
       $fields = "wp_posts.ID, wp_posts.post_title, wp_terms.name, tt1.parent AS pare,
        (
        SELECT COUNT(*) 
        FROM  wp_posts
        INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
        INNER JOIN wp_term_taxonomy AS tt1 ON ( tt1.term_taxonomy_id = wp_term_relationships.term_taxonomy_id )
        INNER JOIN wp_term_taxonomy AS tt2 ON ( tt2.term_taxonomy_id = tt1.term_taxonomy_id )
        WHERE 1=1  
        AND tt1.parent = pare
        )
        AS Total";
         return $fields;
    }
    
    
    function xc_query_joins( $join ) {
    $join .= "INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
       INNER JOIN wp_term_taxonomy AS tt1 ON ( tt1.term_taxonomy_id = wp_term_relationships.term_taxonomy_id )
       INNER JOIN wp_terms ON ( tt1.term_id = wp_terms.term_id )";
     return $join;
    }
    
    
    function xc_query_orderby( $join ) {
        $join = "total DESC, wp_terms.name ";
        return $join;
     }
    

    Наконец, я активировал фильтры из хука pre_get_post в соответствии с некоторыми условиями.

    function filtra_queries( $query )
    {
    
      if (  is_archive()  && $query->is_main_query() && !is_admin()  ) {
    
    $rutes = array('viajes-privados', 'asia', 'africa', 'oceania', 'america', 'oriente-proximo');
    
    if  ( in_array( $query->get('category_name'), $rutes ) ) 
      {
      add_filter( 'posts_fields', 'xc_query_fields' );
      add_filter( 'posts_join', 'xc_query_joins' );
      add_filter( 'posts_orderby', 'xc_query_orderby' );
    }// end if in_array
    
      }// end if is_archive
    
    }
     add_filter('pre_get_posts', 'filtra_queries');
    

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

    • 0
  7. У меня была очень похожая проблема, с которой я столкнулся: я хочу заказать пользовательский архив типа поста (журнальные статьи) по пользовательской таксономии (проблемы). Я никогда не выполняю прямые SQL-запросы на своем сайте, и обычно, если вам нравятся эти другие ответы, вам нужно переосмыслить свой подход.

    ПРОБЛЕМЫ:

    1) WordPress не позволяет разумно упорядочивать таксономии.

    2) WordPress просто не позволяет orderby использовать таксономии в пост-типе WP_Query (как указано Отто).

    РЕШЕНИЯ:

    1) На данный момент сортировку таксономий лучше всего выполнять с помощью плагина Custom Taxonomy Order NE. Это позволяет вам упорядочивать таксономию через WYSIWYG wp-admin, что я бы не сделал, но я не нашел ничего лучше.

    Когда вы настроите плагин, вы получите что-то похожее на то, что я сделал здесь. Обратите внимание на опцию Auto-sort Queries of this Taxonomy — установите для нее значение Custom Order as Defined Above ; это дает вам заказ, который вам нужен. Снимок экрана:

    Отображение пользовательского порядка таксономии NE

    2) Имея отсортированную таксономию, теперь вы можете создавать серию вызовов WP_Query, которые проходят через каждый термин, эффективно создавая архив, упорядоченный по таксономии. Используйте get_terms() для создания массива всех налоговых терминов, затем выполните foreach над каждым термином. Это создает элемент WP_Query для каждого термина, который будет возвращать все сообщения для данного термина, эффективно создавая архив, упорядоченный по термину таксономии. Код, чтобы это произошло:

      // Get your terms and put them into an array
      $issue_terms = get_terms([
        'taxonomy' => 'issues',
        'hide_empty' => false,
      ]);
    
      // Run foreach over each term to setup query and display for posts
      foreach ($issue_terms as $issue_term) {
        $the_query = new WP_Query( array(
          'post_type' => 'post',
          'tax_query' => array(
            array(
              'taxonomy' => 'issues',
              'field' => 'slug',
              'terms' => array( $issue_term->slug ),
              'operator' => 'IN'
            )
          )
        ) );
    
        // Run loop over each query
        while($the_query->have_posts()) :
          $the_query->the_post();
    
          // YOUR TEMPLATE OUTPUT FOR EACH POST
    
        endwhile;
      }
    

    Связанное чтение на этом сайте: Отображение всех сообщений в пользовательском типе сообщений, сгруппированных по пользовательской таксономии.

    • 0
  8. Вот решение, которое я использовал для этой конкретной проблемы. Это решение предназначено для крайних случаев, когда невозможно использовать pre_get_posts фильтр и существует разбиение на страницы в запросе (например, WooCommerce):

    global $wpdb;
    
    $taxonomies = array('my-tax-1', 'my-tax-2', 'my-tax-3');
    
    $orderby = "'".implode("', '", array_keys($taxonomies))."'";
    $id_sql = $GLOBALS['wp_query']->request;
    
    $id_sql = preg_replace('/LIMIT\s+\d+\s?,?\s\d*/', '', $id_sql);
    $id_sql = str_replace('SQL_CALC_FOUND_ROWS', '', $id_sql);
    
    $term_sql = "SELECT
      tt.taxonomy AS `taxonomy`,
      t.name AS `term_name`,
      t.slug AS `term_slug`,
      count(*) AS `term_count`
    FROM ({$id_sql}) p 
    JOIN wp_term_relationships tr
      ON p.ID = tr.object_id
    JOIN wp_term_taxonomy tt
      ON tr.term_taxonomy_id = tt.term_taxonomy_id
    JOIN wp_terms t
      ON tt.term_id = t.term_id
    WHERE tt.taxonomy IN ({$orderby})
    GROUP BY t.slug
    ORDER BY
      FIELD(tt.taxonomy, {$orderby})"; // Add further specific ordering here
    
    $results = $wpdb->get_results($term_sql, ARRAY_A);
    

    Я использовал это для создания навигационного меню, упорядоченного по таксономии, термину и количеству сообщений за термин.

    Если вам просто нужны сообщения, измените запрос на SELECT p.* иGROUP BY p.ID

    • 0
  9. Мне нравится сортировать термины вручную, поэтому для этого я использую плагин. и я поклонник pre_get_posts фильтра, поэтому я взял правильный рабочий пример Дрю Гурли и заставил его работать с ним. так что это какой-то особый случай, но я все равно публикую это, на случай, если это кому-то поможет. следующий код входит в functions.php или пользовательский плагин.

    сначала давайте начнем с фильтра. мы упорядочиваем пользовательский тип сообщения music по пользовательской таксономииstyle

    function so14306_pre_get_posts($query)
    {
        if (is_admin()) :
            return;
        endif;
    
        if ($query->is_main_query()) :
            if (is_post_type_archive('music')) :
                $query->set('orderby', 'style');
    
            endif;
        endif;
    }
    
    add_action('pre_get_posts', 'so14306_pre_get_posts');
    

    затем мы вызываем фильтр post_clauses:

    function so14306_posts_clauses($clauses, $wp_query)
    {
        global $wpdb;
    
        if (isset($wp_query->query_vars['orderby']) && $wp_query->query_vars['orderby'] === 'style') {
            $orderby = $wp_query->query_vars['orderby'];
            $clauses['join'] .= <<<SQL
    LEFT OUTER JOIN {$wpdb->term_relationships} ON {$wpdb->posts}.ID={$wpdb->term_relationships}.object_id
    LEFT OUTER JOIN {$wpdb->term_taxonomy} USING (term_taxonomy_id)
    LEFT OUTER JOIN {$wpdb->terms} USING (term_id)
    SQL;
            $clauses['where'] .= " AND (taxonomy = '{$orderby}' OR taxonomy IS NULL)";
            $clauses['groupby'] = "object_id";
            $clauses['orderby'] = "GROUP_CONCAT({$wpdb->terms}.term_order ORDER BY {$wpdb->terms}.term_order ASC) ASC";
            $clauses['orderby'] .= ", {$wpdb->posts}.post_name ASC";
        }
    
        return $clauses;
    }
    
    add_filter('posts_clauses', 'so14306_posts_clauses', 10, 2);
    

    теперь все, что вам нужно сделать, это отсортировать ваши таксономии с помощью следующего плагина: Simple Custom Post Order. Этот плагин является обязательным для этого решения, так как он добавляет столбец term_order в базу данных!

    и эта строка здесь: $clauses['orderby'].= ", {$wpdb->posts}.post_name ASC" упорядочивает сообщения по заголовку, поэтому полная сортировка приведенного выше решения такова: термин таксономии => заголовок сообщения.

    • 0
  10. Довольно простой способ сделать это — добавить функцию, которая говорит:

    1. Когда ваш пост будет опубликован…
    2. Получите идентификатор вашей категории/слаг/и т.д….
    3. Сохраните его как пользовательское мета-значение для вашего сообщения.

    А затем в своем цикле упорядочите свои сообщения по этому мета-значению.

    Так:

    // 1
    add_action( 'publish_post', 'save_and_add_meta' );
    
    function save_and_add_meta($post_id){
    
            //Temporarily remove the action to avoid an infinite loop
            remove_action( 'publish_post', 'save_and_add_meta' );
    
            // 2            
            $category_slug = get_the_terms($post_id, 'your_taxonomys_name')[0]->slug;
    
            //3
            add_post_meta($post_id, 'cat_slug', $category_slug);
    
            //Add the action back in.
            add_action( 'publish_post', 'save_and_add_meta' );
    }
    

    Затем в своем запросе WP добавьте в свои $args:

    'meta_key' => 'cat_slug',
    'orderby' => 'meta_value',
    'order' => 'DESC',
    

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

    • 0
  11. Это похоже на запрос перед запросом, но не будет беспокоить, если мы не запрашиваем слишком много сообщений… Идея состоит в том, чтобы изменить основной запрос, чтобы нам даже не нужно было переходить к шаблонам и генерировать новые запросы и петли…

    function grouped_by_taxonomy_main_query( $query ) {
    
        if ( $query->is_home() && $query->is_main_query() ) { // Run only on the homepage
    
            $post_ids = array();
    
            $terms = get_terms('my_custom_taxonomy');
    
            foreach ( $terms as $term ) {
                $post_ids = array_merge( $post_ids, get_posts( array( 
                    'posts_per_page' => 4, // as you wish...
                    'post_type' => 'my_custom_post_type', // If needed... Default is posts
                    'fields' => 'ids', // we only want the ids to use later in 'post__in'
                    'tax_query' => array( array( 'taxonomy' => $term->taxonomy, 'field' => 'term_id', 'terms' => $term->term_id, )))) // getting posts in the current term
                );
            }
    
            $query->query_vars['post_type'] = 'my_custom_post_type'; // Again, if needed... Default is posts
            $query->query_vars['posts_per_page'] = 16; // If needed...
            $query->query_vars['post__in'] = $post_ids; // Filtering with the post ids we've obtained above
            $query->query_vars['orderby'] = 'post__in'; // Here we keep the order we generated in the terms loop
            $query->query_vars['ignore_sticky_posts'] = 1; // If you dont want your sticky posts to change the order
    
        }
    }
    
    // Hook my above function to the pre_get_posts action
    add_action( 'pre_get_posts', 'grouped_by_taxonomy_main_query' );
    
    • 0

Оставить ответ

You must login to add an answer.