WordPress.org

Ready to get started?Download WordPress

Forums

[Plugin: CPT-onomies]Listing custom posts within the Loop (16 posts)

  1. nprior
    Member
    Posted 2 years ago #

    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?

  2. nprior
    Member
    Posted 2 years ago #

    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?

  3. nprior
    Member
    Posted 2 years ago #

    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();
    ?>
  4. Rachel Carden
    Member
    Posted 2 years ago #

    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!

  5. nprior
    Member
    Posted 2 years ago #

    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.

  6. Rachel Carden
    Member
    Posted 2 years ago #

    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.

  7. nprior
    Member
    Posted 2 years ago #

    Much neater - thank you

  8. r1987
    Member
    Posted 2 years ago #

    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

  9. nprior
    Member
    Posted 2 years ago #

    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!

  10. Rachel Carden
    Member
    Posted 2 years ago #

    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?

  11. r1987
    Member
    Posted 2 years ago #

    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?

  12. Rachel Carden
    Member
    Posted 2 years ago #

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

  13. r2kjet
    Member
    Posted 1 year ago #

    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()

  14. Rachel Carden
    Member
    Posted 1 year ago #

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

  15. Rachel Carden
    Member
    Posted 1 year ago #

    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.

  16. Rachel Carden
    Member
    Posted 1 year ago #

    I've added get_posts() to my documentation.

Topic Closed

This topic has been closed to new replies.

About this Topic