Mostrar todas las publicaciones en un tipo de publicación personalizada, agrupadas por una taxonomía personalizada

18

Estoy trabajando en una página de miembro donde uso un tipo de publicación personalizada con una taxonomía personalizada. Se llama a membermi tipo de publicación personalizada y se llama a mi taxonomía personalizada member_groups.

Quiero enumerar todos los miembros pero agruparlos en sus respectivos grupos.

Para ser claros, tengo 35 miembros divididos en 9 grupos, así que en lugar de hacer la misma consulta nueve veces, quiero hacerlo una vez, pero agruparlos, de modo que Miembros1, Miembros4 y Miembros 11 se agrupen en un grupo, llamado "Marketing".

Estoy usando WP_Querypara recuperar todas las publicaciones en miembro de tipo de publicación. He intentado diferentes intentos pero sin resultados exitosos.

¿Cómo puedo lograr eso?

Mestika
fuente

Respuestas:

29

Por lo tanto, puede considerar automatizar las múltiples consultas.

Primero, obtenga la lista de términos en su taxonomía personalizada, usando get_terms():

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

Luego, recorra cada uno, ejecutando una nueva consulta 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();
}
?>

No puedo ver nada particularmente malo con este enfoque, aunque puede tener una capacidad limitada para escalar (es decir, si tiene cientos o miles de miembros, o términos de member_group, puede ver problemas de rendimiento).

Chip Bennett
fuente
Sí, funciona perfectamente. Solo tengo un problema. Quiero mostrar campos cutom como este <? Php get_post_meta ($ member_group_term-> ID, 'job_title', true);?> Pero no funcionó. También probé con $ post- > Identificación pero no funcionó, ¿podría ayudar a @Chip Bennett por favor?
Anahit DEV
6

Encontré una solución usando una consulta personalizada y luego agrupándola con el nombre del término:

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'

Luego, simplemente usando una consulta foreach normal, puedo extraer la información que quiero.

Pero todavía estoy interesado en otra forma si la hay, tal vez usando las propias funciones de Wordpress.

Mestika
fuente
Acabo de agregar un método alternativo. Tiendo a evitar cualquier cosa que requiera consultas SQL sin procesar.
Chip Bennett el
2
Me alegra ver esto marcado como la respuesta correcta, incluso si la consulta deja de funcionar en WordPress si el esquema cambia en algún momento ... El concepto de recopilarlos todos en una sola consulta es la respuesta correcta. La iteración para agrupar las taxonomías en php no se escalará tan bien como lo hará.
wowo_999
4

aún más simple:

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

Dentro de la matriz $ posts resultante, cada término de impuesto es la clave para una matriz anidada que contiene sus publicaciones.

djb
fuente
4

Tenía esta necesidad exacta, y la solución de Chip funcionó, excepto por una cosa: 'field' => 'slug'se requiere.

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

También necesitaba que la pantalla resultante fuera plana, así que 'get' => 'all'está configurada aquí.

Esperemos que esto ayude a alguien más.

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

Luego, cuando recorra esta consulta, puede usar un if a lo largo de estas líneas (en 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 eso ayude. Creo que estabas haciendo esto mucho más complicado de lo necesario.

Más información: http://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters

AKnox
fuente
3

Tuve que hacer esto en un proyecto hace años. Respuesta similar a djb, solo con un poco más de detalles. Esto generará todos sus nombres de taxonomía como h3, con una lista con viñetas de cada título de publicación vinculada a su página de detalles.

<?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 píxeles
fuente
1

Bueno, es un hilo viejo, pero si alguien pasa como yo, esto podría ayudar. La idea es modificar la consulta principal para que no necesitemos ir a las plantillas y generar nuevas consultas y bucles ...

PD: Aún no se ha probado en grandes dbs. Fue satisfactorio en mi 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' );
Marcelo Viana
fuente