Avec wp_query, est-il possible de commander par taxonomie?

49

Ma question est simple. J'utilise WP_Query pour récupérer des messages de type personnalisé filtrés par une taxonomie à l'aide de tax_query.

Maintenant, mon problème est que je voudrais commander par taxonomie, mais de la documentation et de la recherche sur le Web, je ne trouve pas de solution.

Avec orderby dans WP_Query, vous pouvez classer par champs, même des méta-champs personnalisés, mais cela ne semble pas prendre en charge la taxonomie.

Des pointeurs dans la bonne direction?

Merci à tous.

yeope
la source

Réponses:

12

Non, il n'est pas possible de classer par taxonomie, car d'un certain point de vue, cela n'a pas vraiment de sens.

Les taxonomies sont des moyens de regrouper des éléments. Donc, l’intérêt d’avoir une taxonomie sur les postes serait vraiment d’avoir des termes dans cette taxonomie partagés entre les postes. Si une taxonomie comportait des termes qui n'étaient utilisés que sur un seul poste, cela rendrait la taxonomie inutile. Et si les termes étaient partagés comme ils devraient l'être, alors commander par celui-ci ne produirait rien de particulièrement utile.

Ce que vous devriez utiliser dans une telle situation est le post méta. Vous pouvez commander par la poste méta, et c'est unique à chaque poste.

Edit: Cela dit, vous pouvez commander par taxonomie en faisant une requête SQL personnalisée à l'aide d'un filtre. Vous ne pouvez pas le faire depuis un WP_Query non modifié: http://scribu.net/wordpress/sortable-taxonomy-columns.html

Cependant, si vous devez recourir à ce type de processus, la structure de conception de vos données est erronée. Les "termes" dans la taxonomie ne sont pas des "données" réelles. Les termes eux-mêmes n'ont aucune signification inhérente, ils sont simplement des étiquettes pour le groupe particulier qu'ils décrivent. Si vous les traitez comme des données significatives, vous avez un défaut de conception sous-jacent.

Les taxonomies regroupent les choses en leur attribuant des termes. Ce groupement est l’essentiel des taxonomies, les termes sont simplement de jolis visages sur le groupement. Si vous devez affecter des métadonnées significatives à une publication, vous devriez plutôt utiliser la méta de publication correspondante. Et que vous pouvez commander par, car post meta utilise à la fois des clés et des valeurs pour stocker des informations. Avec une taxonomie, vous ne stockez réellement que des clés, leurs valeurs étant les posts regroupés par ce terme.

Les choses sont plus faciles à long terme si vous utilisez la bonne approche. Bien que je ne dis pas que vous ne pouvez pas faire quelque chose d'étrange avec la taxonomie, vous ne faites que rendre les choses plus difficiles pour vous-même à long terme en les utilisant mal.

Otto
la source
Bonjour Otto, merci pour la réponse. Je vois ce que vous voulez dire et je me trompe peut-être. Dans mon exemple, un site d'émissions de télévision, j'ai la taxonomie des séries 1, 2, 3, etc. Pour pouvoir regrouper toutes les émissions de télévision par numéro de série. Ensuite, j'ai la même chose pour les épisodes, Episode 01, Episode 02, etc. Ce que j'aimerais, c’est de montrer une liste de tous les épisodes à classer par épisode et par série. Je vais analyser ensuite les champs méta et personnalisés. Merci Otto.
yeope
@yeope votre taxonomie devrait être une série et vos termes devraient être une série, une série 2, etc. Avec les épisodes, je suppose qu'une série contient plusieurs épisodes de sorte qu'elle puisse utiliser la même taxonomie, "série" et si elles sont hiérarchiques, l'épisode 1, l'épisode 2, etc. aurait le terme parent "série x". Ensuite, vous pouvez interroger toute une série dans l’ordre, les épisodes s’alignant comme il se doit.
Chris_O
@Chris_O Je vois, vous pourriez être sur l'argent là-bas! Le seul problème que je peux voir est le fait de devoir répéter les termes "Episode 1", "Episode 2" pour chaque série. De plus, ne pas pouvoir regrouper tous les épisodes 1 ne dépend pas de la série, mais je pense qu'il y a probablement un moyen de la contourner. Merci Chris_O
yeope
2
Utiliser une taxonomie pour les épisodes n'a pas beaucoup de sens, en fait, car le regroupement ne vaut rien. Pensez-y. Si vous utilisez le terme "épisode 1", vous regroupez l'épisode 1 avec tous les autres épisodes 1 de toutes les émissions de télévision. Les numéros d'épisodes et de séries ont plus de sens en post_meta, car ils sont spécifiques à cette émission et ne sont pas utiles en tant que groupe. Le nom de l'émission de télévision serait utile comme terme dans une taxonomie d'émissions de télévision, car vous regroupez alors l'émission dans son ensemble.
Otto
1
Otto a ensuite publié un article de blog intéressant: quand utiliser une taxonomie personnalisée ?
Jan Fabry
47

