Ubercart Beta and Beyond

Just a quick post to celebrate the initial beta release of Ubercart. I can't imagine the beta phase being anywhere near as long as the alpha phase in which we rapidly built out the core features, expanded into a few unexpected areas (file downloads, role promotions, etc.), and spent plenty of time providing bug fixes, usability enhancements, and forum support. Rather, we're looking for a relatively short beta with a 1.0 release as soon as possible.

We know there are many places we can improve, and we're counting on the community to keep posting them up (with patches when possible ;)). For a quick list, you can view this thread where I outline a few outstanding issues and emphases for the beta phase.

I don't really know what the full way forward beyond the beta will be. The release of Drupal 6 looms large on the horizon, but we are taking advantage of a few modules that will need to be updated along with Ubercart before it can be fully implemented on Drupal 6. We still have a couple large modules that need to be coded before our business can fully use Ubercart, but I'm not too hot on coding those in Drupal 5 and then spending even more time updating them before we can use them. Further, some of the API enhancements in Drupal 6 are just too good to pass up. I'd expect us to transition into Drupal 6 development as soon as possible.

I'm sure we'll get it sorted out, as changes and updates always take longer than expected anyways. Smile

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?