I’ve been working on a project to redevelop our school web site in WordPress MU. The idea is to continue and support what Patrick Delaney started years ago, with teachers and students blogging and making the web site a living part of the school instead of just a stiff brochure, or even (in the more modern conception) a utility. The idea is that this site and its blogs have the potential to be part of the teaching and learning that goes on at our school. So, high-minded Web 2.0 educational philosophy aside, the practical concern here is that we need to support about 100 teacher blogs, currently living in Manila. Hence, WordPress MU and a bunch of customization. It must be easy for teachers to use. It must look good. It must be powerful and able to integrate cleanly with other services.
In that frame of mind, as part of the WordPress implementation, we want to make it easy for individual teachers to display a Google calendar on their blog. No problem, the WPNG Calendar plugin is already written and has a widget implementation. (If you’ve never used WordPress, widgets are packaged bits of code that, when installed, offer users a drag-and-drop interface to add content “modules” to their blogs. Along with the theme and plugin architecture, it makes WordPress easy to develop for and work with.) We’re using widgets extensively to give teachers an easy way to lay out the content on their blogs, but still stick within a general design framework that gives us a consistent look.
The only problem with the calendar widget is that I wanted to be able to include more than one copy on a given blog. For example, on the main school blog we’d like to list out the sports calendar in a different space than other events. (You can temporarily have a look-see, if DreamHost is up today and we haven’t broken everything as we work on it.) I can also imagine teachers keeping different Google calendars for their different courses and wanting to display all of them on their blog. This particular widget was not set up with these use cases in mind. In fact, it was only a display widget for a calendar feed specified in a different option panel, and generally intended to have a dedicated page of its own. So the widget didn’t have many options of its own.
Fortunately, adapting it for multiple instances was easy (at first): store the feed URL in the widget options, add some UI to deal with that, tack on an ID numbers to each widget, make sure to use that ID when saving and loading the options, and add a little menu to the admin interface to let users specify how many of these thingies they want. Pretty stock widget development, all just glue code that I could copy by example. Easy, I thought, I’ll be done in no time. All I had left was hacking up the display code.
Then we call the Google API and specify a callback function. (I parameterized this to allow the feed URL to be passed in from the saved options, instead of grabbed from a global variable as it was previously.) Once the data arrives, the callback function finds the event list div and loops over the calendar data, formatting and adding items to the list until it’s done as many as you told it to do. Finally, it hides the loading div and shows the list div.
Of course, I need to parametrize the div names since there can now be more than one of each. That’s easy enough to do when we build the page, and we already have individual IDs for each widget that we can tack on. But remember the callback function? Oh yeah, that. The problem is that the callback function needs to know the div name to do its magic. The callback a separate function. How can it know what div it should be looking for? Right now, the div name is hardcoded. So why not just pass it the div name? Because it’s Google’s code that invokes the callback when they get done fetching data. I can’t pass the div name through their code, because I can’t change their method signatures to give me an extra parameter. And, in fact, I don’t even want to do that. The code between where I kick off the request for the calendar data and get the callback doesn’t need to know anything about how or where I’m going to display the data.
So what’s the right way to handle this? Well, my callback function needs to have the div name available to it, without having it passed in. Global variables not only lose style points but also reduce to the same problem: which global variable am I looking for? One solution that would work is to hardcode a different function for each div, and pass the appropriate one in. But that’s very ugly. Not only would we be duplicating code, but we’d be duplicating it only to change one string in the whole function! As the meme goes, fail.
Think for a minute about how we’re passing the function as an argument. (This is the notion of first class functions.) Why not make a function that will build and return the function we want? This function is a higher-order function, and this is usually where programming really starts to “bake your noodle” as a friend of mine likes to say. The basic concept is straightforward: if you define a function inside another function, the inner function’s scope includes that of the outer function. That is, the inner function has access to all the variables in the outer function — that would be the first stop outside itself on the scope chain. This is the basic idea of closure.
Simple, right? Actually, it can be pretty confusing, especially without a clear understanding of how names are resolved into values and how scope changes with execution context.