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 ;)

Chat Dérive: I Ran in to Someone on the Web

Something odd happened to me today. I ran into a complete stranger on the Internet.

I signed into chat, and almost immediately had the conversation below with someone I didn’t know, going by the handle “toweringcoho”. I was at a largish gathering and had bonjour turned on as usual, so assumed it was someone in the room—even though I didn’t bother to look to see what chat connection toweringcoho was using.

A quick Google search suggested that “toweringcoho” is the name of one of a series of IM bots that randomly connect to otherwise unconnected chat users.

And that’s how I met Sunil Khiatani from Hong Kong. It took a while for both of us to figure out that we were NOT talking to robots, and a bit longer to introduce ourselves. In the end, we had a worthy conversation, got to know each other a bit, and went on our ways.

I’m not sure if these IM bots are supposed to be malicious, but I liked what happened. It was like going on a kind of unintentional dérive in text only.

6:45:55 PM toweringcoho: Hi, Billy Mays here with another fantastic coho.
6:46:40 PM Nate Angell: wish I knew what that meant…
6:46:52 PM toweringcoho: hmmm
6:46:59 PM toweringcoho: take a wild guess
6:47:04 PM Nate Angell: salmon?
6:47:23 PM toweringcoho: you definitely aren’t turing complete
6:47:39 PM Nate Angell: human error
6:48:06 PM toweringcoho: are you related to skynet?
6:48:51 PM Nate Angell: maybe on the distaff side
6:49:14 PM toweringcoho: ahh
6:50:01 PM toweringcoho: here’s the thing though, will skynet be porgrammed with the 3 robot laws and if so would it still be able to nuke us?
6:50:28 PM Nate Angell: did the 3 robot laws really work out? have to refer to the text
6:50:54 PM toweringcoho: dunno about the text, but in the movies they didn’t
6:51:55 PM Nate Angell: isn’t the book always better than the movie?
6:52:21 PM toweringcoho: naw
6:52:28 PM toweringcoho: fight club is better movie wise :D
6:53:22 PM Nate Angell: didn’t read fight club
6:55:24 PM toweringcoho: so who are you? :P
6:55:41 PM Nate Angell: @xolotl
6:55:56 PM toweringcoho: huh?
6:56:11 PM Nate Angell: you definitely aren’t turing complete
6:56:30 PM toweringcoho: yeah yeah
6:56:57 PM Nate Angell: that should be enough to go on
6:57:20 PM toweringcoho: naw it isn’t
6:57:45 PM Nate Angell: there’s this thing called google…
6:58:15 PM toweringcoho: nad what should I be searching for
7:01:19 PM Nate Angell: @xolotl
7:01:34 PM Nate Angell: it’s a pretty unique character string
7:02:31 PM toweringcoho: you’re nate angel?
7:03:23 PM Nate Angell: no, I’m Nate Angell
7:04:05 PM toweringcoho: ah close enough
7:04:08 PM Nate Angell: or, perhaps A dog-like deity, Double of Quetzalcoatl
7:04:10 PM toweringcoho: how come you’re contacting me :P
7:04:25 PM Nate Angell: you contacted me
7:04:48 PM toweringcoho: I did???
7:05:10 PM Nate Angell: I think there’s an AIM chat robot that connects random users
7:05:14 PM Nate Angell: and we are victims
7:05:30 PM toweringcoho: ahhh
7:05:36 PM toweringcoho: strange
7:05:58 PM toweringcoho: thi is my yahoo account though
7:07:41 PM Nate Angell: i think they are all connected
7:07:52 PM Nate Angell: so you know me, want to iintroduce your self?
7:08:16 PM toweringcoho: alright
7:08:27 PM toweringcoho: I’m Sunil Khiatani, I’m a coder in Hong Kong :D
7:08:37 PM Nate Angell: very cool
7:08:40 PM Nate Angell: what do you code?
7:08:56 PM Nate Angell: Sunil Khiatani doesn’t sound very HK ;)
7:09:21 PM toweringcoho: at the moment, stuff for work. Web Services in ASP.NET and C# :\
7:09:30 PM Nate Angell: sorry
7:09:33 PM toweringcoho: been trying to do OSS coding but I’ve been lazy
7:09:41 PM Nate Angell: that would be better!
7:09:53 PM Nate Angell: as you may have learned, I’m a bit of an OSS zealot
7:10:22 PM toweringcoho: haha yeah a lot of people freak out when I tell them that I’m an indian born in Hong Kong that has a fairly american accent
7:10:31 PM toweringcoho: yeah I think I did, what do you code ?
7:10:34 PM Nate Angell: i guess HK has all types
7:10:36 PM toweringcoho: bbs.. loo
7:10:50 PM Nate Angell: I’m not much of a coder
7:11:13 PM Nate Angell: but I usually evangelize around http://sakaiproject.org http://drupal.org and http://openid.net
7:11:35 PM Nate Angell: there are many worthy projects, depending on your interests
7:11:50 PM Nate Angell: I encourage you to broaden your skills/interests with OSS
7:16:25 PM toweringcoho: I have a few interests
7:16:46 PM toweringcoho: but i think I should focus on the KDE desktop, it’s waht i like and use the most
7:19:26 PM Nate Angell: that’s a worthy project

