Handy Custom Taxonomy Template

boat brain

In a few short days I will be on a boat for Ireland. This is a much awaited and much needed vacation – I’ve been going full force since…I honestly can’t remember the last time I took more than a couple days off let alone took a trip that didn’t involve WordPress.

But my brain has already been on that boat for the better part of two weeks. Yes, I have boat brain. This has been making the task of actually getting work done in anticipation of the trip particularly challenging.

I’m currently working on a beautiful site – bathing suits, a nice change-up from all things wedding-oriented – using both Woocommerce and WPML. It’s got custom post types and sliding menus and parallax effects. It’s going to be awesome…if only my boat brain would cooperate.

For the past week I’d been stuck on what should have been (and ultimately is) a pretty straightforward template for displaying custom post types by their custom taxonomies. For my purposes, there are no single post views, I have a two-part scenario:

  1. If the taxonomy has no children, I want to display the posts in a list on that taxonomy archive page (with a nice URL mysite.com/taxonomy/term)
  2. If the taxonomy does have children, then I was to display the posts in a list, but grouped by these child terms.

Put concretely, my post type is Distributors, and on one page I have a simple list of Online Distributors. Then, for stores, these contacts are organized first by continent, then by country.

custom taxonomy template

After scouring the forums and trying multiple approaches, I finally asked for help. Luckily I know awesome people, and one rockstar in particular (though don’t tell him I called him that, he hates it) who threw me a life vest. I thought it appropriate to share:

[pastacode lang=”php” message=”” highlight=”” provider=”manual”]

/* HANDY CUSTOM TAXONOMY TEMPLATE */
	
$current_location = get_queried_object();
$child_locations  = get_terms( $current_location->taxonomy, array(
     'child_of' => $current_location->term_id,
) );
                    
$query_args = array( 'post_type' => 'YOUR-CUSTOM-POST-TYPE', 'posts_per_page' => - 1, );
                    
if ( empty( $child_locations ) ) {
                    
     $query_args['tax_query'] = array(
          array(
          'taxonomy' => $current_location->taxonomy,
          'terms'    => $current_location->term_id,
          ),
     );
                    
     $distributors = new WP_Query( $query_args );                    
     while ( $distributors->have_posts() ) : $distributors->the_post();
                    
          /* PUT SOME STUFF HERE */
                    
     endwhile;
                    
} else { 
                    
     foreach ( $child_locations as $location ) {                    
          echo '<h2>' . esc_html( $location->name ) .'</h2>' ;
                    
          $query_args['tax_query'] = array(
               array(
               'taxonomy' => $location->taxonomy,
               'terms'    => (int)$location->term_id,
               'field'    => $location->slug,
               ),
          );
                    
          $distributors = new WP_Query( $query_args );
          while ( $distributors->have_posts() ) : $distributors->the_post(); 
                    
               /* PUT SOME STUFF HERE */
                    
          endwhile;  
     }                   
}

[/pastacode]

Et voilà ! Easy.

I even got a little fancier, and, as you can surmise from the image above, wrapped my content in an accordion. Am I on a boat yet?

/* UPDATE – July 9, 2014 */

I ran into a little snafu with WPML that resulted in some notices being thrown and my content not showing up for the child taxonomy pages in my translated language. After some banging my head against the wall, I discovered two things:

  1. WPML doesn’t like it when the ‘field’ parameter isn’t defined in the tax_query
  2. For some unexplainable reason, the translated version wasn’t reading the term_id as an integer. Thanks to Samy for pointing me to int() which helped me force its hand and get my content to display.

Code above has been updated. smile