La réponse acceptée pour cette question est inacceptable. Il est illogique de supposer qu'une commande par taxe "n'a pas de sens". La réponse qu'il a donnée n'a pas de sens.

Pensez à avoir un type de message de menu. Ensuite, vous avez une taxe personnalisée de "FoodCategories". La taxe FoodCategories comprend les termes "Petit déjeuner", "Déjeuner" et "Dîner". Si vous soumettez une requête en utilisant le paramètre tax_query, vous avez maintenant un ensemble de résultats avec tous les termes, mais ils sont classés par date de publication.

Afin d’en obtenir le bon ordre, par rapport à leurs termes, puis d’être affichés au début du système en séparant les publications dans leurs différentes catégories, vous devez parcourir le jeu de résultats, puis interroger chaque publication dans la liste. jeu de résultats pour trouver ses termes et les comparer au terme actuel, filtrer dans un tableau et continuer tout au long. Ensuite, vous devez à nouveau parcourir le nouveau tableau pour l'affichage. Ce n'est pas productif.

Ce serait bien si WP avait l'option "tax__in" orderby comme "post__in", mais comme ce n'est pas le cas, vous devez également suivre le processus ridicule ci-dessus; personnalisez vous-même la requête à l'aide des filtres 'posts_orderby' et 'posts_join' afin d'ajuster la méthode orderby et d'ajouter le terme au jeu de résultats, respectivement; ou vous devez créer une nouvelle requête pour chaque terme que vous filtrez dans les sections html par rapport à ces termes.

Le plus efficace serait de changer la chaîne de requête au moyen de filtres. Le plus simple serait de faire trois requêtes distinctes. L'API WP devrait gérer les commandes par taxe ou tout paramètre de requête restrictif. Si vous limitez une requête en fonction de certaines conditions, il est fort probable que beaucoup auront besoin de passer commande selon ces mêmes conditions.

Aryan Duntley
la source
2
Désolé, mais vous avez tort. Commander par taxonomie n'a aucun sens dans votre cas non plus. Que veux-tu montrer? Tous les petits déjeuners d'abord, puis tous les dîners, puis tous les déjeuners? Vous devez sélectionner ce que vous voulez et l'ordre dans lequel vous le souhaitez, mais la taxonomie n'est qu'un libellé de regroupement. Ce ne sont pas des "données" significatives que vous devriez commander. Si c'est le cas, alors ce ne devrait pas être un terme dans une taxonomie, vous devriez plutôt en faire un post-méta.
Otto
15
Allez, bien sûr, il y aura des cas dans lesquels vous voudrez commander des messages par terme de taxonomie. Un autre exemple est un type d'article Movie avec une taxonomie d'évaluation. Dans une liste de films, il est très facile d’imaginer les personnes qui souhaitent commander une liste de films en fonction de leur classement, de sorte que tous les films classés G, puis PG, etc. (Dans cet exemple et l'exemple de repas, ils pourraient être commandés par term_id plutôt que par nom.) Il existe une zone grise où vous êtes probablement mieux servi par une taxonomie que par une méta, mais il est également utile que cette taxonomie soit commandée. -capable.
SeventhSteel
2
Les classements PG et G et autres constituent un bon choix de taxonomie, sauf qu’il s’agit de données relatives à des films spécifiques. Ainsi, ils sont méta. Ce sont des données, pas des catégories. Avoir un nombre limité de choix ne fait pas une taxonomie. S'il doit être trié par, faites-le en méta ou forcez-le par la taxonomie via un code spécifique à la taxonomie. BTW, NC17 vient après PG. Donc, vous avez quand même besoin de code pour faire cette commande.
Otto
Je sais que je suis en retard à la fête avec ce commentaire, mais je me suis heurté à cela. La commande par taxonomie peut avoir du sens dans certaines situations. Nous avons des offres d'emploi sur un projet en tant que type d'article, puis les états et la ville dans lesquels l'emploi est traité sont des taxonomies. Nous voulons qu’ils soient facilement accessibles (montrer tous les emplois dans un État ou afficher tous les emplois dans une ville), la taxonomie était donc la meilleure solution. Parallèlement, il existe une recherche d’emploi générale dans laquelle nous souhaitons les classer d’abord par titre, puis par État, puis par ville.
Dennis Puzak
Autre cas d'utilisation: un client a plusieurs articles, chacun ayant une catégorie. Le client souhaite qu’une page répertoriant tous les articles puisse être triée par ordre alphabétique, par date ou par catégorie. Les catégories peuvent également être filtrées, mais répertorier tous les articles par catégorie par ordre alphabétique n’est pas aussi dingue d’un cas d’utilisation et vous le voyez apparaître assez souvent.
Wilson Biggs
15

Oui, mais c'est assez impliqué ...

Ajoutez à functions.php dans votre thème:

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 );