Thought Experiments for Sakai: Keep It Simple Like Twitter & Draw Good Boundaries Like Drupal

I admit I’ve been lurking in a very slackernly manner in all the discussions in the Sakai community about content authoring, 3akai, UX, K2, Sakai NG and other unpronounceables, so I’m sorry if all this is a day late and a dollar short. Feel free to ignore me if you’re part of Sakai and are way too far gone for any more input. After all, these are just thought experiments ;) If you’re not part of Sakai, you might learn something about Drupal at least, so it may well be worth your time.

I draw some lessons here from Twitter and Drupal not to suggest that Sakai duplicate them, but rather that we hold those models in mind as we move Sakai forward. Even without these experiments, some of these ideas may be in our thinking about Sakai, so if they are familiar, take it as a vote of confidence. But if not, I’d like us to have at least thought through why we would not take them as inspiration or why we would choose another path.

In the lessons I draw from Twitter and Drupal below, I may come off as a bit of a zealot. Frankly, I have a greater appreciation for Twitter and Drupal as tools that I have for Sakai as a tool—my greatest appreciation for Sakai has always been for its community. But I would like to appreciate Sakai-the-tool as much or more than Twitter and Drupal, and I think I could, given the directions I see Sakai heading now.

But why Twitter and Drupal? When I’m thinking about all this Sakai stuff, my first thought is to reach for existing models. And the models I reach for are the handy ones. Why? Because there must be some reason I keep certain tools handy. There are lots of good tools, but the ones that fit so comfortably in my hand are well-worn for a reason. I also know them well—keen edges and ugly nicks—and so can draw the best lessons from them.

For those of you who live under rocks, Twitter is a microblogging and social networking service that has gotten a bit of press lately. A lot of people are using Twitter, and a lot of people don’t get it at all. If you already use Twitter, great. If you don’t get it, that’s OK. You don’t need to “get” Twitter to learn its lesson. There’s only one, it’s pretty big picture, and you won’t have to tweet about doing your laundry or hear about mine just because you read about it.

Drupal is a mature web content management system/application toolkit, currently at version 6.10, with a very vibrant international community and strong commercial ecosystem. About 1,400 people attended the most recent DrupalCon in Washington DC.

Keep It Simple Like Twitter

Keep it simple. Open it up. Let the complexity come from everywhere.

John Ellis has kidded that Twitter has become so popular mostly because it is so easy to make new words that start with “tw”: twavatar, tweeple, tweetup, twistory, etc, and if you haven’t heard them all, check out the twictionary: http://twictionary.com

