drupal planet

drupal-javascript-and-jquery.jpg

After reading Drupal 6 Javascript and jQuery (Matt Butcher, Pact Publishing), I gained a new appreciation for writers attempting to expound on a one specific aspect of Drupal development. jQuery, for example, can be used by nearly every layer of Drupal, from module building to theming, from the file system to forms. How does one boil down the many and varied applications of this multi-purpose tool into a reasonably sized book? I think Matt Butcher did a fantastic job of doing just that.

The book was not quite what I expected, and that's a good thing. For one, the author assumed a minimal amount of experience from the reader, and started at square one with some basic terminology and a first 'hello, world' tutorial. Like most tech tutorial books, the chapters are comprised of 1-3 mini projects where some new ideas or techniques are introduced. For the most part, each chapter builds on previous chapters, illustrating more complex functionality. Another thing that struck me from the start and continued to impress me throughout was the quality and creativeness of the example projects. While few of the examples were production-ready, they solved common issues in a compelling way. Here's a quick list of some of the mini-projects:

  • Load an RSS feed via AJAX
  • Create a live in-page alert when new comments are added
  • Create a text editor
  • Create a random, rotating node teasers in jQuery
  • Write a jQuery plugin

A lot of these projects have crossed my mind as things I'd like to dig into at some point anyway. In addition to being interesting ideas, these projects are also executed in a way that brings together many aspects of Drupal. Having used jQuery and Drupal for a couple of years now, I felt like I knew the basics, but I was pleasantly surprised to learn something new in virtually every project. Some things I learned, but didn't expect to:

  • How to use JSON - I've been wanting to wrap my mind around that for a while
  • How to use translations in jQuery
  • What are Drupal behaviors - If you don't know about them now, you absolutely need to! They solve one of the more complex problems I've dealt with in complex jQuery apps
  • How to theme in jQuery - Awesome, I didn't know you could do that
  • Creating jQuery functionality in themes - I had thought this was a purely modular job, but no!

By the time you make it through the book, you've been introduced to all of the major parts of Drupal. If I had known nothing about Drupal from the start, I would come out the other end with the ability to create themes, modules, and jQuery plugins. Not bad for 318 pages, probably half of which is code. And the fact that I was still satisfied even having worked with Drupal and jQuery for the last couple of years says something to the depth of the material covered.

I was excited enough about the new stuff I learned that I picked up a module that had been languishing for a while and re-wrote a bunch of the code using the principles addressed in this book. The code is now a whole lot easier to understand and debug. The 2 major concepts I applied were object oriented javascript and Drupal behaviors. Drupal behaviors is binding jQuery actions to html elements on the fly, so if you load up some new content via ajax, you can then attach all the jQuery stuff to it without affecting the rest of the page (like accidently attaching an action a second time, which can have undesirable consequences). I've found all kinds of ways of dealing with this is the past, and they've all been really ugly in comparison. Behaviors are a breath of fresh air, and there were lots of examples in Drupal 6 Javascript and jQuery to really anchor the coolness of them.

Minor Nitpicks

My criticisms of the book are really minor in comparison with my praise. There were quite a few typos and consistency errors. In another genre of book I wouldn't be as concerned, but when dealing with code where one misplaced character can break an entire script, running into typos in the text reduces confidence that the code will work if copied verbatim, especially for the unexperienced programmer. I actually worked through every example up until the last two chapters, and was pleased to find out that they all (with one exception) worked as advertised. The one exception was in Chapter 7 where a module is required that does not produce valid JSON. It took me a while to discover the problem, look and find a patch to the module. One more really minor thing is that I felt that the tone vacillated a bit, assuming at times that the reader was new to programming, and at others more experienced. Sometimes a good bit of work went into describing more complex programming conventions, and at other times they were more casually alluded to.

Summary

Overall, I was really happy to spend the time reading this book. I'm not the fastest reader, and working through the code examples takes me some time, but it was worth it. It anchored some important Drupal 6 conventions, illustrated some best practices for jQuery which can extend from simple to complex projects, and introduced me to some of the ways that jQuery integrates with the different aspects of Drupal. I'm looking forward to reading more from Matt, and would recommend this book to anyone aspiring to jQuery ninja-dom.

Notes in the margin

I made several notes in the margin of the book that didn't make it into the above review, so here they are for those interested:

  • Until later on in the book, the example code snippets were short, which I appreciated
  • I liked the idea of introducing jQuery in the theme layer in early chapters. Really simple, good call.
  • Good callout in the translation chapter, which says 'hey, translations are really important, don't skip this chapter'. By the title, it was the least interesting chapter to me, but I really enjoyed it.
  • Excellent job covering lots of gotchas: Syntax coloring, can't call ajax on a different domain
  • Creating a javascript templating engine - weird and cool!
  • Would have liked a chapter on jQuery.getScript() - dynamically load javascript
  • How to handle cookies in jQuery - yea!
  • I like the .info file trick - stick your own stuff in there, use it later
  • I really liked the using caching for search auto-complete example. Will definitely use that one in the future.


