This is a function I created a while back. It basically does what you want to do, but it's not a template. Maybe you can adapt it.
<?php
/**
* Displays a condensed list of the posts grouped by month/year.
*
* @param $order The order of the posts. Either 'DESC' or 'ASC', case sensitive.
* @param $date_prefix Whether to prefix the posts with the month/date.
* @param $display Whether to display the results or return it as a String.
*/
function condensed_post_list($order='DESC', $date_prefix=true, $display=true){
global $wpdb;
if( !in_array($order, array('DESC','ASC' ) ) ) $order = 'DESC';
$query = "SELECT ID, post_title, post_date FROM $wpdb->posts ".
"WHERE post_type='post' AND post_status = 'publish' ".
"ORDER BY post_date $order";
$results = $wpdb->get_results( $query );
ob_start();
$current_month = '';
foreach( $results as $result ) {
if( $current_month != mysql2date('F Y', $result->post_date)) {
if( $current_month ) echo '</ul>';
$current_month = mysql2date('F Y', $result->post_date );
echo '<h2>'.$current_month.'</h2>';
echo '<ul>';
}
echo '<li>';
echo ($date_prefix ? mysql2date('M j: ', $result->post_date) : '');
echo '<a href="'.get_permalink($result->ID).'">';
echo $result->post_title.'</a></li>';
}
if( $current_month ) echo '</ul>';
if( $display ) {
ob_end_flush();
} else {
return ob_get_clean();
}
}
?>