Ethan's blog

Testing Asynchronous JavaScript Drupal Apps with QUnit

Ethan's picture

As one blogger has put it: “we cannot avoid testing javascript anymore”…especially when it comes to testing sophisticated client-side web apps that integrate with our servers via various APIs. As we begin to build more complex interactive functionality and web applications, making sure that our JS code is working correctly becomes central to our QA process. Tools like Drupal’s SimpleTest implementation are great for unit testing our server-side code and basic input-output expectations, but effective testing of advanced client-side functionality requires a robust, fast, JavaScript based solution.

Following up on our recent post introducing the Backbone module for Drupal, this post will cover how to test Drupal JS apps using the QUnit module. We’ve chosen QUnit in large part because its GPL lisence makes it a good fit for Drupal development, and the QUnit module is a mature, well designed implementation.

Introducing the Backbone Module for Drupal

I am tremendously, overwhelmingly, and kind of absurdly excited to announce the alpha release of the new Backbone module for Drupal. Why? Because the oddball combination of new-kid-on-the-block Backbone with venerable-ol'-stallwart CMS Drupal is actually a suprisingly well matched and powerful one.

With Backbone.js, Drupal is no longer a drag when making dynamic, JS-based functionality...in fact, it's kind of awesome. Backbone works by creating lightweight model objects in the browser that are then easily bound to the vast array of interaction events and views using a flexible client-side templating system. Drupal is a great tool for producing the sort of structured JSON data that Backbone consumes: we get the full power of Drupal's Field API and content administration tools on the server side, but don't have to deal (much) with Drupal's theme layer and rendering stack, getting Backbone's lightweight awesomeness in our UI code. It's kind of a marriage made in web development heaven.

The Backbone module for Drupal provides a foundation for building Backbone apps within Drupal sites. Following the Backbone philosophy, it extends Backbone's Model, Collection and View objects to work with Drupal nodes, views and templates, respectively, via the Services module's REST server functionality. While a few default views and example templates are also included, the rest is left up you, the developer, to build on as you please.

Getting Ahead of Drupal's Coding Standards w/ Drupal Code Sniffer, Vim and a little Regex

Ethan's picture

If you've submitted a project for consideration in a Drupal.org project application or issue queue, you may have received a review that looks something like this, a seemigly-endless stream of errors relating to whitespace in comments, function argument documentation format, and horribly malformed "else" statements. We can thank Drupal Code Sniffer and it's web-service offspring, the Automated project review tool at ventral.org, for much of this turn toward strict compliance reviewing. While we all know that it's "the right way to go", it can often be quite discouraging to hvae to churn through a list of what feels like miniscule issues in order to share code with the community, especially when many of those issues are caused by inconsistencies between standard code editor templates, documentation auto-generators, and what Drupal.org requires.

The good news, though, is that we can get one step ahead of the review process, and integrate these new tools into our development environment to ensure that the code we write for Drupal is alway 100% compiant, from the start.

Setting JS Callbacks with Drupal, JSON and Some jQuery Sauce (for jCarousel controls)

Ethan's picture

Sometimes a few characters of code can make all the difference in the world. All coders know the scenario: the code looks fine, all the right values are in the right place, the code validates or compiles (or at least looks like it should), but when we run it we get...nada. Maybe the source of the problem is a comma following an array declaration (fine in PHP, but can be a killer in JS), an extra "$" in a variable name, or - as in the case of trying to define a callback for jQuery libraries like jCarousel using JSON - an extra pair of quotes around the callback function value.

Unfortunately, the difference of a few quotes is not always so easily overcome. In the case of extraneously quoted JSON function values, for instance, the issue originates from within the drupal_add_js function and PHP's own json_encode. Such situations can lead to desperate measures: grabbing the drupal_get_js output and munging it with regular expressions or other hackish means to make it do what we need. While use of such techniques is something of a religious dispute among Drupalists, I'm happy to announce that there's also another way to tackle JSON callbacks in Drupal, with nothing more out-of-line than drupal_add_js and a bit of simple jQuery magic.

Google Analytics and Drupal's Scheduler: How to be first in line

Ethan's picture

This post was not written at 7 AM. Using Drupal's Scheduler module it was automatically posted at a carefully calibrated time in order to get the most number of visits.

Now don't be fooled by that whole "carefully calibrated" bit, though. While post time does have some impact on social media shares and RSS reader share, it's not the most important factor. Not by a long shot. Real, sustainable audience growth comes from regular, high-quality content and responsive relationships to your online readers.

Echo Nest Remix API: The Next Level

Ethan's picture

EchoNest has basically taken the web API to a completely new level with their new Remix API.

The API allows not just the analysis of beats and musical characteristics that their basic API offered, it additionally allows coders to modify audio and video files based on the analysis information for programatic remixing.

To get a sense of the amazing results, check out these initial exploratory vids: http://musicmachinery.com/2009/06/21/wheres-the-pow/

More info: http://code.google.com/p/echo-nest-remix/

Does anyone know of any other multimedia API's that allow for the modification of audiovisual assets via API calls?
Any on your wishlist?

Personally, I'd love some good web-based speech to text and face recognition APIs.