Skip to the video

To celebrate by recent release from employment, I spent several days busting my butt to put the sexy back in administration. Namely, I updated the Drupal Navigate module to include some new features, and to fix some long-standing bugs that had been making administrators feel less than sexy for the last several months.

navigate.jpg

For the uninitiated, Navigate is an administration module that works a little like Administration Menu. It loads a sidebar with widgets which allow users to search the menu, nodes or users, construct favorite lists, and load up expandable / collapsable menus. It works really well for clients who aren't used to Drupal. The newest release allows admins to set default widget sets, and adjust user sets. You can also theme it (a funky lemon theme is included as an example).

There's a video demo below, but here's a quick list of improvements made in this release:

  • Made snappier through quicker transitions and fewer ajax calls
  • Added ability to manage default widget sets for users and user roles (all ajax, btw)
  • Made theming Navigate really easy
  • Fixed compatibility issues with Administration Menu
  • Added keyboard shortcuts
  • Added XHTML compliance
  • Added import / export ability for Favorites and for entire widget sets, so you can quickly deploy a set from one site to another
  • Added 'customize' permission, to keep *certain* users from messing up their own sets
  • Added ability to search users
  • Squashed some bugs
  • Re-factored lots of code to be more Drupal-esque
  • Made some minor layout adjustments

I'm hoping to put in some work to help with the current administration tools in D7, but before that, I needed to grease my wheels a bit with some contrib work to to anchor some jQuery techniques I'd learned, and re-familiarize myself with D6. It feels good getting so much done so fast. You can do that with contrib work, but it's hard to be that productive in core Drupal. Things just move at a different pace there. Now that I've gotten a bit out of my system, I think I can crack down a bit and start seeing what I can do for core.

And here's the demo video to celebrate Issue Queue Zero (at least for the D6 version):




Below are my slides from my presentation at DrupalCamp Colorado (had an awesome time, blog post of praise to come later). I think the presentation went well, but would appreciate any feedback from the folks that came. Was the info pertinent? Confusing? Was the presentation too basic or contrived?

Next time, I will remember to post the slides before the session so I can get feedback right away. Also, thanks to the fellow in the back for recommending Slideshare!



I've spent a good bit of time the last couple of weeks getting my thoughts straight for a session I may present at DrupalCamp Colorado called "Plugging into the Drupal community - Essential tools". The process of formulating my thoughts regarding my experiences with the Drupal community and what the project is all about has been a really good one. As a friend pointed out the other day, I'm more of verbal guy, so I've been thinking / practicing out loud and jotting down good thoughts when they come out. I remember David Byrne once saying that he writes music in a similar way.

The idea of the session is to help atendees wrap their mind around the social channels used by the Drupal community so they can get plugged in quick. Not just the technological aspects, but also the cultural implications of how the community uses them. I've been involved with the community on some level for a couple years now, and in hindsight I think my climb up the Drupal learning curve would have been greatly accelerated if I had gotten plugged in to the community earlier. Drupal is really a social solution to a technical problem, not the other way around, and realizing that can have a positive impact on the speed of learning and the ability to make a meaningful contribution.

Based on the voting so far, the session is lagging behind a bunch of other great-looking sessions - probably the material I'm covering seems too basic for the typical DrupalCamp crew. But I think I like the idea of putting a session out there, regardless of if it gets presented, just for the nudge to get some ideas in order. If I end up not presenting, that's just one more session I can either attend or skip out on to rub real elbows with some virtual friends.



Just got my tickets for Drupalcamp Colorado, and reserved a spot at the Melbourne hostel (my first hostel ever). I got so excited I put together a google map, complete with hostel, camp location, burrito place with good reviews and a couple grocery stores.

For those of you who might be considering going, but aren't sure about absorbing the costs, here's what it's going to run me:

$280 for plane ticket
$20 for registration
$22 for 1 night in hostel
$20 for shuttle to airport (will be catching a ride with fellow Drupaler from airport to event on Saturday)
$15 burrito budget (lunches served at the event, will bring breakfast with me)
---------------------
$357 TOTAL

That's almost a third the cost of just attending a 2-day Lullabot workshop (not including airfare). For me, if I do something like this about 4 times a year, that's about $90 / month, the amount I'm saving by using a Virgin mobile phone and iPod touch instead of an iPhone. So, basically free! ;)

Look forward to seeing you there!



