Fish 'n Flush

Thanks to my Dave Barry calendar (from last year), I have a new favorite item on my Christmas wishlist. I can take up to two, so bring 'em on!

Adventures in Drupal 6

As soon as we get the Ubercart 1.0 release out the door, we're going to dive into converting the entire project to Drupal 6. Drupal 5 has served us well for over a year now, but many features offered by the major API changes/additions (menu, forms, schema) are just too sweet to miss out on when we start making our own Ubercart sites. I know we'll be taking a beating for at least a couple weeks updating all our modules, but ... well, no "but" - it's just going to hurt. ;)

In anticipation of the update, I've decided to dive into module development in Drupal 6 early. As my pilot project, I've started building out a budget module my wife and I can use to monitor our spending through a Drupal site. I'm hoping other people and organizations will find online budget tracking handy, and I'm betting they'll be happy to use Drupal 6 to do it. (How sweet will it be to be able to enter receipts remotely? Your budget won't get torn to shreds when you go on vacation.) After several hours reading d.o, chatting in IRC, and trying everything until my eyes hurt, I'm starting to feel comfortable with the changes.
So, Drupal 5 module developer... what can you expect when you come to Drupal 6? A lot of new, and a bit of confusing. The documentation is still being fleshed out and arranged, so you should be gracious to those posting it up as you try to find that bit of info you need. Overall, it's been pretty helpful, and there are always plenty of examples in Drupal core for just about anything you'll need to do. You can expect to spend a few hours grokking the changes to the menu and forms APIs, even if you were there to see Jeff's ewoks dance in Barcelona. There's just too much going on for folks familiar with the old systems to grasp all the changes in one go. Also, you can expect to spend plenty of time learning to use the new schema API. Here again, I just opened up as many .install files as I could find in core and went to town trying and retrying my own. Just keep reminding yourself that this really is a huge improvement over the old method (or lack thereof) of creating tables!

