Book Review: Pro Drupal Development

August 12th, 2007 by comment Nola

Book Site | Sample Chapter: The Theme System | Table of Contents

Many of you are aware of my current total infatuation with Ruby, and that I’ve used PHP for about 6 years and at one point decided I hated PHP…until, I needed it for a quick one-off page and then realized that PHP had its place. Then again, I was totally frustrated with Ruby when making my moms bakery site and then turned to Drupal and Gallery (another fine PHP project), which saved my bacon and I got a website and photo gallery up in a weekend. So, PHP and I have had our moments but I’m not abandoning it!

Drupal powers some big sites, its not just for joe smoe’s blog. This is an interesting page about Is Drupal Right For You? and if you are wondering if its something that would even work for you.

I was excited to get my hands on a review copy of Pro Drupal Development. Its no secret that coders hate documentation and Drupal has one of the most complete online documentation I’ve seen for an Open Source project, but its almost too hard to find what you need amongst so much. The Pro Drupal Book is a godsend for the drupal programmer, new and experienced alike. I wish it was written a year ago!

The book starts off with a quick overview of how Drupal is structured and defines terms such as hooks, node and blocks in just 10 pages. Chapter 2 is a A step-by-step tutorial with making a module. That is a great idea to start off quickly writing code. It get the reader involved and hands on. I really tire of books that have to start off with the history of the internet, html and how things have evolved. Get to the code dangit!! Kudos to the Authors for that! Chapter 3 gets into module specific settings, like how to get your module to show up on the admin page and storing user settings that your module needs.

After you’ve had some experience with the code then the book goes into details on the specific parts of Drupal:

  • Menu System
  • Databases
  • Users
  • Nodes
  • Themes
  • Blocks
  • Form API
  • Filter System
  • Searching and Indexing
  • Files
  • Taxonomy
  • Caching
  • Sessions
  • JQuery
  • Localization
  • Using XML-RPC

Drupal is a pretty amazing framework, when I read the code I say “why didn’t I think of that?” … the module and hook system is genius.

Then some more general topics:

  • Writing Secure code
  • Development Best Practices
  • Optimizing Drupal
  • Installation Profiles

One of the chapters I skipped ahead to read was The Form API. In my years of PHP I’ve often tried to come up with a framework for doing forms and I wanted to see how they did it. This chapter follows a tutorial style as well. The Form API allows you to define fields, their label, their value, description. Some frameworks take the template approach, where you hammer out your HTML. Some are more configuration based like Drupal making a multi-dim array with keys and values. I can see advantages to both. There is a hook function for validation which allows you to write your validation checks.

PHP gets a bad wrap for security, partly because its pretty easy to learn PHP and newbies don’t always realize what they are doing. There is a chapter devoted to security and includes even some things I didn’t know about — encoding mail headers. The Form API is very secure,  one thing it does is check values that come from dropdowns were actually in the options and it wasn’t something that the hacker made up.

Developer Best Practices are great for the new developer, it talks about using cvs, tags, branches. It talks about how to create and apply patches (hint - you can contribute back to drupal). That is awesome. Alot of open source projects are like “HELP us, submit patches!” and the new user is left with uhhhhhh..how?

Caching is another interesting chapter. You will learn  how caching works and how Drupal Core uses it. There is a Cache API that has methods for module creators to make their modules faster.

JQuery … I am not sure if I like it or not, but its part of Drupal 5! I skipped ahead to this chapter to see what its all about. There is a javascript hook built into Drupal making it easy to add, thats pretty cool.

One thing I found lacking in the book is anything about Testing. There are few pages on debugging and some modules to help with testing, but I would like to see more. At least some talk about selenium, which is great for a site made with any framework/cms.

Over all, Thanks APress for another great book!

ˆ Back to top

Getting started with YUI’s Connection Manager in Rails and PHP; or “All Happy Families Are Not Alike”

February 28th, 2007 by comment sarah g

This post is geared towards folks who haven’t done the A part of AJAX before (And I mean the first A, as in Asychronous); are new to Yahoo’s implementation of the XMLHttpRequest object (The Yahoo! Connection Manager) and would like added information on how that works; or bothThis is not meant to supplant the excellent yui! tutorials which you should read in detail for thorough explanations and examples. What I am adding here are a few examples of using this in the Rails framework and some thoughts on the callback object and scope.

