When I first started this blog, I used Drupal’s built in jQuery library to randomly show a picture in my header from a stockpile I put on my webserver. It worked great, but it was a manual process: selecting the pictures, sizing & cropping them, uploading them, etc. In the end, I rarely added any new pictures because it was a hassle.
I had long wanted to try something more automated and show a wider variety of more current pictures on my blog. The goal: automatically show selected pictures from my flickr stream with no extra steps other than posting to flickr and maybe adding a special tag.
Finally, the images you see in my header are randomly shown from a set provided automatically from my flickr stream and are automatically cropped and sized. All I have to do to add a new image to my site header rotation is add one extra tag to a picture when I upload it to flickr.
Here’s the Drupal technology I used to make this possible. FYI: everything is done with stock Drupal core and contributed modules…absolutely no coding required!
- Create a special page type for images: I use some basic cck modules to create a special page type on my blog to display images and related information about them.
- Sync with flickr: I use the flickrapi and flickrsync modules to automatically download any new images I put in my flickr stream. Flickrsync syncs the images automatically on a schedule I determine via Drupal’s stock cron process. Each new image downloaded from flickr creates a new image page and the title, description and tags from flickr are added to the page along with the image. I download all my flickr images, including the ones marked with a special tag to show them in my header.
- Size and crop the images: I use the imagecache module to automatically size and crop a copy of each image so they fit perfectly in my header. The automatic process doesn’t always work perfectly…I might size and crop differently if I did it myself. But it often works well and sometimes even comes up with interesting, surprising results. Best of all: I don’t have to do it ;)
- Display images randomly in the header: I use the indispensable views module to create a special view of the image pages created in the steps above that shows just one random image a random selection from only those images marked with the special image tag and displays the copy of the image copies of the images cropped and sized specifically for my header.
As an added benefit, I end up with a lifestream-style copy of all my flickr images on my blog, which I can also use as a dashboard to find images and change tags if I want to override the tags I’ve set in flickr itself (eg, to add or subtract an image from the header rotation).
Now with Dynamic Rotation
Thanks to an experiement I undertook for my review of Matt Butcher’s excellent Drupal 6 JavaScript and jQuery book, I’ve now come full circle and used jQuery to add dynamic rotation to my header images. Here’s how I did it.
First, I made a small adujstment to the view I created in step 4 above to have it return more than just one randomized image. You can adjust the view to return whatever number of randomized images you want by changing only the value for “items to display”.
Then, I modified a the sticky_rotate.js example code Matt supplied with his book to affect my header images rather than the original sticky node teasers. I actually simplified the code because all my header images are the same height, so I could remove his code that calculated the tallest teaser. I mostly just changed the function and variable names to pertain to my use case. You can see my header_rotate.js script below and for a full explanation of what’s going on, you should just buy Matt’s book, because it’s money well spent.
Finally, I just put my new header_rotate.js file in my theme folder and modified the theme.info file to include this new script
Voila! My header images now rotate dynamically with an adjustable delay and a nice fade feature. I’m sure something more sophisticated is warranted (like loading the images as needed via ajax or something more clever), but I was happy to have this small demonstration of Drupal and jQuery’s simplicity and power after only a few minutes work.
// $Id$ /** * Rotate through all header images returned by view, * using jQuery effects to display them. * * Based on StickyRotate from Drupal 6 Javascript & jQuery * Chapter 3, by Matt Butcher * http://www.packtpub.com/drupal-6-javascript-and-jquery/book */ // Our namespace: var HeaderRotate = HeaderRotate || {}; /** * Initialize the header rotation. */ HeaderRotate.init = function() { var headerImages = $(".view-header-rotating .views-row"); // If we don't have enough, stop immediately. if (headerImages.size() <= 1) { return; } headerImages.hide().css('height', '100px'); HeaderRotate.counter = 0; HeaderRotate.headerImages = headerImages; headerImages.eq(0).fadeIn('slow'); setInterval(HeaderRotate.periodicRefresh, 7000); }; /** * Callback function to show a new header image. */ HeaderRotate.periodicRefresh = function () { var headerImages = HeaderRotate.headerImages; var count = HeaderRotate.counter; var lastHeaderImage = headerImages.size() - 1; var newcount; if (count == lastHeaderImage) { newcount = HeaderRotate.counter = 0; } else { newcount = HeaderRotate.counter = count + 1; } headerImages.eq(count).fadeOut('slow', function () { headerImages.eq(newcount).fadeIn('slow'); }); }; $(document).ready(HeaderRotate.init);
To get the images to load dynamically, I’ve recently jettisoned my own jQuery experiment above in favor of the most excellent Views Slideshow module.
All I had to do after installing and enabling the module was change the header block generated by the view I’d already made (above) to use a slideshow style, and then make some slideshow settings choices.
That’s what I get for trying to do it on my own ;) Goes to show you with Drupal: the next time you look, someone has made a module that does exactly what you want, and more.
You might be better off using views to rewrite the output, giving each image apart from the first one a special css class that will ‘display: none;’ the images by default. Every time I go to a new page on your site, I get a flash of every image over the top.
I see this flash as a problem too, and was thinking how to fix it.
One issue is the js I’m applying does apply “display: none;” to all the images, but only after the whole document is loaded. Are you saying if I apply it in the view, it will be applied before the document loads?
I’d appreciate any pointers you may have.
That is a dope solution. Nice work.