C'est frankensteined de certains trucs trouvés et des trucs que j'ai faits moi-même. Expliquer est assez difficile, mais le résultat final est que vous pouvez exécuter? Orderby = (requête de taxonomie var) & order = ASC (ou DESC) et elle décollera immédiatement!

Drew Gourley
la source
Merci Drew, je vais essayer et essayer d’exécuter ce SQL, il faut éditer un peu, mais cela pourrait fonctionner. Mon seul problème à présent, c’est que je risque d’aller dans la mauvaise direction, comme l’a souligné Otto. Merci Drew. EDIT- Pas besoin de modifier je peux voir où il a besoin de peaufiner :) Merci
yeope
Si vous l'avez attrapé dans les deux dernières minutes, ça ne marchera pas, allez-y, attrapez-le maintenant, je l'ai corrigé. Il a été défini pour deux taxonomies spécifiques, j'ai amélioré le code pour qu'il fonctionne avec toutes les taxonomies enregistrées.
Drew Gourley
Merci une fois de plus. Juste au cas où j'aurais essayé votre solution et que ça marcherait. De plus, si quelqu'un d'autre veut l'utiliser, vous devez changer add_filter('posts_clauses', 'orderby_tax_clauses', 10, 2 );en add_filter('posts_clauses', 'todo_tax_clauses', 10, 2 );Merci :)
yeope
Oui, ceci est maintenant corrigé dans le bloc de code, je l'ai tiré d'un projet sur lequel je travaille et j'ai oublié de changer le nom de la fonction même si je l'ai changé dans le crochet.
Drew Gourley
1
Savez-vous s'il est possible de commander les taxonomies par ID au lieu du nom? J'essaie d'obtenir le même résultat en classant les groupes de taxonomie par ID
Javier Villanueva
9

Je viens en retard au jeu ici, mais il existe un moyen plus simple et plus WordPressy de le faire.

Construisez votre requête fiscale comme d'habitude.

$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;

Configurez vos arguments pour query_posts ou WP_Query

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

Avant de passer votre appel query_posts / WP_Query, connectez-vous au filtre orderby et remplacez-le.

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');

n'oubliez pas de retirer le filtre par la suite ...

cela fonctionne car c / tax_query crée les jointures, etc. pour vous, il vous suffit de commander par l’un des champs de la jointure.

Francis Yaconiello
la source
2
Une idée sur la façon de commander par nom au lieu de term_taxonomy_id? la modification de term_taxonomy_id dans orderby_statement génère des erreurs
avez pris connaissance
C'est la bonne réponse pour quiconque est intéressé!
Mayra M
2

Eh bien, j'aimerais exposer mon expérience dans le tri des types d'articles personnalisés par catégorie / taxonomie.

LA TOILE

  1. Un site Web d'agence de voyages fonctionnant sur WordPress
  2. Contenu principal sur le type de message personnalisé appelé 'ruta'
  3. Taxonomie avec cette structure Type de voyage> continent> pays

L'AFFAIRE