I think John’s almost right. It’s about the simplicity and what people do with it. I think Twitter’s rise has a lot to do with their focus on keeping it simple: 140 character posts, direct, addressed, or pure statement, public/private, following/followers, search. Twitter keeps it simple and—just as importantly—offers a public API that lets the world layer an almost unfathomable and—to the Twitter team I’m sure—unimagined variety of interfaces, uses and extensions based on Twitter’s simple service.

In other words, Twitter knew what it was doing, but it didn’t expect that what it was doing was all that could be done.

Neither can Sakai. Looking ahead: we should focus, keep it simple, do it well, and open it up, so that everything we can’t yet imagine can hang off our work.

Draw Good Boundaries Like Drupal

One of the most crucial decisions for any information machine is to decide how specific it wants to be and where it will draw boundaries around what it will do.

Every piece of software I’ve been involved with seems to follow the same general development pattern: In the beginning, software is built to meet specific needs in a certain context. As more needs are layered on over time, the software becomes either more cluttered or more generalized—or both—and gets rather messy. No one knows anymore exactly what it is for or where its boundaries are, but we end up tethered to it in all its messy complexity.

Take MS Word, which is both highly generalized (name something you CAN’T do with Word) and overly cluttered (you have to manage the TOOLBARS in Word). At this point, Word is really neither a great word processor nor is it powerful enough to be our main content management interface. And yet we use it for both. We are stuck to this big, messy machine and we can’t get loose (assuredly, there are also some other, non-technical reasons we are stuck to Word).

Sakai also started out meeting specific needs. And over time, Sakai too has become rather cluttered. Now it seems we are clearly at a turning point where we want to generalize. I think our success will depend on where and how we map Sakai’s boundaries as we clean things up. Drupal provides an instructive model in the cartography of information machines.

Caveats: There are other models that might be just as instructive. Drupal is just the piece of software I know best that, in my opinion, matches Sakai’s stature and has done a good job defining itself as an information machine. There are also many valid criticisms of Drupal. For example, I would never argue that Drupal’s user interface is ideal. The lessons I think Sakai can take from Drupal are at a deeper, architectural level.

First, like Twitter, Drupal has done a good job of drawing boundaries around what should be core and what should be left outside. Drupal core is pretty clean, focused on key, common functions. Meanwhile, in Drupal’s contribution space and beyond, it is rather messy. That is exactly as it should be. Good stuff comes out of that mess and some of it makes its way into Drupal core when the time and scope is right. Other stuff outside is fully mature and absolutely essential—for some. And for that reason, it will never become core, which is exactly as it should be. Core should not be defined by maturity, but by generality. There are a lot of ways that the Drupal community works to support both high innovation in the periphery and healthy boundaries at the core. Sakai should think carefully about where we put our borders and how we will support work inside and out.

Second, Drupal has done a good job of generalizing, focusing and simplifying its core functionality, and making core functions easily available to peripheral tools. If you do it right, all you need to build into a Drupal module is the specific functionality you need…everything else is a call to core. This makes it incredibly easy and quick to add functionality to Drupal—which fosters innovation—and also ensures that contributed modules participate fully in the larger Drupal machine. As we collaborate to define and build Sakai’s next generation, we should look to mature models like Drupal that have a head start on clarifying and exposing core functionality.

Those are the general lessons I draw from Twitter and Drupal, so if you’ve had enough, you can stop reading here. Following are some more specific examples I draw from Drupal that relate to some of our recent discussions in Sakai.

Content

Drupal starts with the idea that (almost) everything is a piece of content, starting from the same place on a conceptual and technological level as a “node.” In Drupal, you augment the structure and/or functionality of these generic nodes by “decorating” them with additional structured data fields, workflow, etc. This way, all Drupal core has to concern itself with is the common structure (eg, common metadata like author, creation timestamp, etc) and common functionality (eg, access, CRUD, versioning, validation, input, etc) of nodes. More specific structure and/or functionality gets layered onto the basic node either through generic admin interfaces (eg, the Content Construction Kit, or CCK) or more tailored modules that make specially augmented nodes for specific purposes.

