Hi all,
What I am trying to do is create the following:
CPT: Workshops
Custom Tax: workshops_tax
Primary Terms: Adults, Kids
Secondary Terms: Jan-April, May-Aug, Sept-Dec
(I am aware this will need different slugs e.g. jan_apr_kids, jan_apr_adults)
Tertiary Terms: Monday, Tues, Wed, Thurs etc.
(also with difernet slugs e.g. jan-apr-mon-kids, jan-apr-mon-adults)
Then with the idea being to create two pages:
Regular Workshops: Kids
Regular Workshops: Adults
Each of those pages then needs to display the posts assigned to each, by initially the second level term and then by the tertiary level term like so:
–––––––––––––––––––––––––––––––––––––––
h1 - Regular Workshops: Kids - h1
h2 - January - April - h2
h3 - Monday - h3
div - Post #1 (title, content, custom field data etc.) - div
div - Post #2 (title, content, custom field data etc.) - div
h3 - Tuesday - h3
div - Post #1 (title, content, custom field data etc.) - div
div - Post #2 (title, content, custom field data etc.) - div
etc.
h2 - May - Aug - h2
h3 - Monday - h3
div - Post #1 (title, content, custom field data etc.) - div
div - Post #2 (title, content, custom field data etc.) - div
h3 - Tuesday - h3
div - Post #1 (title, content, custom field data etc.) - div
div - Post #2 (title, content, custom field data etc.) - div
etc.
-------------------------------------------------------
The Adult page being the same, but obviously showing the posts assigned with the primary term 'adult'.
Can anyone provide an example loop (or probable nested loop) I'd need for one of these pages please?
I'll need the facility for the loop to not return empty tertiary levels terms (i.e. if there are no posts(events) added on a Monday, then the box containing those events doesn't appear.
Thanks!
Adam.
Remy answers:
I think this should work. You don't have to worry about empty terms, since the get_terms query doesn't get empty terms (hide_empty on 1 by default).
$parent_term = get_term_by( 'name', 'kids', 'workshop_tax' );
$children = get_terms( 'workshop_tax', array( 'orderby' => 'id', 'parent' => $parent_term->term_id ) );
if ( !empty( $children ) && !is_wp_error( $children ) ) :
foreach ( $children as $child ) : ?>
<h2><?php echo $child->name ?></h2>
<?php $subchildren = get_terms( array( 'workshop_tax', 'orderby' => 'id', 'parent' => $child->term_id ) );
if ( !empty( $subchildren ) && !is_wp_error( $subchildren ) ) :
foreach ( $subchildren as $subchild ) : ?>
<h3><?php echo $subchild->name ?></h3>
<?php $workshops = new WP_Query( array(
'post_type' => 'workshops',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'workshop_tax',
'field' => 'id',
'terms' => $subchild->term_id
)
)
) );
if ( $workshops->have_posts() ) :
while( $workshops->have_posts() ) : $workshops->the_post(); ?>
<div>
// Post content
</div>
<?php end while;
wp_reset_postdata();
endif;
endforeach;
endif;
endforeach;
endif;
flint_and_tinder comments:
Hi Remy,
Unfortunately this doesn't quite work. I've added in the php code for the posts in the div, but for example, on the adult page, I get this:
----------------------------
Regular Workshops: Adults
h2 - January -April - h2
[Nothing]
h2 - May -August - h2
[Nothing]
---------------------------
The 3rd level terms and post titles aren't displaying.
Thinking about this further though. I'd like to add in Advanced custom field checkbox to the page that allows the user to only show certain second level terms if required.
So, I'll end up with something like this:
------------------------------------
Main page loop
- page title -
// If statement to see if advanced custom field checkbox for Jan - Feb is selected //
_____________________________
LOOP that gets the following:
workshops_type
workshop_tax
adult term
jan-feb-adult tax
_____________________
h2 - 2nd Term (e.g. January - April) - h2
h3 - Monday - h3
div - post #1 - div
div - post #1 - div
div - post #1 - div
h3 - Tuesday - h3
div - post #1 - div
div - post #1 - div
div - post #1 - div
etc.
// end of my checkbox if statement //
Then I can just duplicate the loop for the rest of the 2nd terms (May - Aug, Sept - Dec) changing the query each time and setting each query within another if statement before...
End main page loop
------------------------------------------
I think that would be much easier.
flint_and_tinder comments:
Can you help with the loop in the above comment?
I already have the code for the main page loop and if statements for each sub-loop. It's just the sub-loop itself. I don't know how to get the posts for a 3rd level term.
Remy comments:
Ok my code is not working because I made a mistake on one line. If you want to do it the way you say in your last post, you can keep only this part
$parent = get_term_by( 'name', 'jan-feb-adult', 'workshop_tax' );
<?php $subchildren = get_terms( 'workshop_tax', array( 'orderby' => 'id', 'parent' => $parent->term_id ) );
if ( !empty( $subchildren ) && !is_wp_error( $subchildren ) ) :
foreach ( $subchildren as $subchild ) : ?>
<h3><?php echo $subchild->name ?></h3>
<?php $workshops = new WP_Query( array(
'post_type' => 'workshops',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'workshop_tax',
'field' => 'id',
'terms' => $subchild->term_id
)
)
) );
if ( $workshops->have_posts() ) :
while( $workshops->have_posts() ) : $workshops->the_post(); ?>
<div>
// Post content
</div>
<?php end while;
wp_reset_postdata();
endif;
endforeach;
endif;
flint_and_tinder comments:
That doesn't work properly either I'm afraid.
With the $parent term set to 'january-april-kids', I should just get the two test posts assigned to that term, but it's outputting <strong>all</strong> the posts like this:
---------------------
Regular Workshops: Kids
Adult
Test post #1
Test post #2
Test post #3
Test post #4
Kids
Test post #5
Test post #6
Test post #7
Test post #8
---------------------
When it should be like this:
---------------------
Regular Workshops: Kids
January - April
Monday
Test post #5
Kids
Test post #6
---------------------
Remy comments:
Can you show me the whole code you have ?
On my test site it's working like expected, with the parent term, then the sub term, then the 3rd level term & the posts below.