Exibe todas as postagens em um tipo de postagem personalizada, agrupadas por uma taxonomia personalizada

13

Estou trabalhando em uma página de membros na qual uso um tipo de postagem personalizado com uma taxonomia personalizada. Meu tipo de postagem personalizada é chamado member e minha taxonomia personalizada é chamada de member_groups .

Eu quero listar todos os membros, mas agrupá-los em seus respectivos grupos.

Então, para ser claro, eu tenho 35 membros divididos em 9 grupos - então ao invés de fazer a mesma consulta nove vezes eu quero fazer uma vez, mas agrupá-los, então Member1, Member4 e Member 11 são agrupados em um grupo chamado “Marketing”.

Estou usando WP_Query para recuperar todas as postagens do membro do tipo de postagem. Eu tentei tentativas diferentes, mas sem resultados satisfatórios.

Como posso conseguir isso?

    
por Mestika 04.11.2011 / 13:09

7 respostas

5

Eu encontrei uma solução usando uma consulta personalizada e, em seguida, agrupando-a com o nome do termo:

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'

Em seguida, usando apenas uma consulta regular foreach, posso extrair as informações desejadas.

Mas ainda estou interessado em outro modo, se houver, talvez usando as próprias funções do Wordpress.

    
por Mestika 04.11.2011 / 13:31
26

Então, você pode considerar a automação de várias consultas.

Primeiro, veja a lista de termos da sua taxonomia personalizada usando get_terms() :

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

Em seguida, percorra cada um deles, executando uma nova consulta a cada vez:

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

Não consigo ver nada particularmente errado com essa abordagem, embora possa ter uma capacidade limitada de dimensionamento (ou seja, se você tiver centenas ou milhares de membros ou termos de membro_grupo, poderá observar o desempenho questões).

    
por Chip Bennett 25.01.2012 / 15:31
4

ainda mais simples:

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

Na matriz resultante de $ posts, cada termo de imposto é a chave para uma matriz aninhada que contém suas postagens.

    
por djb 04.04.2012 / 15:12
4

Eu tive essa necessidade exata, e a solução do Chip funcionou, exceto por uma coisa: 'field' => 'slug' é necessário .

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

Eu também precisava que a exibição resultante fosse plana, então 'get' => 'all' está definido aqui.

Espero que isso ajude alguém a sair.

    
por bigsweater 24.01.2013 / 02:38
2
$query = new WP_Query( 
   array ( 
      'post_type' => 'member', 
      'orderby'   => 'meta_value', 
      'meta_key'  => 'member_group' 
   ) 
);

Então, quando você percorre essa consulta, você pode usar um if ao longo dessas linhas (em pseudocódigo 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>

Espero que ajude. Eu acho que você estava fazendo isso muito mais complicado do que precisava ser.

Mais informações: enlace

    
por AKnox 05.11.2011 / 06:01
2

Eu tive que fazer isso em um projeto anos atrás. Resposta semelhante ao djb, apenas com um pouco mais de detalhes. Isso gerará todos os nomes de taxonomia como h3, com uma lista com marcadores de cada título de postagem vinculada à página de detalhes.

<?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; ?>
    
por 61Pixels 11.02.2015 / 18:55
0

Bem, é um tópico antigo, mas se alguém passar por mim, isso pode ajudar. A ideia é modificar a consulta principal para que não precisemos ir aos templates e gerar novas consultas e loops ...

PS: Ainda para ser testado em grandes dbs. Foi satisfatório no meu caso.

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' );
    
por Marcelo Viana 22.04.2017 / 08:33