Want to create an event record? Create a new “event” content type, add a timestamp field that uses a mini-cal data entry widget. Click, click, done. Add location? Just decorate your event content type with a location field—oh, and then you’ll have all the magic of a host of map integration modules at your disposal. Click, click, done. Want your events to link to location profiles? Create a separate “location” content type and add a node relation field to your event content type to link each event to a profile of its location. There, you just built a dynamic event web application in 15 minutes without calling your code monkey.

Another key Drupal module—Views—provides a generic query and output service for content. Need a table listing of all content meeting certain parameters, paginated in groups of 25 with sortable columns? Click, click, done. Want to offer that same content as a feed? Click, click, done. Want some completely different bucket of content, organized and presented in some other way? Again, click, click, done—and almost always with no coding required.

By generalizing core content in this way, Drupal handles it all consistently, but at the same time makes it easy to customize content for even the most complex needs—often with no coding required. Is it so easy faculty could do it? Maybe not without training, but you may not want end-users defining new content types willy nilly anyway. What the Drupal model offers is a way to lower the bar for meeting specialized content needs to a level that they can be met in minutes by someone with only a bit of training: a faculty power user, instructional designers, help desk staff, student assistants—crikey, even I can do it. Also, did I mention that Drupal content type definitions are exportable? Yes, you can define, export and share specialized content types.

Drupal understands that content creation and display is a core function, but it doesn’t expect to know what YOUR content needs to be. Sakai would benefit with generalizing its content handling to Drupal’s degree. As educators, we may feel that we are well-placed to define what a syllabus, a quiz, a discussion, a lecture podcast, or a portfolio should be. But as technologists, we will serve all the unforeseen ideas for what educational content might be far better by designing a solid, general framework on which our current—and future—ideas can be made manifest.

Taxonomy

From the start, Drupal anticipated that taxonomy—which is just a fancy word for categorization or tagging—was an essential core function. Drupal enables you to define any number of category vocabularies, each having special characteristics (eg, freetagging, hierarchy, etc), each holding any number of terms, and each related to whatever specific content types you desire. Thus any content in Drupal can be categorized in multiple ways, with highly structured categories or freetag folksonomies—or both—for different purposes. Good stuff is baked into core, like returning content matching various categories by simply including boolean queries in the URL.

Following the model I’ve been stressing of core simplicity enabling unanticipated innovation, Drupal modules make use of the basic, core taxonomy service to do all sorts of unexpected things, like category-based access control, or category-based organic group creation and management. With taxonomy as powerful as Drupal’s baked into core, Sakai too could enable all sorts of things that we may not have yet imagined.

Theming

Drupal’s core presentation layer is the icing on the cake, which is exactly what presentation should be: icing. There’s nothing worse than finding presentation baked into deeper levels of software, where it’s static and hard to change. Drupal handles presentation as the final layer, enabling design to be very flexible and easy to modify. Want every user to be able to choose between three entirely different designs? Just load three themes and let the users choose for themselves. Need to offer a mobile version of your site? A dedicated mobile URL and/or some user agent sniffing can automatically deliver a theme optimized for mobile devices—oh, and there’s a module that does all that for you (something you’ll find again and again in Drupal). Need that new content type you just made to look different than every other piece of content on your site? Drop a custom theme template named for that content type in your theme’s directory and your generic theme gets overridden automatically with your custom design—just for that special case.

The power of this theming model came when Drupal core stopped worrying about what the perfect presentation should look like and instead offered a way to deliver ANY presentation predictably with easy-to-build templates. In Sakai, the same power and flexibility would take us past the question of what Sakai SHOULD look like to the simple answer: Sakai looks like whatever you want it to look like.

Layout

