Ubercart building a reputation for Drupal as good e-commerce solution

As Ubercart marches toward a beta release, I'm pleased to see more and more stores popping up in the <a href="http://www.ubercart.org/site">live sites directory</a>. I was just as happy to see a post in my Google Alerts from another development shop finding <a href="http://chasesagum.com/drupal-ubercart-simple-shopping-cart">Drupal + Ubercart to be a good solution</a> for e-commerce development. The guys at <a href="http://www.sundaysenergy.com">Sundays Energy</a> have been doing this openly for a while, and I know several other developers who have pumped out multiple incredible sites (izi are you out there? :P ). The post that just came up today, though, was different. It not only praised our beloved CMS for having a good e-commerce module package in Ubercart, but it <em>also</em> praised Drupal over against the likes of Joomla/Wordpress (and their e-commerce extensions) and other dedicated e-commerce solutions like osCommerce and ZenCart.
The fellow who posted the article seems to be a pretty well-rounded developer who probably has much more experience than me in general and with other e-commerce packages. He likes the combination of Drupal + Ubercart for simplicity, flexibility, and (for lack of a better word) themability. Don't we all? My hope for Ubercart is that it continues to build a name for Drupal as <em>the</em> open source CMS solution for e-commerce... We're working hard to make it easier for folks to use and more applicable for a variety of uses. I'm happy to be working on such a fun project, and even happier knowing it's building a good reputation for Drupal in another niche market of web development. What's good for Ubercart is good for Drupal and vice versa. :)

<div style="float: left; margin-right: 1.5em;">
<script type="text/javascript">
digg_url = 'http://digg.com/programming/Drupal_Ubercart_Simple_Shopping_Cart';
</script><script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></div>I found this article through a Google Alert on "Ubercart" as a Digg. You should <a href="http://digg.com/programming/Drupal_Ubercart_Simple_Shopping_Cart">Digg it</a>, too!
<br style="clear: left;" />
On a somewhat related note, we had a new user post the following quote in our forums:
"Ubercart rocks. I was tooling with ecommerce feeling suicidal until I found this."

There you have it... Ubercart saves lives.

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="http://drupal.org/node/109153">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="http://drupal.org/node/102338">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' => 'budget.admin.inc',

// 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 FB.net (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