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:
I'm going to be presenting at tomorrow's Dorkbot DC meeting — anyone who's interested should come on by. I'm going to be talking about making a Fonera router talk to an Arduino, a subject I first blogged about right here.
And of course the DC nerd community also shouldn't forget about Wednesday's Drupal Meetup at Affinity Lab, which is once again being hosted by our friend Mike McCaffrey. You can find details here. I think it's safe to say you'll be able to find some of us at each of these events.
Yesterday Development Seed was kind enough to give Chris & me a rundown of how the Drupal community is organizing its participation in the Google Summer of Code program. Along the way I got a chance to chat with Alex and Ian about FeedAPI and FeedAPI Mapper, two excellent projects that DevSeed ushered into being through last year's Summer of Code and now continues to maintain and extend.
I've just begun using FeedAPI for the first time in a project destined for production, and so far I'm very pleased with it. It offers a more fully-considered alternative to aggregator.module — and with the addition of the optional Mapper module it becomes simple to turn aggregated RSS items into Drupal nodes, with the items' attributes stuck in whatever CCK fields you care to create. It's really slick.
In my case I'm using it as an integration point for Blip.tv. Our client needs video capabilities, but I saw no reason why we should mess around with transcoding, customizing an FLV player and all the rest of the headaches that come with web video (been there, done that). Blip does all of that stuff very well, and has social features baked in, too. I'd rather just have the client upload their videos there, then count on FeedAPI to turn them into nodes that can be exposed through Views. Any configuration that we can't get from the Blip RSS feed can be manually handled by an editor — Workflow-NG fires off a "please come edit and publish me!" email whenever a new video node is created.
Yesterday Ethan, Chris and I found ourselves needing to move some data into Drupal — we're building an existing client a new site and they need some blog posts moved over from their old one. It sure sounds simple. But as anyone who's actually done data migration from one blogging platform to another (or just from one version to another) can attest, it's rarely that easy. There are a few options, though, which I present here in increasing order of their likelihood to unexpectedly spiral into a huge, awful mess:
I've had a couple projects that needed the menu system to stay open when a full node was being displayed. The Drupal menu system, while dynamic and mostly awesome, didn't seem to allow for that, at least not in the way that I needed it to. So, I wrote Automenu.
For each content type, Automenu allows an administrator to set a default parent in the menu system. If a node is given an entry in the menu system, that default parent is ignored. Relatively simple.
To illustrate, let's say you'd like all nodes of type 'news' to show up under an entry in Primary links called 'Newsroom,' but you don't want to actually create an entry in the menu system for each one. Automenu will do that for you, specifically without creating additional entries in the menu system. If you want to give an individual news node its own special place in the menu system, you can still do that the standard way.
Give it a shot!
Thanks to merlinofchaos and the folks in the #drupal IRC channel for steering me in the right direction on this. They're a bunch of great and helpful folks.
Out of all the modules in Drupal Core, Profile has always seemed me to be the most half-assed. It's clear that something needs to happen to it — using CCK field types at the least, maybe removing profile data from the user object, and, if I had my way, permanently node-ifying users. I haven't poked around Drupal 6 as thoroughly as I ought to, but based upon what I've heard from Phil's writeup and the Lullabot podcast, I may have to wait a bit longer to see meaningful change come to Profile.
So others may find themselves in the situation I did yesterday for a bit longer: trying to embed a profile form somewhere that Profile.module doesn't think it ought to go — for instance, yesterday I needed to let users edit their name and address on their user_profile page, rather than expecting them to mess around with a bunch of tabs and only-vaguely-different categories.
You'd think there'd be a way to call drupal_get_form() to collect your users' addresses and names whereever you might care to. But you'd be wrong, so far as I can tell — profile.module acts as a user.module parasite, accomplishing what it does through hook_user() and the abuse of arg().
But it's very easy to re-wrap Profile's form-generating functions in your own module and then call drupal_get_form() against it. Here's the example that I came up with:
I'm kind of a jQuery fanboy. Nontechnical friends following my Twitter feed are sick of hearing about it; my colleagues at EchoDitto have learned to avoid mentioning competing JS libraries around me, lest they be subjected to a long and increasingly enthusiastic speech about why they should be using jQuery instead. It's a bit embarrassing. I've used script.aculo.us, moo.fx, and read enough of the Dojo docs to become deeply confused. But jQuery's the one for me.
And, excitingly, a new version was released on Monday. Let's have a look at the biggest changes, shall we (or at least the ones that seem most immediately relevant to me)?
I've always been a bit perplexed by the relatively short lifespan of any given Drupal version, particularly when big changes, such as API modification, always rear their heads. I first began Drupal development back when things were still 4.6 and 4.7 was a whisper in darkened corners of run-down bars. When Drupal 4.7 finally came out I had just gotten a handle on how 4.6's APIs worked, and here I was, having to unlearn what I had learned. Thankfully, it was a quick process, and forms API turned out to be much more of a help than a hindrance.
About a year and a half later, we're on the verge of a stable release of Druapl 6.x, and I'm looking forward to this one much more than I was for 4.7. So, in celebration of that fact, I figured I'd run down a few elements of Drupal 6.x that I'm excited about.
"JavaScript theme functions are entirely free in their return value. It can vary from simple strings, up to complex data types like an object containing in turn several jQuery objects which are wrapped around DOM elements. See the original (default) theme function to see what your custom theme function should return."
Here's something I recently presented at the DC Drupal Meetup:
You've already heard us prattle on about Hey!Watch — it's a great video transcoding service that we've gotten in the habit of using for several of our clients. As much fun as wrestling with ffmpeg is, sometimes it's more appealing to just bit then bullet, pay a dime per transcode and not have to worry about keeping your codecs up to date.
They offer some neat add-on features, too, like direct uploading of transcoded videos to your Amazon S3 account. Even more tantalizingly, there's this: a method for allowing your users to upload directly to Hey!Watch's servers, complete with fancy-pants AJAX progress indicator. There's no need to spend your server's bandwidth and CPU on videos at all — you can stick to running Drupal on your system, outsourcing all the heavy lifting. You can send along your own arbitrary variables with the video submission, then receive them back via a ping that Hey!Watch sends once transcoding is complete (allowing you to keep track of who uploaded what video). It's pretty slick.
But interested Drupal developers will click through to the Hey!Watch code and despair. First, the AJAX is written with Prototype, which won't play nicely with Drupal's preferred jQuery library. Sure, it'd be possible to rewrite it in jQuery — but I'd really rather not.
Second and more damningly (and unsurprisingly), the form that uploads to Hey!Watch needs to stand on its own. You won't be able to nest it in a Drupal form — Drupal understandably doesn't like nested forms.
Any interested Drupalologist would do well to go read Jeff Robbins' take on how to improve Drupal. Okay, so it's a bit utopian — I think he's only half-kidding when he talks about Drupal "saving the world." But the guys at Lullabot know Drupal's strengths and weaknesses as well or better than anyone else.
I was particularly interested by the "What If..." section of the post. He phrases it a bit more politely, but Jeff's right: drupal.org and api.drupal.org are downright embarrassing when compared to other CMSes' sites. Providing the the code that comprises a function is not the same thing as documenting that function. And providing a boring, poorly-organized product site is no way to win converts.
For my own, selfish part, I'd just like to see some stability in the APIs. 4.7's Forms API changed everything; 5 changed much of it again. I've become a grudging convert to using CCK and Views for nearly everything — there are very good reasons for that design decision, made by developers smarter than I — but there's no question in my mind that it's made development slower. I'd like to see these projects remain in a stable place for a while, and try to consolidate rather than continuing to reinvent the wheel — the fact that CCK has its own pidgin DDL is something no one should be happy about.
At last! The answer to a persistent problem that's been stymying my Drupal 5 efforts. First, some brief background for the non-techies:
A very common way of developing code for use on the web is to run a local copy of the site on your own machine's webserver while tunneling traffic to a central development database. The dev writes his code and saves it on his machine. He then points his web browser at his own machine. The web server picks up the request and runs the code. Whenever it needs to talk to the database, it does so by talking to a central DB server over an encrypted tunnel. This is made possible by SSH, a handy program that can let you securely pipe TCP traffic between servers like magic.
This is useful because when multiple people are working on a site, it's important to be able to combine their work while simultaneously preventing them from stepping on one another's toes. There are a number of well-developed tools for combining files within a project (we use Subversion). But it's very hard to have people work on separate copies of a database and then combine their work into something useful. It's much easier to just have everyone work off the same development database. It's also not as big a deal, because if someone makes an incorrect change to the database it's generally less likely to negatively affect other developers (well, unless they did something really unwise). Tunneling makes it easy for devs to keep their code separate and their databases unified.
I was hoping to follow up the EchoDump release with redirect.module, a simple Drupal module for providing HTTP 301 redirects in a manner similar to how Drupal's path aliasing system works. All I had to do was fix some minor issues to make our 4.7 version compatible with Drupal 5.
But wouldn't you know it, former Ditto and all-around great guy Justin Miller beat me to the punch. He's just released a Drupal-5 compatible version of http_redirect.module (originally created by professionalnerd.com). You can get it here. And if that doesn't exactly meet your needs, this module might.
So! No reason to reinvent the wheel, regardless of how fun the reinvention may be. Thanks for putting this together, Justin!
Some of you may remember opensource.echoditto.com, EchoDitto's lately-neglected repository of free software. We've had turnover both in staff and Drupal versions since the last time we paid serious attention to it. One of the goals of this labs project is to migrate that software over.
Much of it hasn't been ported to Drupal 5 — and most of it shouldn't be. Webform makes echoinvite unncessary; askismet and the spam module encompass the capabilities of blacklist.
But we've still got a few useful tricks up our sleeves — and now have some new and improved, Drupal 4.7 and 5 versions of "classic" EchoDitto modules.
So, first up: EchoDump. This is an awfully simple module, but also an awfully useful one — at least in my experience. If you're maintaining a Drupal site for a client that expects regular reports but isn't capable of wrangling with SQL, this can greatly simplify your life. It allows you to create SQL reports that can be exposed on a granular basis to users. And it features easy exporting to Excel, making the creation of "user signups over time" graphs and the like a relatively painless process.
As you might expect, you'll want to be very careful about which users you grant the right to enter SQL.
Also, please note that although the 4.7 version has been used on production websites, I just adapted it to 5.0 for this post. Please consider it beta software, and use it with care.
Ah, springtime in Washington, DC. Where unpredictable weather comes to sow its wild oats.
It's been a distressingly long time since the days my mother was around to remind me to 'bring a jacket', but it got me thinking: The judgments that I make on whether to don a blazer in the morning are based on fairly quantifiable data. I know at what temperature I like to wear a jacket, I know what the temperature for the day is supposed to be, and I know not to wear suede if there's a chance of thunderstorms.
It seems likely that in the age of ultra-accessible information (of which weather seems most ubiquitous), I could build something to do this decision-making for me. Inspired by the geekery at this year's SxSW, I started envisioning a service that would send my phone a text message each day—advising me on whether I should wear jeans or shorts, a jacket or a t-shirt, or bring an umbrella.
WeatherMama had been conceived, and its 2 month gestation is finally almost over.
Read on past the jump for all the geeky details.