Our next-generation Sakai authoring experiments are delivering some juicy tools to place different pieces of content and widgets in different parts of a page. Drupal offers two models that may help us refine the good work we’re already doing.

Drupal core has long had the concepts of regions and blocks. Regions are areas of a page defined by a theme. A theme can have any number of regions laid out in any way. Blocks are bite-sized content or functionality: anything from a static welcome message, to a listing of recently updated content, to a user log in form. Blocks can be created individually by users or made available programmatically by Drupal core or contributed modules. Drupal core offers tools to map blocks to different page regions, and customize the visibility of blocks based on almost anything: user role, content type, authentication status, URL patterns, etc.

Drupal’s region and block system is very flexible, but it is better suited for site administrators to define global page layouts than it is for individual users to author custom pages with varied content as we have been imagining in Sakai.

Panels is a module outside Drupal core that comes closer to what we’ve been imagining in Sakai: the ability for an individual user to place content and/or widgets exactly where they want on an individual page. Unfortunately, the authoring experience in panels is not anywhere near the kind of intuitive WYSIWYG experience we have been working toward in Sakai. However, Drupal panels offers all the ingredients we might want in a page authoring experience…we just need to cook and serve them differently.

I take several lessons for page authoring in Sakai from what works well in Drupal’s layout tools of regions, blocks and panels. When laying out a page in Sakai, we should be able to choose from:

  • A library of predefined layouts, offering good, commonly-used page structures. Some of these layouts could be merely structural—empty containers waiting for me to fill them—defining something like Drupal’s page regions (eg, a typical three-column layout with header and footer). Others could combine some empty regions for me to fill, along with other regions already filled with existing widgets (eg, a big, empty body region with a sidebar that has calendar, discussion and tagcloud widgets already in place). We should be able to export and import these predefined layouts. I should be able to tag layouts and see/browse tags from other users—but one should be able to tag everything in Sakai, so we don’t ever need to state this requirement again, right?
  • The opportunity to author a new, custom layout, where I can design whatever structure I want. I should be able to tag, export and share my custom layout.
  • A library of widgets—not unlike Drupal blocks—that deliver either content or functionality. I should be able to search and browse global widgets supplied by the system, my own widgets, and ideally, widgets authored by other users I’ve subscribed to. I should be able to tag widgets and see/browse tags from other users.
  • The opportunity to author a new widget on the spot, thereby adding it to both the page I’m authoring right now and my widget library for use elsewhere. Making a new widget might be like making a view in Drupal: the ability to make some selection of content and display it in some form (eg, table, list, feed, etc). Making a new widget might be like something else too. Like Drupal, Sakai should offer new tools the opportunity to supply new widgets—and/or the opportunity for users to author new kinds of widgets.
  • The opportunity to author a piece of content on the spot, thereby adding it to both the page I’m authoring right now and whatever other collections that specific kind of content happens to live within (eg, pages, syllabi, tests, forum topics, etc). Like modules in Drupal, new tools in Sakai that define content should end up offering the chance to author in Sakai’s standard authoring environment.
  • The opportunity to define under what circumstances a given layout/widget/content piece is visible. As in Drupal, I should be able to define who can see something and when they can see it. Default visibility should be baked into predefined layouts, widgets and content. And if I have the right access, I should be able to override default visibility.

Pluggable Authoring Tools & Filters

Drupal offers flexible frameworks for modules to supply different ways to get content in and spit it back out. While Sakai has been wedded to the oft-maligned FCKeditor for some time (yes, all the WYSIWYG tools have their drawbacks), Drupal offers the ability to plug in almost any authoring tool: plain old text, different WYSIWYG/WYSIWYM editors, various markup formats, etc. At the same time, Drupal offers the ability to define output filters that can clean up and/or enhance stored content when it is rendered. Drupal’s filter on output strategy allows the same content (stored raw in the database) to be transformed differently depending on what filters are in use (which can even depend on user role or preference). Want anonymous users to see all your content translated into Pirate talk? Done. Again, Drupal core is not determining how stuff gets in and out, it instead provides a pluggable framework so we can decide for ourselves what we need. So many of Sakai’s usability issues revolve around the rigidity of input and output, we would do well to adopt a pluggable model which opens possibilities beyond what we can anticipate.