There's a nice little firefox plugin called Stealthier, which allows for secretive browsing of the internet. While it's probably most widely used for untraceable porn siestas, it can also allow you to quickly switch off your cookies, cache and sessions, making you instantly anonymous on any site. In particular, I use it to view my Drupal sites from an anonymous perspective without logging out or opening another browser (that likely doesn't have Firebug). Then, I can just turn off Stealthier and I'm back. Kind of like the spy in Team Fortress 2.



During a recent push to a production server, I recorded a Selenium test to illustrate one of its uses, which is porting Drupal configuration changes from one server to another reliably. In this example, I use a Selenum test suite to accomplish several tasks, including:

  • Import a content type
  • Import a view
  • Install modules
  • Create a multi-paned panel page
  • Fill out several configuration forms.

This series of tests saved me a lot of time and reduced the probability of errors to virtually nothing. In the past, I would keep a list of configuration changes to port, and do them manually to push from a development server to staging, and then from staging to production. It's time-consuming and error-prone that way.

This video just shows the tests running with me narrating (rather poorly). I just wanted to actually show what was possible to whet the appetite of folks who haven't used Selenium before. I hope to add more tutorial-style videos later.

This video has been removed, but I will post a clearer one at some point. Thanks!



The other day I decided to finally figure out how to do a little benchmarking on some of the code we've been working on, and on my co-worker Jason's lead, I started fumbling around for a way to use kCacheGrind, which allows you to visualize where the bottlenecks are in your code, showing you information like how much time was spent on each function, in milliseconds or percentages. Very cool, but it took a while to get the setup just right. So, this is a cheat sheet to capture my research.

First of all, here's the aspects of my setup that might differ from yours:

  • Mac OSX
  • I'm using VMWare Fusion for hosting a Linux virtual machine
  • xDebug was already installed and enabled on my local machine

In a nutshell, here's how it works:

  • Using a firefox plugin and the php xDebug extension, you turn on xDebug profiler and load a page
  • xDebug creates 'cachegrind' files, which contains information about each php function that ran during that page load.
  • Open the cachegrind files with kCacheGrind to visualize the data.

You could do this all in Linux, but I end up creating the files on my mac and then drag them over to an Ubuntu virtual machine.

And here's the steps:

1. Download the firefox xDebug plugin

2. Set up xDebug profiler configuration in php.ini.

A cachegrind file can be created for each process, and Apache typically uses several processes for each page load. After some experimentation, I realized I wanted all of these merged together in a single file, which is what the settings below will do. Technically, this is 'append' mode, and if you refresh the page again, it will continue to append information. So, I will load a page, then I'll change the filename slightly (added a description at the end, for example), so the next page load will create a new file. Below are the php.ini settings I use for xDebug (set up to use remote debugging) and the xDebug profiler. I've bolded the lines you need to change to reflect your setup:

; xDebug settings
zend_extension=/Applications/MAMP/bin/php5/lib/php/extensions/no-debug-non-zts-20050922/xdebug.so
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000 ; Choose a port

; profiler settings
xdebug.profiler_append=1
;xdebug.profiler_append=0
xdebug.profiler_enable=0
xdebug.profiler_enable_trigger=1
xdebug.profiler_output_name = cachegrind.out.%s
xdebug.profiler_output_dir=/xdebug/

3. Make sure cachegrind files are getting saved

Turn on the profiler in Firefox by clicking the little (p) button in the lower right corner of the window. Then, load a page that's hosted on your local machine (I haven't checked how remote testing works). A file should be generated in the directory you specified for xdebug.profiler_output_dir.

4. Get an Ubuntu virtual machine

If you don't have an Ubuntu machine and have VMWare fusion, download a torrent for a full Ubuntu setup. If you haven't used torrents yet, Transmission is a good client for mac, and Azareus is the only one I have experience with on Windows.

5. Install kCacheGrind

Use the Add Applications menu item in Ubuntu and search for kCacheGrind. The install might take a while because there's a lot of dependecies.

6. Test out kCacheGrind

Once installed, open up a cachegrind file in kCacheGrind. You should see a lot of pretty colors and be a little confused. Perfect, that means it's working.

I haven't spent a lot of time figuring out the different levels of information in kCachegrind, but just the basic information is useful. It's easy to see which functions eat up the most processing power.

A couple other thoughts once you get to this point:

  • Each page load might be quirky for one reason or another, so it might help to balance out between several loads. Since we've set up the profiler in append mode, just refresh the page a particular number of times. Just remember how many time so that when you benchmark changes you can make an accurate comparison of the changes.
  • In addition to seeing the amount of time spend on functions, you can see how many times it was called, and by what. I noticed a function right away that was being run several times when it only needed to be run once. It's because I assumed that template.php was only included once. I realized this is a good way to test out some of your assumptions.

Sources

Below are some links I found particularly useful for information:
http://elrems.wordpress.com/2008/02/12/profiling-php-with-xdebug-and-wincachegrind/ - Info for setting up php.inihttp://www.maccallgrind.com/ Mac callgrind reader (for use in a pinch, it was hard to find useful information in it, though)http://derickrethans.nl/files/phparch-xdebug-qa.pdf - Info about what the xDebug configuration lines actually mean
http://www.xdebug.org/docs/all_settings#trace_output_name - Variables that can be used for naming the cachegrind output files

- Credit to other co-worker Caleb for "Promoting me to get off my ass and write a blog post"



Syndicate content