Your “AJAX” goals are simple: you want to communicate with your server, get a response back that you can use (or not), do something with that response (or not), and move on. As this is asynchronous, you want to do this without reloading your web page. Or, as a client once said to me, referring to certain animated gifs in the upper right-hand corner of certain browsers, without “making the world spin”. To this end, Yahoo! has supplied us one line of code:

var transaction =
YAHOO.util.Connect.asyncRequest(
method, uri, callback, postData);

or, same line with some data plugged in:

var transaction =
YAHOO.util.Connect.asyncRequest(
'POST',   'php/post.php', callback,"id=1&old_id=2");

When I was making the switch from synchronous to a-, it helped me to visualize a standard web form to see how form elements and attributes are translated to an AJAX request. It’s pretty obvious, but if you need an “aha!” moment, the above line is akin to the html form printed below (though unless you’re one of those people whose definition of interactivity is “The Monologue”, do refrain from creating forms with 2 hard-coded hidden inputs and nothing else! :)).

<form method="post" action="php/post.php">
<input type="hidden" name="id" value="1" />
<input type="hidden" name="old_id" value="2" />
<input type="submit">
</form>

So, excluding a reference to the callback for the moment (which is not addressed in this example), that form maps to the Connection Manager call quite simply: method, action (uri), data. Let’s look at the arguments required:

method: the method of the server request (POST, GET and others also available).

uri: the uri that’s receiving and processing the data you send (in our example, “php/post.php”). YUI’s examples use php, but, if you’re using the Connection Manager in a Rails app, it’s easy to adapt: your argument uri might read “/projects/update which would pass the data to the update method in projects_controller.rb, which would then be able to access the data through the params array, like so:

def update
@project = Project.find(params[:id])
end

In php you’d probably do some type of db query [assume input cleanup and some type of database abstraction layer, such as PEAR/DB_DataObject, here]

$project = DB_DataObject::factory('Projects');
$project->get($_POST['id']);

Callback: a reference to the callback object you are supplying. This is how everything is handled. More on that in a minute.

postData: the data itself in standard query-string format (”new=1&old=2″). NOTE: if you’re doing a GET transaction, your 4th argument would be false and your second argument would include the url and query string, like so:

“php/post.php?new=1&old=2".

So, what’s this callback?. In a synchronous transaction, you have the luxury of redrawing the page to process your data (and yes, nothing says luxury like a nice, slow, page reload…). In an asynchronous transaction you need to essentially “sneak” your data back into the page without reloading it. This is where your callback object comes in. It helps you get your data “in the door”, so to speak, so your page or application can change in a way that feels seamless to the user but often returns a visible result (changing a div, displaying some text, etc.) and if not a visible result at least a meaningful one (setting the value of a hidden form element, for example). Your callback is responsible for executing actions based on the data retrieved (or the failure to retrieve data) from the uri. In a standard synchronous form this action might be “generate an HTML table that displays your database results”. Or, “Print a message saying there are no results”. Of course, you can do anything you want with your data, that’s just an example of a fairly common scenario.

Once you’ve sent your data to the uri for processing, you need to wait for your response — without, of course, appearing to wait (save for the ubiquitous web 2.0 spinner you know you’re dying to try!). And, of course you want to know if your transaction failed. If you don’t watch for these things — “success” and “failure” in technical terms — you’re not going to be able to make an appropriate decision about what to do next in your app. So you feed your AJAX request a callback object: an object that defines functions for what to do in the cases of success and failure. In simplest terms, we’ve got

var callback = {
success: handleSuccess,
failure: handleFailure
};

where “handleSuccess” and “handleFailure” are user-defined functions that take the http response object and do stuff with it.

handleSuccess = function(o){
// cheer! (or process data returned from the server)
}

handleFailure = function(o){
// cry, vow to try again! (or display failure message)
}

There’s also the ability to pass scope, timeouts, and additional arguments to the callback object. To do so you’d read the great tutorials at the links above and add the lines below, of course changing the values to values meaningful in your application.