Dans les pages de liste de catégories d'archives, le client souhaitait que les articles soient triés par

  1. Le continent, classé par nombre de routes sur chacun.
  2. Le pays, classé par ordre alphabétique.

LES MARCHES

Tout d’abord , j’attrape la requête de la requête de la page d’archive non modifiée qui se présentait de la manière suivante:

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

Deuxièmement , j'ai modifié le code SQL dans Sequel Pro par rapport à la base de données pour répondre à mes besoins. Je viens avec cela (oui, probablement, cela peut être amélioré: mes connaissances sur MySQL ne sont pas exceptionnelles):

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  

Troisièmement , j'ai lié la requête au fichier functions.php avec trois filtres: posts_fields, posts_join et posts_orderby

Le code dans 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;
 }

Enfin, j'ai déclenché les filtres du hook pre_get_post en fonction de certaines conditions.

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');

J'espère que cela peut aider quelqu'un

Xavier Caliz
la source
Beau travail, ridicule qui a pris cette quantité de code pour trier quelque chose par une taxonomie. Énorme problème avec WP.
Serraosays
2

J'ai eu un problème très similaire que j'ai traité: je veux commander une archive de type post personnalisé (articles de magazines) par une taxonomie personnalisée (questions). Je ne fais jamais de requêtes SQL directes sur mon site - et généralement si vous êtes comme ces autres réponses - vous devez repenser votre approche.

PROBLÈMES:

1) Wordpress ne vous permet pas de commander des taxonomies de manière intelligente.

2) Wordpress ne permet tout simplement pas orderbyd’utiliser des taxonomies sur des post-types WP_Query (comme l’a expliqué Otto).

SOLUTIONS:

1) Le meilleur moyen de trier les taxonomies consiste à utiliser le plugin Custom Taxonomy Order NE pour le moment. Il vous permet de commander la taxonomie via WYSIWYG, wp-admince qui n’est pas ce que je ferais mais je n’ai rien trouvé de mieux.

Lorsque vous installez le plugin, vous obtiendrez quelque chose de similaire à ce que j'ai fait ici. Prenez note de l'option Auto-sort Queries of this Taxonomy- définissez ceci sur Custom Order as Defined Above; cela vous donne la commande dont vous avez besoin. Capture d'écran:

Affichage de l'ordre de taxonomie personnalisé

2) Avec une taxonomie triée en place, vous pouvez désormais créer une série d'appels WP_Query qui passent par chaque terme, créant ainsi une archive ordonnée par la taxonomie. Utilisez get_terms()pour créer un tableau de toutes les conditions fiscales, puis passez en foreachrevue chaque terme. Cela crée un WP_Queryélément pour chaque terme qui renvoie tous les articles pour un terme donné, créant ainsi une archive classée par terme de taxonomie. Code pour y arriver:

  // 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;
  }

Lecture connexe sur ce site: affiche tous les articles d'un type d'article personnalisé, regroupés par une taxonomie personnalisée.

Serraosays
la source
2

Je ne suis pas sûr de savoir pourquoi toutes les solutions proposées ici surpassent assez. OK, il y a une demi-décennie, mais j'utilise actuellement le code suivant et cela fonctionne:

   <?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);
    ?>

Cela va trier les taxonomies de votre CPT en fonction de sa taxonomie par ordre alphabétique et au sein de ces groupes de taxonomie ainsi que par ordre alphabétique.

utilisateur3135691
la source
@yeope Pourquoi est-ce la réponse acceptée!? Dieu merci, j'ai fait défiler
Juan Solano
1

Voici la solution que j'ai utilisée pour ce problème particulier. Cette solution est destinée aux cas extrêmes où il n'est pas possible d'utiliser un pre_get_postsfiltre et qu'il y a une pagination existante sur la requête (par exemple: 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);

J'ai utilisé cela pour créer un menu de navigation classé par taxonomie, terme et nombre de messages par terme.

Si vous voulez simplement les articles, changez la requête en SELECT p.*etGROUP BY p.ID

CodeShaman
la source
0

C'est comme une requête avant la requête, mais cela ne dérange pas si nous n'interrogeons pas trop de publications ... L'idée est de modifier la requête principale de manière à ce que nous n'ayons même pas besoin d'aller aux modèles et de générer de nouvelles requêtes. boucles...

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' );
Marcelo Viana
la source