A few things to look out for that I wasn't expecting and don't know if they're documented:
<li>It seems truncating cache_menu no longer does the trick when fooling with your menu hooks to get them right. I've kept the modules page open and disabled/re-enabled the module while working on it. Surely someone can point me to a higher path. 8)</li>
<li>The sequences table is out and auto_increment (and other DB equivalents) are back in. The schema API lets you specify a column's type as 'serial' and takes care of the rest. I got snagged here on a default value in my schema (was copy/pasting...). As far as I know, you should not specify a default value on a serial column. (At least setting it to 0 is going to give you a nice error when it tries to install.)</li>
<li>All form builder functions are being passed an argument... the catch all <b>$form_state</b> array. Either I missed this in the update notes or it wasn't yet in the right place, but this had me baffled for a bit till I realized that the first parameter passed to your function when you use <b>drupal_get_form()</b> is always going to be <b>$form_state</b>. You should account for this if you're counting on a form receiving any arguments, like this one from my <em>budget.module</em>:
function budget_category_form($form_state, $category = NULL) {
// ...

I also hopped on IRC briefly with my fingers crossed hoping to find someone knowledgeable of the new menu API. I half-heartedly asked if anyone around could help when lo and behold, the Architect himself, chx, waved at me. I leapt for joy (inside, not literally) in my chair and got to chatting. You see, I needed some local tasks to show up only on the edit form of budget nodes, but I was having a hard time restricting them to nodes of that type. I had read in the docs about <a href="">dynamic argument replacement</a> and thought I might be able to do something with that, and chx showed me how. Joy. :D

So, the skinny is... menu item paths now accommodate some wildcard action using the handy %. In my menu items, I was able to put in %node_budget with a coordinated load function that checks if a node having an nid equal to the value of %node_budget exists and is of the budget type. If that function returns FALSE (bad nid or not a budget node), then the menu path is a 404 and won't be displayed in the local tasks area of whatever node you're editing. This may sound vague, but check the code and the screenshot. You'll know if you'll never need this information and can go ahead and forget you ever read this paragraph. For everyone else, as soon as I look at the code making this work, I'll be posting this to the <a href="">menu system docs</a> per chx's request. Thanks again, chx!

// In budget_menu:
$items['node/%node_budget/edit/budget'] = array(
'title' => t('Edit budget'),
'access callback' => 'node_access',
'access arguments' => array('update', 1),
'weight' => 0,
$items['node/%node_budget/edit/categories'] = array(
'title' => t('Edit categories'),
'page callback' => 'budget_categories',
'access callback' => 'node_access',
'access arguments' => array('update', 1),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
'file' => '',

// The function called when a path that may resolve for either of those items is loaded:
function node_budget_load($arg) {
return (is_numeric($arg) && ($node = node_load($arg)) && $node->type == 'budget') ? $node : FALSE;

So, on a page node, those menu items won't show up in the local tasks area at all. However, on a budget node, you'll see them both and get to further setup your budget node. How cool is that!? 8) See the screenshot below for a visual. Also, unless I'm way off, <b>node_load()</b> caches the node so you needn't worry about superfluous database queries.

So... these are the start of my adventures in Drupal 6. Won't you come adventure with me?


Well, for the last several weeks, there has been a FreeBASIC game programming competition in the forums at (view thread). I pleaded with my wife and was allowed to work on and submit an entry. I've sacrificed plenty of sleep to work on the project after she's gone to bed and ended up with what I feel is a solid, enjoyable arcade game with enough bonuses and gameplay strategies to provide some replay value. The title is SECTOR SHOCK, and it is your next favorite pasttime.

The restrictions of the competition were you had to use the original graphics and sound files from Space Invaders. I checked out what I had to work with and dove into brainstorming fast... during lulls in the day, over lunch break with Lyle, and while putting Christina to bed. The week before I had been playing with a game programming library called HGE that makes a lot of things easier... graphics, sound, frames, etc... it's just nice. Many thanks go to Dalex for porting HGE to FreeBASIC.

My final product is a top down space shooter that takes advantage of the arrow keys for movement, WASD for firing, and shift/ctrl for special features. The game features 6 types of enemies and their generators (portals), 3 types of weapons, 2 special maneuvers, and 2 special bonus types spread across 25 waves of combat. Each wave gets progressively harder, while your ship gets more lethal. There are a few different level types, and even some health and support resources that must be managed during gameplay. There are some fun particle effects to provide atmosphere, courtesy of the excellent HGE library without which my entry would not be near as good. I assure you the game is very beatable, as I've played through every level myself. Estimated play time is somewhere around 45 minutes to an hour.

I'm hoping to nab first price, which is 100 GBP, but even third prize is a nice bit of spending cash (Christmas presents, anyone?) when the U.S. dollar is so low. }:) I've gotta find more of these European competitions! I've listed my game in the competition thread with a few more details and credits, but I'll also put the screenshots and links up here. To view the other games entered, head to the competition page at FreeBasic Tracker (a FreeBASIC community site I'm developing... or have been for the last 1.5 years... ;)).

Eye candy:

Main menu goodness.

Probing an enemy to charge the ion cannon.

Wave introduction screen.

The final stage! Crazy!

So... what are you waiting for?

Download SECTOR SHOCK today, and post your high scores and best shot rates up here!

*If you have trouble starting this up, it may be your video card doesn't support the 320x240 full screen mode I'm using. You can adjust settings.ini to specify other screen modes, a windowed version, and any number of debug features. You can also use it to warp levels. Wink

Last Ubercart Alpha Version Reached

After a fine wrestling match in the office with CVS, tags, and project releases on d.o, I finally got the initial Alpha 8 release of Ubercart out the door. The last few alpha versions have seen marathons of development and feature additions, and this "minor" release is no different. Thanks in large part to Shawn and Lyle on the Ubercart team, we now have core functionality for file downloads and expirable role promotions (depending on a customer's purchases) and a good base of Workflow-ng integration providing administrators with a UI to create custom order workflows.

The two most requested features from folks I met at Drupalcon were related to the selling of digital goods and user account roles, and Shawn was able to use work that had already been contributed by third party developers (aymerick, CpILL, torgosPizza, and others) as a starting point for some really great module additions to the Ubercore. No time for a complete feature list here, and really no space either. Both modules are packed with excellent functionality, and we're already seeing a very positive response.

Warner Brothers Records has launched their first artist site using Ubercart selling Avenged Sevenfold fan club memberships with the new roles module and Workflow-ng support. Furthermore, the soon to be released redesign of Mike Nelson's RiffTrax will use Ubercart to sell downloads of the trax through a sharp looking custom catalog. The feedback and contributions from both these companies has been very helpful as we've implemented the new features.

So... all that combines together to make this one of the most exciting Ubercart releases to date. What's even better is this will be our last alpha version. We usually hit the minor versions pretty quick with install and update function fixes, but there will be no moving to Alpha 9. From here, we'll head to beta and beyond. Once we hit the 1.0 milestone, we'll set to work frantically updating Ubercart for Drupal 6 and finally get to a point where we can start using this for our own company's sites!

For those interested in demoing some of these new features, you can check out the recently revamped Ubercart Livetest. The site is running the latest code and demos a lot of the key features of Ubercart. (This product, for example, demos the file download system integrated with the product attribute system to sell music either as a CD or mp3 download.) Granted, I'm particularly proud of what goes on "under the hood" in the administrative menus and forms, but I'm also happy with the way the front end is working out. As elv pointed out indirectly through a post at g.d.o/usability, the user experience is very important, and we're working to make the customer user experience better with each new release.

So... feel free to check it out and post any bugs or suggestions in the appropriate forum, and while you're there, you may as well start dreaming of all the ways you can use Ubercart in your future projects. Wink

(Click here to view the news post at If this sounds like cool software to you, please vote for Ubercart at Intel's Cool Software site. We're not doing so bad in the rankings. 8))