Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Function to group posts by month WordPress

  • SOLVED

I need a function that work similar to the_date() but groups posts by month/year. It needs to work with the post type 'album'.

The loop should render like this:

<h2>Month, Year</h2>
<post dated end of month><post dated middle of month><post dated beginning of month>

<h2>Month, Year</h2>
<post dated end of month><post dated middle of month><post dated beginning of month>

<h2>Month, Year</h2>
<post dated end of month><post dated middle of month><post dated beginning of month>

Edit: The snippet below is the code that I use to display the archived items. The code as-is results in a repeating error that can be seen here: [[LINK href="http://surfbirdapp.com/myalbums"]]http://surfbirdapp.com/myalbums[[/LINK]]. If you can help me resolve this, we can wrap up the question.
For reference the code in the function surfbird_grab_album_image() can be found here: [[LINK href="http://wordpress.stackexchange.com/questions/30115/how-to-get-post-id-of-first-child-of-the-same-post-type"]]http://wordpress.stackexchange.com/questions/30115/how-to-get-post-id-of-first-child-of-the-same-post-type[[/LINK]]

<div style="margin-left:60px">
<div class="threecol" style="margin-left:-58px; width:230px !important">

<div style="background:url(<?php echo get_stylesheet_directory_uri() ?>/images/albumthumbbg.png) no-repeat; height:165px; display:block;" /><span style="display:block; position:relative; top:13; left:15"><a href=" ##<?php echo get_permalink() ?> "><?php echo surfbird_grab_album_image() ?></a></span>
</div>

<div style="display:inline-block; margin-bottom:20px; padding-left:20px"><?php printf( __( '<a href="%1$s" rel="bookmark">%2$s</a><br /><em>%3$s</em> images','twentyeleven' ), get_permalink(), get_the_title(), $total_images); ?></div>
</div>
</div>

Answers (4)

2011-10-03

Romel Apuya answers:

<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<ul >
<?php
/**/
$years = $wpdb->get_col("SELECT DISTINCT YEAR(post_date) FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'album' ORDER BY post_date ASC");
foreach($years as $year) :
?>
<h4><li><a href="<?php echo get_year_link($year ); ?> "><?php echo $year; ?></a>
<ul>
<?php $months = $wpdb->get_col("SELECT DISTINCT MONTH(post_date) FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'album' AND YEAR(post_date) = '".$year."' ORDER BY post_date ASC");
foreach($months as $month) :
?>
<h4>
<li><a href="<?php echo get_month_link($year, $month); ?>"><?php echo date( 'F', mktime(0, 0, 0, $month) );?></a>

<ul>
<?php $theids = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'album' AND MONTH(post_date)= '".$month."' AND YEAR(post_date) = '".$year."' ORDER BY post_date ASC");
foreach ($theids as $theid):
?>
<h4 style= font-style:italic;><li><a href="<?php bloginfo('url'); ?>?p=<?php echo $theid->ID; ?>"><?php echo $theid->post_title; ?></a></li></h4>

<?php
endforeach; ?>
</ul>
</li></h4>
<?php endforeach;?>
</ul>

</li></h4>
<?php endforeach; ?>
</ul>
</div>
</div>

2011-10-03

Sébastien | French WordpressDesigner answers:

use this code in your template




<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>

<ul >

<?php

/**/

$years = $wpdb->get_col("SELECT DISTINCT YEAR(post_date) FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_date ASC");

foreach($years as $year) :

?>

<h4><li><a href="<?php echo get_year_link($year ); ?> "><?php echo $year; ?></a>

<ul>

<?php $months = $wpdb->get_col("SELECT DISTINCT MONTH(post_date) FROM $wpdb->posts WHERE post_status = 'publish' AND YEAR(post_date) = '".$year."' ORDER BY post_date ASC");

foreach($months as $month) :

?>

<h4>

<li><a href="<?php echo get_month_link($year, $month); ?>"><?php echo date( 'F', mktime(0, 0, 0, $month) );?></a>



<ul>