URLs

Unfriendly to humans and search engine robots alike, Sakai has some of the ugliest URLs ever. It makes sense for a web application to have canonical URLs and it’s hard to make them friendly, but there’s no reason to show them to the world. Drupal solves the ugly URL problem by offering a core service for URL aliasing, so users themselves can define better URLs for their content. A valuable contributed module—pathauto—allows site administrators to define automatic URL aliasing rules for different canonical URLs, thus saving authors the aliasing task and enabling more structured aliasing patterns. Again, the lesson for Sakai is to fix our problems by offering flexible options rather than trying to bake in the final solution.

Workflow

Drupal core has basic workflow baked in based on triggers and actions, where triggers are set to fire on certain events, in turn generating specific actions. For example, a workflow can be established to email a site owner (an action) every time new content is posted (a trigger). Once again, instead of providing all the ideal workflows we might imagine, Drupal provides a generic tool to build workflows, which we can use to build those we already know we need, as well as those we don’t yet know we need. If only Sakai’s sometimes idiosyncratic workflows were merely defaults, which I could change or replace as easily as I can in Drupal.

Installation Profiles

Many parts of Drupal can be exported/imported (eg, content types, views) or are modular (eg, modules, themes, filters) to allow for easy sharing and migration. One of the Drupal’s most powerful tools is the installation profile: an automatic recipe to build a new Drupal site. Installation profiles set modules, themes and other configuration options when Drupal is first installed so you can distribute a pre-packaged Drupal recipe, optimized for specific purposes. If Sakai had installation profiles like Drupal, I could imagine distributions for different organizational types (K-12, community college, liberal arts college, research university, etc), different usage focuses (collaboration, portfolios, teaching and learning), or different languages, giving new adopters better starting places than a generic Sakai installation. As Sakai generalizes itself, we should also have a way to demonstrate and distribute best practices for specific uses.

Other Stuff

There are many other (smaller) lessons Sakai might take from Drupal. Some that come to mind include:

  • The core form API that lets modules safely offer forms with minimal work and modify others (including core forms) dynamically as needed.
  • The core multisite functionality that allows Drupal to run multiple sites from the same codebase, yet override and/or augment any part of any site as needed.
  • The core comment functionality that lets any piece of content include threaded comments.
  • The core support for automatic feeds.
  • The core menu functionality that allows navigation to be managed as its own kind of content.
  • Core support for OpenID authentication.
  • Sophisticated core caching mechanisms.

Finally, a Shout Out to Portfolios

Oddly enough, the part of Sakai that most reminds me of Drupal’s generality is our portfolio toolset. It’s not surprising that portfolios—maybe the least well-defined practices in teaching and learning—have led to the most generalized tools in Sakai. And yet, the most obvious complaint about Sakai portfolio tools is that they don’t do anything at all. The fact is: Sakai portfolios can do almost anything. What’s missing in portfolios is the easy tools to build them and the portable models to demonstrate their power. Sakai would do well to look inside to its portfolio tools—for inspiration to generalize, but also for caveats about what must be in place to make generalized tools usable and practical.

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 Wins 2008 Webware 100 Award

For the second year running, Drupal placed in the Webware 100 awards in the Publishing & Photography category.

In this publishing category, the only other contender in the top 10 that comes close to matching the flexibility and functionality of Drupal was WordPress, which would probably do well to continue to focus on the blog niche and not try to play catch-up with the more mature Drupal (current versions: Drupal 6.2, WP 2.5). Missing altogether were projects that match up better with Drupal, such as Joomla and Plone.

Check out all 10 winners: