Wyświetl wszystkie posty w niestandardowym typie wiadomości, pogrupowane według niestandardowej systematyki

18

Pracuję na stronie członka, na której używam niestandardowego typu posta z niestandardową taksonomią. Mój niestandardowy typ postu jest nazywany, membera moja niestandardowa systematyka jest nazywana member_groups.

Chcę wymienić wszystkich członków, ale zgrupować ich razem w odpowiednich grupach.

Żeby było jasne, mam 35 członków podzielonych na 9 grup - więc zamiast dziewięciu razy wykonać to samo zapytanie, chcę to zrobić raz, ale zgrupować je razem, tak aby Member1, Member4 i Member 11 zostali zgrupowani w jedną grupę, zwany „marketingiem”.

Używam WP_Querydo pobierania wszystkich postów należących do członka typu post. Próbowałem różnych prób, ale bez powodzenia.

Jak mogę to osiągnąć?

Mestika
źródło

Odpowiedzi:

29

Dlatego możesz rozważyć zautomatyzowanie wielu zapytań.

Najpierw uzyskaj listę terminów w swojej niestandardowej taksonomii, używając get_terms():

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

Następnie przejrzyj każdy z nich, za każdym razem uruchamiając nowe zapytanie:

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

Nie widzę nic szczególnie złego w tym podejściu, chociaż może mieć ograniczoną zdolność skalowania (tj. Jeśli masz setki lub tysiące członków lub warunki członkostwa w grupie, możesz zauważyć problemy z wydajnością).

Chip Bennett
źródło
Tak, doskonale brzmi. Tylko jeden problem, który mam. Chcę wyświetlić pola cutom, takie jak <? Php get_post_meta ($ member_group_term-> ID, 'job_title', true);?> Ale to nie zadziałało. Próbowałem również z $ post- > Dowód tożsamości, ale nie działał, czy mógłbyś pomóc @Chip Bennett?
Anahit DEV
6

Znalazłem rozwiązanie, używając niestandardowego zapytania, a następnie grupując je według nazwy:

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'

Następnie za pomocą zwykłego zapytania foreach mogę po prostu wyodrębnić potrzebne informacje.

Ale nadal interesuje mnie inny sposób, jeśli istnieje, może za pomocą własnych funkcji Wordpress.

Mestika
źródło
Właśnie dodałem alternatywną metodę. Mam tendencję do unikania wszystkiego, co wymaga surowych zapytań SQL.
Chip Bennett
2
Cieszę się, że zaznaczono to jako poprawną odpowiedź, nawet jeśli zapytanie przestanie działać w Wordpress, jeśli schemat zmieni się w pewnym momencie ... Koncepcja zebrania ich wszystkich w jednym zapytaniu jest poprawną odpowiedzią. Iteracja grupowania taksonomii w php nie będzie się skalować prawie tak dobrze, jak to będzie.
wowo_999,
4

jeszcze prostszy:

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

W wynikowej tablicy $ posts każdy termin podatkowy jest kluczem do zagnieżdżonej tablicy zawierającej jej posty.

djb
źródło
4

Miałem taką dokładną potrzebę i rozwiązanie Chipa zadziałało, z wyjątkiem jednej rzeczy: 'field' => 'slug'jest wymagane.

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

Potrzebowałem też płaskiego wyświetlacza, więc 'get' => 'all'ustawiam go tutaj.

Mam nadzieję, że pomoże to komuś innemu.

bigsweater
źródło
3
$query = new WP_Query( 
   array ( 
      'post_type' => 'member', 
      'orderby'   => 'meta_value', 
      'meta_key'  => 'member_group' 
   ) 
);

Następnie, gdy przechodzisz przez to zapytanie, możesz po prostu użyć if wzdłuż tych linii (w pseudokodzie php)

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

Mam nadzieję że to pomogło. Myślę, że uczyniłeś to o wiele bardziej skomplikowanym, niż trzeba.

Więcej informacji: http://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters

AKnox
źródło
3

Musiałem to zrobić w projekcie lata temu. Podobna odpowiedź do djb, tylko z nieco większą ilością szczegółów. Spowoduje to wyświetlenie wszystkich nazw taksonomii jako h3, z wypunktowaną listą każdego tytułu postu połączoną z ich stroną ze szczegółami.

<?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 pikseli
źródło
1

Cóż, to stary wątek, ale jeśli ktoś przejdzie tak jak ja, może to pomóc. Chodzi o modyfikację głównego zapytania, abyśmy nie musieli przechodzić do szablonów i generować nowych zapytań i pętli ...

PS: Jeszcze do przetestowania w dużych dbs. W moim przypadku było zadowalające.

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
źródło