In a Genesis site that I am currently developing, there is an “Archive” page whose design looks like this:
I could have simply hard-coded the images and the years and be done with the page in about 15 min. But I’ve decided to complicate things for myself and spent half a day making it dynamic i.e., the image would be the featured image of the latest post for each year which is below the image. So this means we should first obtain all the unique years that the posts have been published in and for each of those years, get the latest post and pull its featured image.
There are at least three ways in which this can be done.
Approach 1
Store the output of wp_get_archives()
in a variable which is going to contain the HTML markup of unordered list with linked years. Then explode the variable by </li>
tag, replace <li>
s, line breaks etc. with null, get rid of the anchor markup around the remaining years to obtain an array containing the year numbers. Then write a for loop each for each of the years having a WordPress query to bring 1 latest post while passing the year to year
query parameter. In the loop part, we get the image and display it with the year below it.
Approach 2
Create an empty variable for “old year”, write a WordPress query that loops through all the posts in the database and for each post, store the current post’s published year in a “new year” variable, check if the new year and old year are the same and if not, print the image and the year, replace the old year with the new year.
Approach 3
Check the year of the oldest (first) published post manually and write a for loop that loops from that year to the present year and displays the image and the year.
Approach 1
page-archive.php:
<?php
add_action( 'genesis_entry_content', 'sb_archive_content' );
/**
* Add the featured image of latest post for each unique year posts are published in, below existing entry's content.
*/
function sb_archive_content() {
echo '<div class="yearly-archives"><ul>';
$args = array(
'type' => 'yearly',
'echo' => 0, // return and not echo.
);
$archives = wp_get_archives( $args );
$archives = explode( '</li>', $archives );
$years = array();
foreach( $archives as $year ) {
$year = str_replace( array( '<li>' , "\n" , "\t" , "\s" ), '' , $year );
$year = preg_replace( array( '"<a href(.*?)>"', '"</a>"' ), array( '', '' ), $year );
if ( '' != $year ) {
$years[] = $year;
}
else {
continue;
}
}
foreach( $years as $year ) {
$args = array(
'posts_per_page' => '1',
'no_found_rows' => true,
'year' => $year,
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
echo '<li class="' . $year . '">';
$query->the_post();
if ( has_post_thumbnail() ) {
// store the URL of featured image.
$image_url = genesis_get_image( 'format=url&size=circular-image' );
} else {
// a placeholder.
// $image_url = 'http://lorempixel.com/203/203';
$image_url = get_stylesheet_directory_uri() . '/images/default-circular-image.png';
}
// get the alt text of featured image.
$thumb_id = get_post_thumbnail_id( get_the_ID() );
$alt = get_post_meta( $thumb_id, '_wp_attachment_image_alt', true );
// if no alt text is present for featured image, set it to entry title.
if ( '' === $alt ) {
$alt = the_title_attribute( 'echo=0' );
}
// display the image.
printf( '<figure class="year-image"><a href="%s"><img src="%s" alt="%s" /></a></figure>', get_bloginfo( 'url' ) . '/' . $year, $image_url, $alt );
// display the year.
printf( '<div class="year"><a href="%s">%s</a></div>', get_bloginfo( 'url' ) . '/' . $year, $year );
echo '</li>';
}
} else {
// no posts found
}
// Restore original Post Data
wp_reset_postdata();
}
echo '</ul></div>';
}
genesis();
Approach 2
page-archive.php:
<?php
add_action( 'genesis_entry_content', 'sb_archive_content' );
/**
* Add the featured image of latest post for each unique year posts are published in, below existing entry's content.
*/
function sb_archive_content() {
echo '<div class="yearly-archives"><ul>';
$args = array(
'nopaging' => true,
'posts_per_page' => '-1',
);
$query = new WP_Query( $args );
$year_old = ''; // assign $year_old to nothing to start
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
$year_new = get_the_time( 'Y' ); // get $year_new in Year format
if ( $year_old != $year_new ) { // run the check on $year_old and $year_new, and output accordingly.
echo '<li class="' . $year_new . '">';
if ( has_post_thumbnail() ) {
// get the URL of featured image.
$image_url = genesis_get_image( 'format=url&size=circular-image' );
} else {
// a placeholder.
// $image_url = 'http://lorempixel.com/203/203';
$image_url = get_stylesheet_directory_uri() . '/images/default-circular-image.png';
}
// get the alt text of featured image.
$thumb_id = get_post_thumbnail_id( get_the_ID() );
$alt = get_post_meta( $thumb_id, '_wp_attachment_image_alt', true );
// if no alt text is present for featured image, set it to entry title.
if ( '' === $alt ) {
$alt = the_title_attribute( 'echo=0' );
}
// display the image.
printf( '<figure class="year-image"><a href="%s"><img src="%s" alt="%s" /></a></figure>', get_bloginfo( 'url' ) . '/' . $year, $image_url, $alt );
// display the year.
printf( '<div class="year"><a href="%s">%s</a></div>', get_bloginfo( 'url' ) . '/' . $year_new, $year_new );
echo '</li>';
}
$year_old = $year_new; // update $year_old.
}
} else {
// no posts found.
}
// Restore original Post Data.
wp_reset_postdata();
echo '</ul></div>';
}
genesis();
Approach 3
page-archive.php:
<?php
add_action( 'genesis_entry_content', 'sb_archive_content' );
/**
* Add the featured image of latest post for each unique year posts are published in, below existing entry's content.
*/
function sb_archive_content() {
echo '<div class="yearly-archives"><ul>';
$currentyear = date( 'Y' );
$years = range( $currentyear, 2015 ); // change 2015 to the year first post was published in.
foreach( $years as $year ) {
$args = array(
'posts_per_page' => '1',
'no_found_rows' => true,
'year' => $year,
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
echo '<li class="' . $year . '">';
$query->the_post();
if ( has_post_thumbnail() ) {
// store the URL of featured image.
$image_url = genesis_get_image( 'format=url&size=circular-image' );
} else {
// a placeholder.
// $image_url = 'http://lorempixel.com/203/203';
$image_url = get_stylesheet_directory_uri() . '/images/default-circular-image.png';
}
// get the alt text of featured image.
$thumb_id = get_post_thumbnail_id( get_the_ID() );
$alt = get_post_meta( $thumb_id, '_wp_attachment_image_alt', true );
// if no alt text is present for featured image, set it to entry title.
if ( '' === $alt ) {
$alt = the_title_attribute( 'echo=0' );
}
// display the image.
printf( '<figure class="year-image"><a href="%s"><img src="%s" alt="%s" /></a></figure>', get_bloginfo( 'url' ) . '/' . $year, $image_url, $alt );
// display the year.
printf( '<div class="year"><a href="%s">%s</a></div>', get_bloginfo( 'url' ) . '/' . $year, $year );
echo '</li>';
}
} else {
// no posts found
}
// Restore original Post Data
wp_reset_postdata();
}
echo '</ul></div>';
}
genesis();
Sample CSS:
.page-archive .content .entry {
padding-bottom: 20px;
}
.page-archive .entry-content ul > li {
list-style-type: none;
}
.yearly-archives {
margin: 40px 0;
}
.yearly-archives ul {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
margin-bottom: 0;
margin-left: 0;
-ms-flex-pack: distribute;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
justify-content: space-around;
}
.yearly-archives li {
width: 33.33333333%;
text-align: center;
}
.yearly-archives li:last-child {
margin-right: auto;
}
.year-image img {
width: 203px;
border: 3px solid #ffe131;
border-radius: 50%;
vertical-align: top;
-webkit-transition: all 0.4s ease-in-out;
transition: all 0.4s ease-in-out;
}
.year-image a:hover img {
-webkit-transform: scale(1.04);
transform: scale(1.04);
}
.year {
margin-top: 10px;
}
.year a {
color: #464646;
font-size: 18px;
}
.year a:hover {
color: #c3251d;
}
@media only screen and (max-width: 1200px) {
.yearly-archives ul {
flex-direction: column;
-webkit-box-direction: normal;
-webkit-box-orient: vertical;
-ms-flex-direction: column;
}
.yearly-archives li {
margin-bottom: 40px;
}
.yearly-archives li:last-child {
margin-bottom: 0;
}
}
References:
https://codex.wordpress.org/Function_Reference/wp_get_archives
http://www.stemlegal.com/strategyblog/2011/wordpress-wednesdays-better-archive-lists-in-wordpress/
http://callmenick.com/post/create-a-wordpress-custom-archive-page
Which approach is the most efficient (least queries, fastest)?
According to Query Monitor, these are the number of database queries for the three methods respectively:
74
70
73
You can install that plugin to get more info like Page generation time and Database query time for each method.