• I have created two custom post types for a music related website: Works and Scores. Each Work has many Scores. I have set CPT-onomies up so that each Work is also a term in the taxonomy Works, and can be selected when I create a new Score.

    In the template for single-works, I want to list all the Scores associated with a given Work so I have this code inside the main loop:

    <?php $current_work = get_the_title(); ?>
    <?php echo "<h3>Scores</h3>"; ?>
    <?php
    $args = array('post_type' => 'scores',
                  'tax_query' => array (
                   array ( 'taxonomy' => 'works',
    		       'field'    => 'slug',
    		       'terms'    => $current_work)));
    $the_query = new WP_Query;
    while ( $the_query->have_posts() ) : $the_query->the_post();
    	the_content();
    endwhile;
    wp_reset_postdata();
    ?>

    Can I expect this to work? Currently it is not returning any of the Scores assigned to the Work. It works fine until I add in the tax_query stuff.

    What have I missed? Does get_the_title() return anything like the slug content?

Viewing 15 replies - 1 through 15 (of 15 total)
  • Thread Starter nprior

    (@nprior)

    Oops! It would help if I passed the $args, wouldn’t it? Code as follows:

    <?php $current_work = get_the_title(); ?>
    <?php echo "<h3>Scores</h3>"; ?>
    <?php
    $args = array('post_type' => 'scores',
                  'tax_query' => array (
                   array ( 'taxonomy' => 'works',
    		       'field'    => 'slug',
    		       'terms'    => $current_work)));
    $the_query = new WP_Query ($args);
    while ( $the_query->have_posts() ) : $the_query->the_post();
    	the_content();
    endwhile;
    wp_reset_postdata();
    ?>

    But still no joy from this – any thoughts?

    Thread Starter nprior

    (@nprior)

    Well, I have a solution but it’s not very elegant…. Would appreciate a view on the use of CPT-onomies with the tax_query array for WP_query.

    <?php
    // The Query
    $args = array('post_type' => 'scores')  ;
    $the_query = new WP_Query ($args);
    // The Loop
    while ( $the_query->have_posts() ) : $the_query->the_post();
    $terms = wp_get_object_terms( $post->ID, 'works' );
    if ( $terms && !is_wp_error( $terms ) ) {
       foreach ( $terms as $term ) {
          if ($current_work==$term->name) {
    	      echo '<li>';
                  the_title();
    	      the_content();
    	      echo '</li>';
       		}
    	}
    }
    endwhile;
    // Reset Post Data
    wp_reset_postdata();
    ?>

    I’m adding support for tax_query right now and, if all goes well, will be pushing out an update later today!

    Thanks for all the info!

    Thread Starter nprior

    (@nprior)

    Fantastic! Thanks Rachel.

    This plugin solves something I started to build about 12 months ago and stopped because it was too difficult to give to someone to maintain. Recognise the story?!!

    Its plugins like yours really make WordPress into far more than just a blogging tool.

    Yes, I do recognize the story =)

    I’ve been using this concept of using custom post types as taxonomies for a while, but it was in a very rough form because I didn’t have time to do it right, I just needed it to work. But when the time came, I’m glad I was able to really devote some time and do it right.

    I also knew that I was not the only who had this need and I’m glad I can share my work with others.

    In case you haven’t noticed, version 1.0.2 is available and provides support for tax queries, although you don’t have to use the post title for the query (plus the post title != slug). You can use the post id, like so:

    <?php
    echo "<h3>Scores</h3>";
    $args = array('post_type' => 'scores',
       'tax_query' => array (
          array ( 'taxonomy' => 'works',
             'field'    => 'id',
             'terms'    => get_the_ID()
          )
       ));
    $the_query = new WP_Query ($args);
    while ( $the_query->have_posts() ) : $the_query->the_post();
    	the_content();
    endwhile;
    ?>

    Let me know if you have any problems or questions.

    Thread Starter nprior

    (@nprior)

    Much neater – thank you

    But what about this if i’d like to do a tax query from multiple post types and list them according to their taxonomy name in single-page?

    This outputs all the terms associated to the single-director in one list:

    <?php
    
    echo "<h3>This shows everything</h3>";
    $args = array('post_type' => array( 'musicals', 'movies', 'events' ),
       'tax_query' => array (
          array ( 'taxonomy' => 'directors',
             'field'    => 'id',
             'terms'    => get_the_ID()
          )
       ));
    $query = new WP_Query( $args );
    // The Query
    $the_query = new WP_Query( $args );
    
    // The Loop
    while ( $the_query->have_posts() ) : $the_query->the_post();
    ?>
    <li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>
    <?php endwhile; ?>

    Is it possible to list the terms according to their post type names without having to do 3 WP_Queries?

    Like so:

    Musicals

    Movies

    Events

    Thread Starter nprior

    (@nprior)

    I suppose you could (thinking out loud here) use the Loop to populate an array of posts, and do no more than that. Then sort the array, then process that new array as output. Some ideas here. (Not the SQL bits, although ….)

    It would be quicker by far to duplicate the WP-Querycode a few times for each post type, which is what I did! Elegant? No. Did I have to work all night on it? No. YMMV!

    If you wanted to use the Loop, here’s a modified version of the code you supplied that loops through the queried posts to print out a list for each post type. The only thing that needs to be tweaked for this snippet is what to do if there are no posts for a particular post type but that wouldn’t be too difficult to fix if need be:

    $directors_post_types = get_taxonomy( 'directors' )->object_type;
    $args = array(
       'post_type' => $directors_post_types,
       'tax_query' => array (
          array (
             'taxonomy' => 'directors',
    	 'field'    => 'id',
    	 'terms'    => get_the_ID()
          )
       ));
    // The Query
    $the_query = new WP_Query( $args );
    // The Loop
    if ( $the_query->have_posts() ) :
       $ptype = 0;
       do {
          ?><h3><?php echo get_post_type_object( $directors_post_types[ $ptype ] )->labels->name; ?></h3>
          <ul><?php
             while ( $the_query->have_posts() ) : $the_query->the_post();
                if ( get_post_type( get_the_ID() ) == $directors_post_types[ $ptype ] ) :
                   ?><li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li><?php
                endif;
             endwhile;
             $ptype++;
          ?></ul><?php
       } while ( $ptype < count( $directors_post_types ) );
    endif;

    Another option is what nprior suggested:

    $directors_post_types = get_taxonomy( 'directors' )->object_type;
    $posts = get_posts( array(
       'post_type' => $directors_post_types,
       'include' => $cpt_onomy->get_objects_in_term( get_the_ID(), 'directors' )
    ));
    
    // group by post type
    $all_posts = array();
    foreach( $posts as $this_post ) {
       $all_posts[ $this_post->post_type ][] = $this_post;
    }
    
    // foreach post type lets you print something out of if no posts exist
    foreach( $directors_post_types as $post_type ) {
       ?><h3><?php echo get_post_type_object( $post_type )->labels->name; ?></h3><?php
       if ( isset( $all_posts[ $post_type ] ) ) {
          ?><ul><?php
             foreach( $all_posts[ $post_type ] as $this_post ) {
    	    ?><li><a href="<?php echo get_permalink( $this_post->ID ) ?>" rel="bookmark"><?php echo get_the_title( $this_post->ID ); ?></a></li><?php
             }
          ?></ul><?php
       }
       else {
          ?><p>There are no posts.</p><?php
       }
    }

    Did either of these do the trick?

    Yes!

    They both work and they do the trick! Thanks again, Rachel!

    I wanted to use the loop, because that’s the only way i know how to get that info out. Are there other ways?

    I can’t think of any better options at the moment. If something strikes, I’ll let you know.

    Thanks Rachel, your plugin have saved me a lot of work… this solution is kinda weird because it only works with WP_Query() but not with get_posts()

    I was trying to use get_posts() instead because its more recommended to use to start a loop inside another loop.

    But didn’t have success, so I had to use WP_Query() and now it works like a charm.

    You’ve got to check why it doesn’t work with get_posts()

    Hmm… it seems you are correct! I’ll look into it. Thanks!

    And now I remember why. get_posts() default-ly sets ‘suppress_filters’ to true which disables all the filters that allow CPT-onomies to work.

    Set 'suppress_filters' => false and let me know if it works.

    I guess I just have to decide if this is something I should, or even can, take care of inside the plugin. I’ll add a note to the documentation for now.

    I’ve added get_posts() to my documentation.

Viewing 15 replies - 1 through 15 (of 15 total)
  • The topic ‘[Plugin: CPT-onomies]Listing custom posts within the Loop’ is closed to new replies.