(via O'Reilly Radar)

SimpleMenu Block Admin Fixed!

Ethan's picture

Lovers of the venerable SimpleMenu module rejoice: the issue with Administration themes overriding the default theme on the Blocks admin page (caused by calling theme() from hook_init()) has been fixed by AlexWilke!

Using Tokens in Comment-Triggered Email Notifications

Ethan's picture

The stock "Send Email" action type that ships with Drupal 6 does't offer a whole lot of options for including content from comments in your triggered emails.

In fact, it doesn't offer any.

There has been a good deal of discussion on this: a patch has been proposed and a stop-gap helper module has been posted to drupal.org.

Before you go that route, though, check out this post on using the Token Actions module to provide access to the full array of available tokens in your email. Thanks to Erik Weik at New Rivers Digital for the great post.

We're using Trigger-based email notifications to fight spam and help our clients be engaged with their commenters.

How do you use and implement comment notifications?

Drupal for Firebug: Under-the-hood Made Easy

Ethan's picture

Let's start here: Drupal for Firebug is amazing. I'll even go so far as to say that it's more useful than Devel Themer. More details below, but you should start by downloading the Drupal for Firebug Firefox extension (or the Chrome one) and drush dl drupalforfirebug on a local project and giving it a spin.

Fixing Textmate's PHP Commands with MacPorts PHP

Ethan's picture

For anyone else who's having trouble with include path errors when trying to run PHP-based bundle commands in Textmate like this one:

PHP Warning: require(/lib/beautify.php): failed to open stream: No such file or directory in /private/tmp/temp_textmate.4tD2ED on line 19

It looks like the problem has to do with php.ini configuration settings that ship with MacPorts (may be the production sample ini file, in particular). In order to environment variables to populate the $_ENV global that Textmate uses for settings, etc, be sure you've got the letter "E" at the front of the "variables_order" setting value, like this:

variables_order = "EGPCS"

Reluctant hat-tip to an article on Experts Exchange for this one.

Today I learned: about max() array magic

Ethan's picture

Today I learned:

  1. That there's always more tricks in the PHP bag
  2. That the max() command will return the element with the highest-value key when returned an associative array. So, given $a = array(1 => "red", 5 => "green", 10 => "blue");, max($a) will return "blue".

Symfony and svn:externals... super-slick the easy way

Ethan's picture

(If you already know about Symfony and just want to use svn:externals to install it, you might want to skip here)

We've begun using the Symfony MVC framework for some small projects and really getting into it. If you're not familiar with MVC frameworks, then...well, you probably are more familiar than you know: the MVC patternis the design pattern at the heart of well-known development frameworks like Rails and Django. PHP has its own varieties of MVC frameworks, and Symfony ranks along with other popular options such as CakePHP and Code Igniter.

Like most MVC frameworks, a large part of what makes Symfony such a powerful tool is it's meticulously organized codebase. Placement of each piece of the stack is exquisitely thought-out, providing the foundation for an extensive plugin-architecture capable of interfacing with and incorporating numerous third-party libraries and tools. Like any intricate protocol, however, the organization of Symfony's code can be somewhat daunting and labyrinthine, contributing to its fairly steep learning curve.

Luckily there are some great tutorials and references out there, including the freely available version of the commercially published Symfony Book, the Getting Started Guide and a bunch more.

Drupal Internationalization: Part I, and introduction

Ethan's picture

We've recently begun putting together the infrastructure for a number of upcoming projects which will organize people around the world toward some pretty powerful, ambitious goals. While the details of those sites are still in the works, working with Drupal to create multi-language sites has been a great experience involving a great deal of learning. This is the first of a two part series covering how Drupal works with multiple languages and the best practices/tricks of the trade for making the most of the Drupal Local, i18n and L10n systems.

What the h3l is this i18n/L10n c2p all about, anyway?

Don’t be scared by the geekspeak! “i18n” and “L10n” are just abbreviations for “internationalization” and “localization”, the engineering methodologies used to create software packages and websites which can be used by speakers of different languages. i18n is the process of engineering an application so that it can be adapted for use by speakers of different languages or in different regions without needing major modifications and L10n is the related step of providing conversions between languages, date formats, etc. so the software or site can be accessed in any particular language (see the Wikipedia article on i18n and L10n for more).

Setting up Eclipse to Debug Drupal with XDebug

Ethan's picture

Every 6 months or so I take a stab at setting up line-level, breakpoint style debugging for PHP. In the past I've been able to get the debugger installed, but the lack of a decent interface to use in setting breakpoints and watches has limited the value of a debugger (one thing that I have found helpful is XDebug's profiling feature that lists all function calls in a nested format along with performance timing). The recent announcement of a new XDebug client for OS X got me back on that track, and while I wasn't able to get MacGDBP working as I wanted, it did lead me to re-evaluate the newest Eclipse offering for PHP coders: PDT. PDT has come a long way, and the combination of a robust IDE, nimble 'jumpt to' shortcuts and killer debugger integration are more than I can pass up. Here's how I got everything working on a Mac OS X 10.5 box.

Much of what follows was made possible by and incorporates instructions from these very good tutorials:

A Poor Coder's Devel Themer Port for Drupal 5

Ethan's picture

Let me start by saying I’m not proud of this, it is one of those awful awful hacks which I should be ashamed of and appalled that I would even consider, one of those hideous violations of every coding standard known to good coders throughout the world.

What is this horrid, monstrous bit of code hackery I’m referring to? It’s a simple hack to the theme function which provides a very rudimentary version of some of the theme-level information so elegantly and profoundly usefully exposed by Moshe Weitzman’s Devel Themer module. For various reasons, this hack actually isn’t that egregious; for one it is ONLY FOR USE ON DEVELOPMENT SITES, and therefore does not all into that more loathsome category of coding dark secrets which are injected into codebases in the 11th hour to make Drupal conform to non-Drupal-tuned functional specifications. In addition, the hack allows custom processing of theme output to be included in the info dump for themed blocks, and therefore makes incredibly arduous tasks like finding the source of a missing </div> tag a great deal less awful. Let’s face it (with relish): sometimes hacking core is just the best way to debug difficult problems.

So, enough stalling, just what is this horrible, awful, shameful hack I’ve devised. Well, it’s anticlimactically simple, actually. Just insert the following code into the function theme() declaration in theme.inc just above the return call_user_func_array($functions[$function], $args) call: