WikiWeightWatcher.com Upgrade and Redesign
WikiWeightWatcher.com is a weight loss community website that allows users to view, add, and change Weight Watchers points and nutrition facts for restaurants and food items. It was initially launched in the fall of 2008, has grown to over 7,000 registered users, and currently receives over 3,000 unique visitors a day.
PropDrop is a company specializing in web development and marketing, focusing on niche websites and small businesses and organizations, doing anything from church websites to veterinarian websites. They did both the initial development, the new custom theme, and the implementation of the new features.
The Old
The original site was developed to see what the demand was for such a site like this. Drupal 5 was chosen because of the speed of development and the availability of the modules.
The “wiki” type functionality, while not 100% true “wiki”, suited our purpose and was simple to implement. Any logged in user could add Restaurant type nodes and Menu Item type nodes. Menu Item nodes had the nutrition information, such as calories and fat grams, and a CCK node reference pointing back to a restaurant. Revisions were also turned on for these content types, so rollbacks could be performed if needed.
To make it as easy as possible, an “Add Menu Item” button was located on each restaurant node, which had the restaurant node id as an additional argument in the link. Using a small amount of custom module code, we hid the CCK node reference on the node creation form, while populating it with the node ID from the argument. Easy and limits potential confusion.
To display the menu items for the restaurant, an embedded view was placed in the node-restaurant.tpl.php file.
Similar functionality was completed for food categories and foot items.
To prevent mass deletions or just plain wrong data, we also used the Modr8 and Revision Moderation modules. This allows administrators to approve changes or additions either in bulk, or individually.
For the theme, we used a slightly modified version of LiteJazz.
And as the traffic ramped up, we saw our time to load pages increased to where it began to negatively affect our Google rankings. So we installed Boost and it immediately solved the problem.
This all worked great and it would have continued to work great. But, it was time to mature. After we got our 7,000th user, we decided to sit down and figure out how to bring the site out of infancy and develop a plan to make it more successful.
First on the agenda: moving from Drupal 5 to Drupal 6. With the inevitable release of Drupal 7 on the horizon, it was simply time to stop putting it off. It's not that Drupal 5 stumbled or didn't meet our needs. It met our current needs perfectly. But our needs were not going to remain stagnant. So we upgraded for two main reasons:
1. PropDrop has worked exclusively in Drupal 6 for over a year, and our Drupal 5 skillset (theming, module development, etc) was getting a bit rusty. For both maintenance and additional feature development, upgrading made the most sense. We also gained access to the more advanced Drupal 6 versions of certain modules, like Views 2.
2. Drupal 5 will stop being supported with security and bug fix releases after the release of Drupal 7, which, as far as we know, is probably being released this year. We didn't want to be caught with our pants down.
The Upgrade
This was the first Drupal core version upgrade attempted by PropDrop, and it went more smoothly than we could have hoped. We did it over a single Saturday, which is one of the days with lower traffic.
First we took a snapshot of the database and the file structure, and copied that to a different server. This way, no matter what happened, we always had the live site still running. No worries.
Then, on this new instance, we followed the instructions as listed at http://drupal.org/node/340073
No major hiccups occurred, and after this, we copied the database and file structure back over (after taking another backup of the live site file structure) and we were suddenly running Drupal 6 and ready to grow.
All in all, it took about 10 hours combined work.
The New
Next on the list, after the upgrade, was creating a new brand and custom theme. Litejazz had served us well, but we needed to move on.
We went with a less formal logo, yet a bolder color scheme. On the old site, the most visited pages were the Browse Restaurants and Browse Food Items pages, for obvious reasons, and links to these pages were kept in the left sidebar. For the new theme, we wanted to give them the prominence they deserved, so they are now part of the primary navigation. Not only that, but they are on the far left and a different color than the rest of the primary links.
A new front page layout was devised to look more organized and less cluttered, yet have more information, including room to feature some of the unique articles we would be adding.
We also wanted to move the sidebar to the right. Having main content on the left offered a better user experience.
User Accounts: Making them Useful
Since the very beginning, we’ve had about 6 to 9 new people sign up for user accounts every single day. This was one indication that the idea had some legs to it. There wasn’t even a reason for these people to sign up, other than the forums (powered by Advanced Forum), which, initially, no one really took advantage of anyway. And only about 3% of these users actually edit or add information. It’s still a mystery to us why people kept signing up for no apparent reason, but we’ll take the growth whether we understand it or not.
Regardless, in this iteration of the site, we actually wanted to make these user accounts useful. So we added three things.
First was the Clip to Favorites functionality. Utilizing the Flag module, it was simple to allow users to mark their favorite restaurants and menu items, and have them show up in their profile. If there are a few restaurants they always find themselves looking up, this will help eliminate a few mouse clicks.
Second was the Friends functionality using the User Relationships module. Using this, we will eventually integrate the Heartbeat module show people can know what their friends are commenting on and when a friend marks a restaurant as their favorite.
And third, we added Imagecache and Imagecache Profiles. Yes, on the old site, we didn’t even allow people to have avatars. How lame is that? It has now been remedied. In addition we have a Featured Members section that helps highlight that we are indeed a community site.
iPhone and Services
Upgrading to Drupal 6 allowed us to use the latest Services module. We wanted an iPhone application, but didn’t really want it to draw from a local database. The appeal of the site is that it should have the latest information based on what users are adding and editing, and so we wanted the iPhone app to pull directly from the live Drupal database.
This was the first time we had ever used the Services module, and our first ever iPhone application. It was quite an adventure of head scratches and blank looks at LCD monitors, intermingled with some frustrated sobbing. But we prevailed. The app is now approved! http://itunes.apple.com/us/app/wikiweight/id389590293?mt=8
But how did we go about this? No one knew Objective-C (the language for programming Apple applications), and frankly, no one really wanted to learn it. Thankfully, people much smarter than us had already come up with solutions to this common predicament.
The first is called Phonegap, which wraps HTML, CSS, and Javascript into an XCode project, effectively making it a native iPhone application. This meant that we could use tools we were already familiar with to develop for the iPhone platform. In addition, Phonegap also includes wrappers for Android and Blackberry applications, so the same code can be used for multiple smart phone platforms.
The second tool we used is called JQTouch. It's great to be able to use Phonegap so we can use HTML, CSS, and Javascript, but that doesn't really do a lot of good unless you can have the look and feel of a native application. JQTouch, a JQuery plugin, provides this admirably using webkit animations and a nice default theme (which our application uses).
Thanks to the above tools, we were able to interface with the Drupal Services module with JQuery AJAX calls. To do this, we used the JSON server, modified to accept JSONP(http://drupal.org/node/598358). This was a bit tricky to smooth out all of the kinks and syntax requirements, and required a lot of trial and error, and looking at the Javascript console in Firebug. In particular, figuring out the double quotes that needed to be there, but also escaped in certain places. The typical ajax call we ended up with looks like the following:
var node_id = "["" + id + ""]";<br> view_name = ""menu_items"";<br> $.ajax({<br> url: service_url,<br> dataType: "jsonp",<br> data: {"method" : "views.get", "view_name" : view_name, "args" : [node_id], "sessid" : service_session },<br> success: function(data){<br> $("#progress").hide();<br> if (data["#error"] == false) {<br> load_menu_items(data["#data"]);<br> } else {<br> console.log(data);<br> alert("Error: " + data["#data"]);<br> }<br> },<br> error: function(xhr, status, errorThrown) {<br> $("#progress").hide();<br> alert("Cannot connect to the Internet.");<br> }<br> });
Drupal version: Drupal 5.xDrupal 6.x