<?php $theids = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE post_status = 'publish' AND MONTH(post_date)= '".$month."' AND YEAR(post_date) = '".$year."' ORDER BY post_date ASC");

foreach ($theids as $theid):

?>

<h4 style= font-style:italic;><li><a href="<?php bloginfo('url'); ?>?p=<?php echo $theid->ID; ?>"><?php echo $theid->post_title; ?></a></li></h4>



<?php

endforeach; ?>

</ul>

</li></h4>

<?php endforeach;?>

</ul>



</li></h4>

<?php endforeach; ?>

</ul>

</div>

</div>


Sébastien | French WordpressDesigner comments:

and to dsiplay excatly like you want use this code :

<?php

/**/

$years = $wpdb->get_col("SELECT DISTINCT YEAR(post_date) FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_date ASC");

foreach($years as $year) :

?>

<?php $months = $wpdb->get_col("SELECT DISTINCT MONTH(post_date) FROM $wpdb->posts WHERE post_status = 'publish' AND YEAR(post_date) = '".$year."' ORDER BY post_date ASC");

foreach($months as $month) :

?>
<h2><?php echo date( 'F', mktime(0, 0, 0, $month) );?> <?php echo $year; ?></h2>

<ul>

<?php $theids = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE post_status = 'publish' AND MONTH(post_date)= '".$month."' AND YEAR(post_date) = '".$year."' ORDER BY post_date ASC");

foreach ($theids as $theid): ?>

<li><a href="<?php bloginfo('url'); ?>?p=<?php echo $theid->ID; ?>"><?php echo $theid->post_title; ?></a></li>



<?php

endforeach; ?>

</ul>



<?php endforeach;?>


<?php endforeach; ?>


Sébastien | French WordpressDesigner comments:

About your edit : it's ANOTHER question !!!


Matt Taylor comments:

With all respect, it was only an issue because your solution involved prefixing everything. because of that it is not another question.


Sébastien | French WordpressDesigner comments:

ok try the code like this :

<?php



/**/



$years = $wpdb->get_col("SELECT DISTINCT YEAR(post_date) FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_date ASC");



foreach($years as $year) :



?>



<?php $months = $wpdb->get_col("SELECT DISTINCT MONTH(post_date) FROM $wpdb->posts WHERE post_status = 'publish' AND YEAR(post_date) = '".$year."' ORDER BY post_date ASC");



foreach($months as $month) :



?>

<h2><?php echo date( 'F', mktime(0, 0, 0, $month) );?> <?php echo $year; ?></h2>



<ul>



<?php $theids = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE post_status = 'publish' AND MONTH(post_date)= '".$month."' AND YEAR(post_date) = '".$year."' ORDER BY post_date ASC");



foreach ($theids as $post): ?>



<li><a href="<?php bloginfo('url'); ?>?p=<?php echo $post->ID; ?>"><?php echo $post->post_title; ?></a></li>







<?php



endforeach; ?>



</ul>







<?php endforeach;?>





<?php endforeach; ?>

2011-10-03

Jurre Hanema answers:

I think there is a simpler solution than what the other two answers suggest. In the template that displays your album posts (probably archive-album.php), make the loop like this:


<?php
$prev_month = '';
$prev_year = '';

while(have_posts())
{
the_post();

if(get_the_time('F') != $prev_month || get_the_time('Y') != $prev_year)
{
echo '<h2>'.get_the_time('F, Y').'</h2>';
}

?>
<div <?php post_class(); ?> id="album-<?php the_ID(); ?>">
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></h3>
<div class="entry">
<?php the_content(); ?>
</div>
</div>
<?php
$prev_month = get_the_time('F');
$prev_year = get_the_time('Y');
}
?>


Matt Taylor comments:

Works great, fixed all the issues and no wpdb calls!

2011-10-03

Linda answers:

Hi, are you interested in using a plugin or do you want to just code it? If you want to use a plugin you could try this one: [[LINK href="http://wordpress.org/extend/plugins/smart-archives-reloaded/"]]Smart Archives Reloaded[[/LINK]].

-Linda