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


18

Estou trabalhando em uma página de membro onde uso um tipo de postagem personalizado com uma taxonomia personalizada. Meu tipo de postagem personalizada é chamado membere minha taxonomia personalizada é chamada member_groups.

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

Então, para deixar claro, eu tenho 35 membros divididos em 9 grupos. Portanto, em vez de fazer a mesma consulta nove vezes, quero fazer uma vez, mas agrupá-los, para que os Membros 1, Membro 4 e Membro 11 sejam agrupados em um grupo, chamado "Marketing".

Estou usando WP_Querypara recuperar todas as postagens no membro do tipo de postagem. Eu tentei tentativas diferentes, mas sem resultado bem-sucedido.

Como posso conseguir isso?

Respostas:


29

Portanto, considere automatizar as várias consultas.

Primeiro, obtenha a lista de termos em sua taxonomia customizada, usando get_terms():

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

Em seguida, percorra cada uma delas, 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 vejo nada de particularmente errado com essa abordagem, embora ela possa ter uma capacidade limitada de escalar (ou seja, se você tiver centenas ou milhares de membros ou termos de grupo de membros, poderá ver problemas de desempenho).


Se a resposta ajudou de alguma forma, por favor, marque como resposta, caso a sua dúvida não tenha sido solucionada, por favor, poste novamente. > ID, mas não funcionou, você poderia ajudar @Chip Bennett, por favor?
Anahit DEV

6

Encontrei uma solução usando uma consulta personalizada e agrupando-a com o termo name:

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'

Então, usando apenas uma consulta foreach regular, posso extrair as informações que desejo.

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


Acabei de adicionar um método alternativo. Costumo me esquivar de qualquer coisa que exija consultas SQL brutas.
Chip Bennett

2
Fico feliz em ver isso marcado como a resposta correta, mesmo que a consulta pare de funcionar no wordpress se o esquema mudar em algum momento ... O conceito de coletar todos eles em uma única consulta é a resposta correta. A iteração para agrupar as taxonomias em php não será tão boa quanto essa escala.
Wowo_999 12/11/2013

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 $ posts resultante, cada termo de imposto é a chave para uma matriz aninhada que contém suas postagens.


4

Eu tinha exatamente essa necessidade e a solução de Chip funcionou, exceto por uma coisa: 'field' => 'slug'é necessária.

    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 tela resultante fosse plana, então 'get' => 'all'está definida aqui.

Espero que isso ajude alguém a sair.


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

Então, quando você percorrer essa consulta, você pode usar um if ao longo destas 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 tornando isso muito mais complicado do que precisava ser.

Mais informações: http://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters


3

Eu tive que fazer isso em um projeto anos atrás. Resposta semelhante ao djb, apenas com um pouco mais de detalhes. Isso exibirá todos os seus nomes de taxonomia como um h3, com uma lista com marcadores de cada título da postagem vinculada à sua 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; ?>

1

Bem, é um tópico antigo, mas se alguém passar como eu, isso pode ajudar. A idéia é modificar a consulta principal para que não precisemos ir nos modelos e gerar novas consultas e loops ...

PS: Ainda a ser testado em dbs grandes. 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' );
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.