I wanted to include one of my photos on the home page of my WordPress website, and I wanted it to be a date-appropriate header image chosen at random, without any further effort on my part. Here’s how I modified my theme to achieve that.
Possible solutions
Previously, I had used Customize – Header image to get somewhat like what I wanted, and it met most of my criteria, without much coding. This would have been fine if I had just wanted a random image. Just load up a bunch of images of the right size and check the box that said randomize headers. But I wanted the images to reflect the season, and header image couldn’t accommodate that. Switching to a different seasonal set was not easy, and so my family site that used this theme has been showing “winter’ scenes since last winter. Like a broken clock, it will soon be right again!
My initial thought was to create a database table which would associate the URL of an image with an earliest date and a latest date. Run a query to find all the hits for today’s date and pick one at random. The downside of this was the need for a UI to maintain the database and a small problem of keeping the database and the images in sync – making sure there were no orphans when either end was added or deleted. I also wanted to make sure the photo compression was done, but that would be solved if I kept the images in the media library. One advantage of this approach was the possibility of having a media server for multiple sites, but the downside was complexity.
Solution using WordPress services
In the end I used a WordPress solution. I would add images (with the right proportions) to the Media library using standard methods, and attach a specific tag to each image. Then I could run a standard WordPress loop to return the url of one image at random from all the images which matched the tag for the current day.
All of the image handling (including compression) is handled with regular WordPress services, and if an image is deleted, nothing else is affected.
Now all that was necessary was to translate the day and month part of the current date into a tag.
Translating today’s date into a tag
This can be done in many ways. In the end, I decided I would not be changing the algorithm very often so I could hard-code it. This is obviously not suitable for anyone providing a theme for a client, but I’m my own client! I also decided that there would be four main categories, Winter, Spring, Summer and Fall, and a very limited number of “special dates”, all of which fell on an unchanging date – so no Easter, for instance.
I was extra lazy, and set the tag in a series of elseif statements and then re-set the tag if it turned out it was a special day, like Christmas. The only bump in the road is winter, because I couldn’t just say it’s winter if the month-day is less than 0301, because 1205 is also winter, and that’s greater than 0301. So I’m testing against seasonal start dates in sequence. As soon as one test is true, control drops out of the if sequence, and if it gets through all the tests, the tag is set to winter, because it is December.
As they say in text books, the more general problem of producing a tag in an environment where religious holidays and other random celebrations need to be catered to is left as an exercise for the student.
Choosing image tag names
I prefixed each special tag with “ban-” (for banner) to reduce the chance of getting an unwanted image showing up.
For Christmas (which I regard as a commercial period) I arbitrarily decided to have a generic image tag for Dec 24 and Dec 26 and a more specific one for Dec 25th. I could also have added a date-period in the elseif code so the early part of December was winter, then a Christmas period and then another winter, but that was getting complicated.
It does occur to me that some images could have two or more tags, so they could show up for any one. You wouldn’t tag a Christmas tree image as winter and have it show up in late February, but having a snowy scene show up for Christmas would not go amiss.
The code
The following code sits in a separate file which is included in home.php just after the header:
<?php
date_default_timezone_set('America/Toronto');
$mmdd = date("m") . date("d") ;
/* Get an appropriate tag, based on today's date */
if ($mmdd < '0301') {$imgtag = 'ban-winter';}
elseif ($mmdd < '0601') {$imgtag = 'ban-spring';}
elseif ($mmdd < '0901') {$imgtag = 'ban-summer';}
elseif ($mmdd < '1201') {$imgtag = 'ban-fall';}
else $imgtag = 'ban-winter';
switch($mmdd) {
case "1224":
$imgtag = 'ban-xmas';
break;
case "1225":
$imgtag = 'ban-xmasday';
break;
case "1226":
$imgtag = 'ban-xmas';
break;
case "0701":
$imgtag = 'ban-july1';
break;
}
/* get a single random image which has the tag $imgtag */
$args = array(
'post_type' => 'attachment',
'post_status' => 'inherit',
'tag' => $imgtag,
'posts_per_page' => 1,
'fields' => 'ids',
'orderby' => 'rand'
);
$image = new WP_Query( $args );
if( $image->have_posts() ){
$image_attributes = wp_get_attachment_image_src( $image->posts[0], 'full' );
echo '<img class="photobanner" src="' . $image_attributes[0] . '" alt="" />' ;
}
wp_reset_postdata();
?>
Conclusion
My solution is fine for my needs. I realize it doesn’t scale well, but I’m presenting it here as concept (a working one, at that) rather than a fully-fledged commercial solution. It is a bit of a pain loading it up with a dozen or so images for each season, but once that’s done it just happily does its job, and deleting or adding an individual image later on is no trouble at all.
My only regret is that putting this functionality into my family website is not as simple as dropping the code into the older theme, or upgrading that theme to my latest one, because I still have to upload 50 or so images and get them tagged. It’s a shame WordPress doesn’t allow media libraries to be shared.
My php is pretty rusty, so I may be violating all kinds of rules or conventions, but this code does work. Hope you find my idea useful.