scope: Ajaxobject,
timeout: 5000,
args: ['arg1', 'arg2']

The handlers. handleSuccess and handleFailure both take an object o, which is the http response object. There’s a detailed list of all the properties of o on the yui page (Not to be confused with the Story of O, which I will not link to as it is beyond the scope of this article, you dirty rascals, you…). The property you’ll likely use most often is o.responseText, which is the server’s response as a string. This is what you pass back from good old ‘php/post.php’, and getting it is simple: echo. What? echo. What? echo..o..o… ok, sorry, moving on. For instance, if we wanted to capture the update_date in our successHandler to print to our page and we’re using php, we’d write something like this:

echo $project->update_date;

and if we’re in Rails? something like this:

render_text @project.update_date

If you need more data than a string — an array or collection of objects passed back from the server, you’ll find that’s simple, too: call the ruby method to_json() on your array instead. This essentially serializes your object so it can survive the journey to the Client. Once there, you can access the data using JavaScript’s magic wand: eval(). It’s great. So if you had an array of users connected to a project (and your database relationships are set up correctly), you could write

render_text @project.users.to_json

in php, assume you’ve got your $users array, and use print_r

print_r($users);

The in your JavaScript successHandler use eval(), like so:

var users =  eval(o.responseText)

and bingo: in two lines you’re happily in your JavaScript parsing your users array like you would any other JavaScript array. You have connected your server to your DOM and no one is the wiser for it.

All this is great. We have our AJAX call and our callback object and are ready to go. But, suppose you don’t want to rewrite the AJAX call all over your app? The Yahoo folks have a great example of a ‘“hypothetical ajax object” (mysteriously named “AjaxObject”) that encapsulates success, failure, and process methods and calls a callback object that defines AjaxObject as it’s scope. Encapsulating your AJAX request so you can call it from wherever you want in your scripts in a DRY fashion makes your code cleaner and easier to manage. Yahoo! does this well in their example: in my usage I changed it up a little bit to meet my needs.

To quote the great Chicago writer Leo Tolstoy from his famous novel Anna Karenina Does Lake Michigan, ‘“Happy families are all alike; every unhappy family is unhappy in its own way”. I’ve learned that when working on an app, the opposite is true: success cases call for a range of actions: failures can more easily handled (log, display error, abort). Based on this, I’ve adapted the yui AjaxObject example to accept a postAction, successHandler, and object (used to define scope). This allows you to call AjaxObject from other objects, pass specific success handlers, and pass this (a reference to your current object) so you can access it in your successHandler from within the calling object. The AjaxObject builds the callback using those arguments. Like so:

var AjaxObject = {

handleFailure:function(o){
// Fail gracefully
},

/**
* Wrapper for AJAX calls using YUI connector
*
* @param postAction {String} URL to post to
* @param callBackSuccess {String} Success handler
* @param postData {String} Data to post
* @param obj {Object} Object that handler has scope in
*
*/
startRequest:function(postAction, callBackSuccess, postData, obj) {

var callback = {
success:callBackSuccess,
failure:this.handleFailure,
scope:obj
}
// ASSUME you've shortened your yui connection mgr to $C
$C('POST', postAction, callback, postData);
}

};

Then you can call AjaxObject from within a class, like so, and pass it a class method as it’s success-handler:

var Project = function Project(){
// initialize project however you like
this.foo = "bar";
...
// CREATE in db and return id
AjaxObject.startRequest('/project/create',
this._generateDbId, postData, this);

}   // Success handler  Project.prototype._generateDbId = function(o){
if(o.responseText !== undefined){
this._setDbid(Number(o.responseText));
// DO other stuff..
}
}

This way your AJAX calls are in one place, you can use them in the scope of the calling object and define as many success handlers as success cases (or pass false); and fail in one standard way (gracefully, of course). Of course, this can be adapted to pass failure cases in too, or however you like. This was a way I found helpful in my work, and I hope it’s helpful to you as well. And thanks again to the folks at Yahoo! for providing so much great stuff to work with in the first place.

ˆ Back to top