Search code examples
phpwordpressforeachcustom-taxonomytaxonomy-terms

Display each taxonomy term post under a Year and Month heading


I have a CPT - 'newsletters' and Taxonomy 'newsletter-groups'

I'm trying to display each post under it's respective term heading with all that terms posts displayed under it showing the Month and Year they were posted (by Postdate).

I thought I had something working , but noticed during testing that if a post had the same 'Month' it would wipe out the year and month for other posts in the same term and also for the terms below it , I have some images to show what I mean and the code I'm using so far.

In the images shown I've appended the post date to the filename for clarity , it would normally be just the filename.

Not Working if post date month is the same Not Working if month the same

Working if post date month is different

enter image description here

How can I solve this ? do I need to get all the post dates with a separate query and save that ?

Any examples appreciated

/*
 * Custom Template: Archive Newsletters
 */


// Remove stuff
remove_action( 'genesis_loop', 'genesis_do_loop' );

// Add our custom loop
add_action( 'genesis_loop', 'newsletter_archive_loop' );

function newsletter_archive_loop() {


  //fetch the terms for the newsletter-groups taxonomy
  $terms = get_terms( 'newsletter-groups', array (
    'hide_empty' => 'true',
    'exclude' => 67,  //excluding parent term ID 'school-newsletters' - only want to show term children of 'school-newsletters'
  ));

     
  // run a query for each term
  foreach( $terms as $term ) {

    // Define the query
    $args = array(
    'post_type'  => 'newsletters',
    'newsletter-groups' => $term->slug ,
    'posts_per_page' => -1,
    );


    // run the query 

    $query = new WP_Query( $args );
    
    if( $query->have_posts() ) { 

      echo '<div class="letters">'; 
          
        // output the term name in a heading tag    
        echo'<h4 class="term-heading">' . $term->name . '</h4>'; 

        while ( $query->have_posts() ) { $query->the_post();
          
          // get current month
          $current_month = get_the_date('F');
          // get attachements from custom field
          $attachment_id = get_field('newsletter_upload');
          $url = wp_get_attachment_url( $attachment_id );
          $title = get_the_title( $attachment_id );
          // get the filesize
          $filesize = filesize( get_attached_file( $attachment_id ) );
          $filesize = size_format($filesize, 2);

            if( $query->current_post === 0 ) { 
                  echo '<h4 class="date">';
                        the_date( 'F Y' );
                  echo '</h4>';
            
              } else { 

                  $f = $query->current_post - 1;       
                  $old_date =   mysql2date( 'F', $query->posts[$f]->post_date ); 

                  if($current_month != $old_date) {
                    echo '<h4 class="date">';
                          the_date( 'F Y' );;
                    echo '</h4>';
                  }

            } ?>

            <li class="letters-file">
              <a href="<?php echo $url; ?>" title="<?php echo $title; ?>" target="_blank" rel="noopener noreferrer"><?php the_title(); ?></a><span class="letters-file-sz">&nbsp;(<?php echo $filesize; ?>)</span>
            </li> 

        <?php } // endwhile have posts

      echo '</div>'; // close letters div
    
      // use reset postdata to restore orginal query
      wp_reset_postdata();  
      
    } // end if query have posts

  } // end for each

} // end function 

genesis(); // call genesis framework

Remove if and else both conditions and try to print only echo ''; the_date( 'F Y' ); echo ''

it will only show the individual post dates - But not grouped

enter image description here

EXPECTED OUTPUT

enter image description here


Solution

  • You can push each month in an array and check if the month is already in the array then do not display repeat month.

    /*
     * Custom Template: Archive Newsletters
     */
    
    // Remove stuff
    remove_action( 'genesis_loop', 'genesis_do_loop' );
    
    // Add our custom loop
    add_action( 'genesis_loop', 'newsletter_archive_loop' );
    
    function newsletter_archive_loop() {
    
        //fetch the terms for the newsletter-groups taxonomy
        $terms = get_terms( 'newsletter-groups', array (
            'hide_empty' => 'true',
            'exclude' => 67,  //excluding parent term ID 'school-newsletters' - only want to show term children of 'school-newsletters'
        ));
     
        // run a query for each term
        foreach( $terms as $term ) {
    
            $dates = array();
    
            // Define the query
            $args = array(
                'post_type'         => 'newsletters',
                'newsletter-groups' => $term->slug ,
                'posts_per_page'    => -1,
            );
    
            // run the query 
            $query = new WP_Query( $args );
            
            if( $query->have_posts() ) { 
    
                echo '<div class="letters">'; 
                  
                    // output the term name in a heading tag    
                    echo'<h4 class="term-heading">' . $term->name . '</h4>'; 
    
                    while ( $query->have_posts() ) { $query->the_post();
                      
                        // get current month
                        $current_month = get_the_date('F');
                      
                        // get attachements from custom field
                        $attachment_id = get_field('newsletter_upload');
                        $url             = wp_get_attachment_url( $attachment_id );
                        $title       = get_the_title( $attachment_id );
    
                        // get the filesize
                        $filesize = filesize( get_attached_file( $attachment_id ) );
                        $filesize = size_format($filesize, 2);
    
                        if( !in_array(get_the_date( 'F Y' ), $dates ) ){
                            $dates[] = get_the_date( 'F Y' );
                            echo '<h4 class="date">';
                                echo get_the_date( 'F Y' );
                            echo '</h4>';
                        }
    
                        ?>
    
                        <li class="letters-file">
                            <a href="<?php echo $url; ?>" title="<?php echo $title; ?>" target="_blank" rel="noopener noreferrer"><?php the_title(); ?></a><span class="letters-file-sz">&nbsp;(<?php echo $filesize; ?>)</span>
                        </li> 
    
                    <?php } // endwhile have posts
    
                echo '</div>'; // close letters div
            
                // use reset postdata to restore orginal query
                wp_reset_postdata();  
          
            } // end if query have posts
    
        } // end for each
    
    } // end function 
    
    genesis(); // call genesis framework