Alle Posts in einem benutzerdefinierten Post-Typ anzeigen, der nach einer benutzerdefinierten Taxonomie gruppiert ist

18

Ich arbeite an einer Mitgliedsseite, auf der ich einen benutzerdefinierten Beitragstyp mit einer benutzerdefinierten Taxonomie verwende. Mein benutzerdefinierter Beitragstyp wird aufgerufen memberund meine benutzerdefinierte Taxonomie wird aufgerufen member_groups.

Ich möchte alle Mitglieder auflisten, aber sie in ihren jeweiligen Gruppen zusammenfassen.

Um es klar auszudrücken: Ich habe 35 Mitglieder in 9 Gruppen unterteilt. Anstatt die gleiche Abfrage neun Mal durchzuführen, möchte ich sie nur einmal zusammenfassen, sodass Mitglied1, Mitglied4 und Mitglied 11 in einer Gruppe zusammengefasst sind. genannt "Marketing".

Ich benutze WP_Query, um alle Beiträge unter Beitragstyp Mitglied abzurufen. Ich habe verschiedene Versuche versucht, aber ohne Erfolg.

Wie kann ich das erreichen?

Mestika
quelle

Antworten:

29

Sie könnten also in Betracht ziehen, die mehreren Abfragen zu automatisieren.

Rufen Sie zunächst die Liste der Begriffe in Ihrer benutzerdefinierten Taxonomie ab, indem Sie Folgendes verwenden get_terms():

<?php
$member_group_terms = get_terms( 'member_group' );
?>

Führen Sie dann eine Schleife durch, und führen Sie jedes Mal eine neue Abfrage aus:

<?php
foreach ( $member_group_terms as $member_group_term ) {
    $member_group_query = new WP_Query( array(
        'post_type' => 'member',
        'tax_query' => array(
            array(
                'taxonomy' => 'member_group',
                'field' => 'slug',
                'terms' => array( $member_group_term->slug ),
                'operator' => 'IN'
            )
        )
    ) );
    ?>
    <h2><?php echo $member_group_term->name; ?></h2>
    <ul>
    <?php
    if ( $member_group_query->have_posts() ) : while ( $member_group_query->have_posts() ) : $member_group_query->the_post(); ?>
        <li><?php echo the_title(); ?></li>
    <?php endwhile; endif; ?>
    </ul>
    <?php
    // Reset things, for good measure
    $member_group_query = null;
    wp_reset_postdata();
}
?>

Ich kann an diesem Ansatz nichts besonders Falsches erkennen , obwohl er möglicherweise nur eine eingeschränkte Skalierbarkeit aufweist (dh wenn Sie Hunderte oder Tausende von Mitgliedern oder Begriffe von member_group haben, können Leistungsprobleme auftreten).

Chip Bennett
quelle
Ja, es ist perfekt. Ich habe nur ein Problem. Ich möchte ausgeschnittene Felder wie diese <? Php get_post_meta ($ member_group_term-> ID, 'job_title', true) anzeigen;?> Aber es hat nicht funktioniert. Ich habe es auch mit $ post- versucht. > ID, aber es hat nicht geklappt. Könnten Sie @Chip Bennett bitte helfen?
Anahit DEV
6

Ich habe eine Lösung gefunden, indem ich eine benutzerdefinierte Abfrage verwendet und sie dann mit dem Termnamen gruppiert habe:

SELECT * 
FROM wp_term_taxonomy AS cat_term_taxonomy
INNER JOIN wp_terms AS cat_terms ON cat_term_taxonomy.term_id = cat_terms.term_id
INNER JOIN wp_term_relationships AS cat_term_relationships ON cat_term_taxonomy.term_taxonomy_id = cat_term_relationships.term_taxonomy_id
INNER JOIN wp_posts AS cat_posts ON cat_term_relationships.object_id = cat_posts.ID
INNER JOIN wp_postmeta AS meta ON cat_posts.ID = meta.post_id
WHERE cat_posts.post_status =  'publish'
AND meta.meta_key =  'active'
AND meta.meta_value =  'active'
AND cat_posts.post_type =  'member'
AND cat_term_taxonomy.taxonomy =  'member_groups'

Dann kann ich mit einer normalen foreach-Abfrage einfach die gewünschten Informationen extrahieren.

Aber ich bin immer noch an einer anderen Möglichkeit interessiert, vielleicht indem ich die eigenen Funktionen von Wordpress benutze.

