Open-Source Publisher Packt Reaches 1000th Title

Book cover: Sakai CLE Courseware Management: The Official GuidePackt, publisher of many worthy books about technology topics that have helped me know what I’m doing, is about to publish their 1000th book.

Many Packt titles, such as Sakai CLE Courseware Management: The Official Guide, books on Drupal, and jQuery have been my guides to the open-source technologies I use every day.

To celebrate, Packt is giving away gifts to their readers who register before 30 September 2012 over at Packt.com.

Thank you Packt, and congratulations!

Drupal 6 JavaScript and jQuery

Drupal 6 JavaScript and jQuery CoverI just finished reading a new book, Drupal 6 JavaScript and jQuery, by Matt Butcher. The book title makes it sound highly specialized, but in fact it’s a great resource for a variety of readers, from Drupal beginners to JavaScript experts. Best of all, the book brings together two of my favorite open source technologies: Drupal and jQuery. If you aren’t already a fan, I’ve written elsewhere about Drupal’s benefits, and for jQuery, one statement should win you over: query HTML content using plain old CSS selectors!

Matt does a great job leading the reader from very basic principles to advanced concepts, thoroughly enough to initiate less experienced coders, but quickly enough to get everyone to real meat right away. You will get immediate value from this book whether you are a web designer just starting out with Drupal and/or JavaScript, an intermediate coder looking to expand your skills with either Drupal or JavaScript, or an advanced Drupalista or JavaScriptor looking to bring the two together.

Because I reach under the Drupal hood only sporadically, I love how how Matt quickly covers all the basic terminology and functionality of Drupal, JavaScript, and jQuery to remind me how they all work, and work together. I can see turning to this book as a basic reference again and again.

Best of all, in each chapter Matt provides a hands-on project worth doing for it’s own sake as well as for the added learning. Trying it out, I modified the rotating sticky node teasers project in Chapter 3 to complete something I’ve been wanting to do here on my blog for some time: make my Flickr-stream header images rotate dynamically. Read more about exactly how I did it. If I can do something like this in just a few minutes, that tells you a lot about the power and simplicity of Drupal and jQuery together, and Matt’s ability to make it all understandable.

Ready to dip your toes or delve deeper into how jQuery let’s you “write less, do more” with Drupal? You can buy Matt’s Drupal 6 JavaScript and jQuery book directly from the Packt website.

FYI: I drafted this entire review sitting on an Oregon coast beach using the Evernote iPhone app. Pretty nice working conditions ;)

What Are These Pictures Redux

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!

  1. 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.
  2. 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.
  3. 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 ;)
  4. 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);

Drupal 6.0

I just installed my first Drupal 6.0 version (RC4), which took a total of about 3.5 minutes. You [used to be able to] visit the resulting (minimalist) site.

The new installer worked flawlessly, requiring only establishing a database and user and changing the the access control on a single directory and changing it back again once the install was complete. The rest was answering a few basic questions in Drupal’s web-based installer. Given that the db and file access steps could also be accomplished via a web interface (eg, cpanel on a hosted server), the whole installation process could easily be handled by a non-technical user in the same few minutes it took me.

What’s exciting in Drupal 6? You can check out a complete list, but for me, here are the highlights:

  • OpenID integrated as a core module. My only suggestion here would be to add some administrative controls to toggle various authentication options (eg, only use OpenID or Drupal authentication, prefer OpenID or Drupal authentication, hide password change controls from OpenID users, etc).
  • Workflow actions and triggers integrated as core modules. This demonstrates something I’ve admired most about Drupal: the right functionalities are brought into core as general services/APIs. I haven’t experimented with these yet, but core’s where they belong.
  • The latest jQuery integration. Drupal worked with the jQuery folks to deliver jQuery 1.2.3. This should make for even more jQuery goodness.
  • The update module integrated into core. Now let Drupal tell you when it needs upgrades.

I’ll need to wait until key contrib modules like CCK and Views are ready to test in Drupal 6, but I have every faith that added together, this release will significantly increase the sophistication and power of Drupal.

Meanwhile, there are already even little tweaks to love, like drag and drop reordering of menus and blocks, and hiding the revision log field on the node edit form in a closed fieldset (yes, it would be nice if every user explained every content update they made, but most have no idea what is being asked for in the log).

Stay tuned for more on Drupal 6, and oh, in case you haven’t heard, go to DrupalCon 2008 in Boston!

What’s up with the pictures?

Update

Read my latest post on my image header for how I ended up carrying out this idea.

People have been asking what the deal is with the images in my site header.

I’ve been experimenting with loading random background images from my collection using Drupal’s integrated jQuery tools.

I’ve been thinking about trying to work on having the images feed from a flickr stream, perhaps using the Drupal flickr module, yet be automatically sized/cropped for the site header. More on that if I get to it.

Many of the pictures are of people in my family, or shots I’ve taken around our home or Portland.