5

I am trying to format a custom post type for a "series". Each post is an Episode, each Episode belongs to a Season, and each Season belongs to a series (just like a TV show).

I have the following:

  • Custom Post type: "Episodes"
  • Custom Taxonomy: "Series"
    • Inside Series, parent category of "Real Deal"
      • Inside "Real Deal" category, several subcategories (IE "Season 1", "Season 2" ..)

I need to be able to select my "Episodes" both by Series (IE, "Real Deal" in the above), as well as by Season (IE, "Season 1" of Real Deal).

An image speaks a thousand words so here's a quick mockup of what I mean:

enter image description here

WHAT I'VE TRIED

Here's the code I currently have, however I don't think I'm on the right track for doing what I've illustrated above. This will get me all the Episodes for Season 1, However I need to get all the episodes for every season, and then group each season into it's own HTML container.

<?php
  $args = [
      'post-type'   => 'episode',
      'post-status' => 'publish',
      'tax_query'   => [
          [
              'taxonomy' => 'series',
              'field'    => 'slug',
              'terms'    => 'season-1'
          ]
      ]
  ];
  $episodes = new WP_Query($args);
  if ( $episodes->have_posts() ) {
    while( $episodes->have_posts() ) {
        $episodes->the_post();
        get_template_part('content','episodes');
    }
  } else {
    get_template_part('content', 'none');
  }
?>

QUESTION

How can I structure my Query to A) Select all episodes, grouped by Series, then displayed by season?

EDIT:

I ended up using the 3rd code snippet provded by Michael Ecklund, it managed to accomplish exactly what I was looking for -- grabbing the 4 most recent posts in each season, and storing them into an array. Thank you for your help!

  • Hi Prefix, could you provide more details on what you've tried already (and why it didn't work)? – kraftner Mar 25 '15 at 16:11
  • Hi @kraftner, certainly -- I've added my current code, however I don't think I'm on the right track for doing what I've outlined above so any suggested methods are much appreciated :) – Prefix Mar 25 '15 at 16:15
  • 1
    Just a quick tip: The more you prove that you've tried hard yourself but are stuck, the more likely people will help as you don't come along as lazy and letting other people do your work. As it stands your question is perfect now: Good explanations, images to help explain and an example of what you tried. Someone will soon help. :) – kraftner Mar 25 '15 at 16:17
  • Have you seen: wordpress.stackexchange.com/questions/137065/… – kraftner Mar 25 '15 at 16:31
  • @kraftner interesting, seems to mostly deal with pagination however. I don't anticipate needing pagination for my page. I just need to get the 4 most recent postings for each season, and output them into seperate containers by season. – Prefix Mar 25 '15 at 16:54
4

Here's a straight up simple solution. Requires you to have the most recent version of WordPress though. (or at least 4.1)

Using nested taxonomy query.

Taking what you have, and just adding to it a bit.

$args = array(
    'post-type'      => 'episode',
    'post-status'    => 'publish',
    'posts_per_page' => 4,
    'tax_query'      => array(
        'relation' => 'AND',
        array(
            'taxonomy' => 'series',
            'field'    => 'slug',
            'terms'    => array( 'real-deal' ),// Name of the series (in slug format)
        ),
        array(
            'taxonomy' => 'series',
            'field'    => 'slug',
            'terms'    => array( 'season-1' ),// Name of the season (in slug format)
        )
    )
);

$episodes = new WP_Query( $args );

print_r( $episodes->posts );

That's just saying find the 4 most recent published episodes that belong to a specific series and also contain a specific season. (this is what your visual mockups appear to be portraying)

You mentioned needing the "seasons" to be dynamic.

Here's how you can get all "subcategories" (seasons) from the parent category (series) and then retrieve the 4 latest episodes from that series, and in all possible seasons.

$taxonomy = 'series';

$seasons = get_terms( $taxonomy, array(
    'parent' => 1, // TERM ID OF THE SERIES
    'fields' => 'id=>slug'
) );

if ( ! empty( $seasons ) && ! is_wp_error( $seasons ) ) {

    $args = array(
        'post-type'      => 'episode',
        'post-status'    => 'publish',
        'posts_per_page' => 4,
        'tax_query'      => array(
            'relation' => 'AND',
            array(
                'taxonomy' => $taxonomy,
                'field'    => 'slug',
                'terms'    => array( 'industry-news' ),// Name of the "series" (in slug format)
            ),
            array(
                'taxonomy' => $taxonomy,
                'field'    => 'slug',
                'terms'    => array_values( $seasons ),// Name of the "seasons" (in slug format) DYNAMIC
            )
        )
    );

    $episodes = new WP_Query( $args );

    print_r( $episodes->posts );

}

Let's say you have 3 seasons in a series... And you want to display the 4 latest episodes from each season in this series.

$taxonomy = 'series';

$seasons = get_terms( $taxonomy, array(
    'parent' => 1, // TERM ID OF THE SERIES
    'fields' => 'id=>slug'
) );

$season_episodes = array();

if ( ! empty( $seasons ) && ! is_wp_error( $seasons ) ) {

    foreach ( array_values( $seasons ) as $season ) {

        $season_episodes[ $season ] = array();// Placeholder in-case there's no episodes found.

        $args = array(
            'post-type'      => 'episode',
            'post-status'    => 'publish',
            'posts_per_page' => 4,
            'tax_query'      => array(
                'relation' => 'AND',
                array(
                    'taxonomy' => $taxonomy,
                    'field'    => 'slug',
                    'terms'    => array( 'industry-news' ),// Name of the "series" (in slug format)
                ),
                array(
                    'taxonomy' => $taxonomy,
                    'field'    => 'slug',
                    'terms'    => array( $season ),// Name of the "seasons" (in slug format) DYNAMIC
                )
            )
        );

        $episodes = new WP_Query( $args );

        if ( ! empty( $episodes->posts ) ) {
            $season_episodes[ $season ] = $episodes->posts;// Add all episodes found in this season.
        }

    }

}

if ( ! empty( $season_episodes ) ) {
    print_r( $season_episodes );
}

This last method will take the latest 4 episodes in a series put those 4 posts into separate arrays categorized by seasons.

So all said and done, you'll have an array for each season in the series containing 4 recent episodes. All you have to do is output the information.

  • This is great -- I need to get the 4 most recent published episodes for ALL seasons however -- do I just change 'terms'=>'real-deal' in the second tax query array? – Prefix Mar 25 '15 at 17:17
  • The first array specifies the name of the series, the second array specifies the name of the season. and when I say name, I'm actually meaning the slug. – Michael Ecklund Mar 25 '15 at 17:20
  • Can I do it without specifying the season? As new seasons are created (3,4,5.. etc) I don't want to have to edit the query itself. It should automatically grab all the seasons – Prefix Mar 25 '15 at 17:22
  • basically, if there are 3 seasons it should grab the 4 most recent posts from each season. Later down the line if the client adds a new 4th season, the page should display that one as well without editing the code. – Prefix Mar 25 '15 at 17:23
  • Well that's not really what your mockups are demonstrating. but yeah, just add to the array.... instead of just array( 'season-1' ); you could do array( 'season-1', 'season-2', 'season-3' ); etc. – Michael Ecklund Mar 25 '15 at 17:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.