Mestika
quelle
Ich habe gerade eine alternative Methode hinzugefügt. Ich neige dazu, alles zu scheuen, was rohe SQL-Abfragen erfordert.
Chip Bennett
2
Ich bin froh, dass dies als die richtige Antwort markiert ist, auch wenn die Abfrage in WordPress nicht mehr funktioniert, wenn sich das Schema irgendwann ändert ... Das Konzept, alle in einer einzigen Abfrage zusammenzufassen, ist die richtige Antwort. Die Iteration, um die Taxonomien in PHP zu gruppieren, wird nicht annähernd so gut skalieren wie dies der Fall sein wird.
wowo_999
4

noch einfacher:

$terms = get_terms('tax_name');
$posts = array();
foreach ( $terms as $term ) {
    $posts[$term->name] = get_posts(array( 'posts_per_page' => -1, 'post_type' => 'post_type', 'tax_name' => $term->name ));
}

Innerhalb des resultierenden $ posts-Arrays ist jeder Steuerbegriff der Schlüssel zu einem verschachtelten Array, das seine Posts enthält.

djb
quelle
4

Ich hatte genau dieses Bedürfnis und die Lösung von Chip funktionierte, abgesehen von einer Sache: 'field' => 'slug'ist erforderlich.

    foreach ( $service_categories as $category ) {
        $services = new WP_Query( 
            array(
                'post_type'     => 'service',
                'tax_query'     => array(
                    array(
                        'taxonomy'  => 'service_category',
                        'terms'     => array( $category->slug ),
                        'operator'  => 'IN',
                        'get'       => 'all',
                        'field'     => 'slug'
                    )
                )
            ) 
        ); ?>
        <h2><?php echo $category->slug; ?></h2>
        <?php if ( $services->have_posts() ) {  // loop stuff goes here ?>

Ich brauchte auch die resultierende Anzeige flach zu sein, so 'get' => 'all'ist hier eingestellt.

Hoffentlich hilft das jemand anderem.

Bigsweater
quelle
3
$query = new WP_Query( 
   array ( 
      'post_type' => 'member', 
      'orderby'   => 'meta_value', 
      'meta_key'  => 'member_group' 
   ) 
);

Wenn Sie diese Abfrage durchlaufen, können Sie einfach ein Wenn in diese Richtung verwenden (in PHP-Pseudocode).

$groupName = "";
$counter = 0;
if havePosts: while havePosts: thePost

if( $groupName != post->meta_value )
{
if ($counter > 0)
{
</ul>
}
<h1>A group name</h1>
<ul>
<li>member name</li>
}
else
{
<li>member name</li>
}

endwhile;endif

</ul>

Ich hoffe das hilft. Ich denke, Sie haben das viel komplizierter gemacht, als es sein musste.

Weitere Informationen: http://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters

AKnox
quelle
3

Ich musste das vor Jahren bei einem Projekt machen. Ähnliche Antwort an DJB, nur mit ein bisschen mehr Details. Dies gibt alle Taxonomienamen als h3 aus, wobei eine Liste mit Aufzählungszeichen für jeden Beitragstitel mit der jeweiligen Detailseite verknüpft ist.

<?php // Output all Taxonomies names with their respective items
$terms = get_terms('member_groups');
foreach( $terms as $term ):
?>                          
    <h3><?php echo $term->name; // Print the term name ?></h3>                          
    <ul>
      <?php                         
          $posts = get_posts(array(
            'post_type' => 'member',
            'taxonomy' => $term->taxonomy,
            'term' => $term->slug,                                  
            'nopaging' => true, // to show all posts in this taxonomy, could also use 'numberposts' => -1 instead
          ));
          foreach($posts as $post): // begin cycle through posts of this taxonmy
            setup_postdata($post); //set up post data for use in the loop (enables the_title(), etc without specifying a post ID)
      ?>        
          <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>    
        <?php endforeach; ?>
    </ul>                                                   
<?php endforeach; ?>
61 Pixel
quelle
1

Nun, es ist ein alter Thread, aber wenn jemand so vorbeikommt wie ich, könnte das helfen. Die Idee ist, die Hauptabfrage zu ändern, damit wir nicht die Vorlagen durchgehen und neue Abfragen und Schleifen generieren müssen ...

PS: Muss noch in großen dbs getestet werden. In meinem Fall war es zufriedenstellend.

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
quelle