Development of Dreamsocket.com
- Development
To begin with, we used Drupal to build Dreamsocket.com. We chose it for many reasons but perhaps the best thing about it is the community surrounding it. Drupal is open source and there are literally hundreds of open-source add-ons for it which are under active development. I would recommend anyone looking to build a website to put aside their preconceptions and check it out.
With this project, we set out to build a website that would establish a presence for Dreamsocket on the web, provide a place to sell our products, provide support for those products, and enable us to interact with our customers. I will cover a couple custom modules and techniques we used to reach these goals.
Company Image
Although we have developed web apps that have been seen by millions of people, we have never had a company website. Being our company's first visible presence on the web, we wanted the entire site to reflect Dreamsocket's image. Every section needed to seamlessly mesh together in style as well as function. This is one of the reasons we gravitated towards Drupal in the beginning. We have seen many websites that feel pasted together, they grab a blog from one place then use a forum module from somewhere else and eventually combine all the parts to come up with a functional website, albeit not the best looking. Drupal gave us a way to maintain a common look and feel across every section from submitting forum posts to purchasing products which was invaluable to us.
Initially, we were a little frightened upon glancing at the urls of pages on our Drupal test site. Since look and feel is important to us we wanted the urls to appear logical to the average person and to clearly indicate where the content on screen is located in relation to previously viewed pages. We wanted neither the word "node" nor numbers to appear in any of our urls if at all possible. Fortunately, with clean urls, Pathauto, and a little trickery we were able to get logical and hackable urls across the entire site.
For example, by default Drupal displays user ids rather than usernames in users' accounts i.e. user/5/view. We added a couple lines of code to hook_user() to create aliases for each user when their account is created. So, that same url could be user/jsmith/view, for example. Here is a snippet of that code:
function ds_accountpath_user($op, &$edit, &$user, $category = FALSE) { switch ($op) { case 'insert': // Generate aliases if ($user->name) { $name = check_plain($user->name); path_set_alias('user/'. $user->uid . '/profile', 'user/' . $name . '/profile'); ... } case 'delete': // Delete aliases
The added benefit of cleaning up the urls so much was that we were able to essentially copy the url onto the breadcrumb. In my opinion, this is considerably more logical than letting modules use drupal_set_breadcrumb() and most likely setting the breadcrumb to something that matches neither the url nor the page titles.
Store
Since our main reason for building the site was to sell software, the first thing we did after choosing Drupal was to pick a cart module. We ended up going with Ubercart after looking over all the other options and we are very happy with the choice. It had every feature we were looking for and their support and documentation was robust and very similar to Drupal's. The several times I ran into an issue that I could not solve with their documentation, my forum posts were answered by someone on their dev team (usually Ryan) within the hour.
Our current and future products will be distributed via downloads. Immediately after a customer makes a purchase all the files for their product are added to a tab in their account pages where they can access them it at any time. Ubercart's File Downloads module provided this functionality although we modified it to fit a couple specific needs.
We needed to support products with several "sub products" and multiple versions per sub product. For example, when a customer buys our Media Framework, it comes with an Actionscript 2, Actionscript 3, and Flex version. Additionally, we will release upgrades for each version and will allow the customer to download back versions as well as each new upgrade. As a result, we modified Ubercart's File Downloads module to get a layout that is logical and will not become cluttered at some point in the future when there are many downloads for each sub product. This is a pod from the Files section:
Product Support
The heart of our product support lies in our Documentation section which contains language references as well as instructional articles related to our products. The Documentation section was constructed with Drupal's built in Book module. To create the language reference sections we developed a little script to run against the output of ASDoc and AS2API for Actionscript 3 and Actionscript 2, respectively. Both are tools for generating HTML documentation from source code. Although they are great for standalone documentation, they don't work very well if imported directly into Drupal.
The script we developed cleans up the HTML files and processes the links so that, using a slightly modified version of the Import HTML module, the links work after the files are imported. Our Media Framework has over a hundred classes, so it was not realistic to create and submit each page by hand. Also, we will be updating our language references regularly as we add comments to our code so being able to update the documentation in place and maintain user comments was important, and thankfully the Import HTML module supports this.
Community
We believe establishing a dialogue with customers is key to developing relevant applications. We don't want to isolate our development process from the people we are developing for. Creating areas of the site to gather input was very important. One of these sections is our Issue Tracker. When browsing the Drupal contrib modules, I was very impressed with how all the projects and associated issue queues were managed. We decided to develop a similar system in the spirit of the Project and Project Issue modules but slimmed down a lot to fit our minimal needs.
We didn't need any of the functionality of Drupal's Project module for several reasons but mainly because our "projects" are products that we are selling and we intend to have whole sections of the site devoted to providing information about them; we didn't need an extra page devoted to each project. Our distilled version of the Project module is essentially just a content type and a couple other fields that we use to organize them. Then we have a Project Release content type built on top of the Project module which is what feeds the version numbers for our Issue Tracker and Release notes pages.
A couple issues arose with this approach mainly since all content in Drupal is considered a node. Several of our content types, Project, Product, FAQ and Release Notes, are never intended to be browsed to directly. Our products are only displayed in the Store section using a view from the Views module, our FAQ's are only displayed in views as well, and Release Notes are displayed with a custom module. We did not want these content types to show up in the search or have any content at the address of their urls. Our solution veered from the "Drupal way," perhaps, but it has worked so far. We simply used the Content Template module to hide all content at their urls, providing a link to their actual View, and wrote a SQL query that runs after Drupal's cron to remove these content types from the search index:
db_query("DELETE FROM search_index WHERE sid IN (SELECT nid FROM node WHERE type IN ( 'product', 'project', 'project_release', 'release_notes', 'faq'));");
The Future
We plan on making many improvements over the coming months and have already started working on a couple. Perhaps the largest looming improvement is to move everything over to Drupal 6. The site was built on Drupal 5 because Ubercart wasn't stable for Drupal 6 throughout most of our development phase. Most of all though, we look forward to hearing ideas from our users and will make improvements based on that input.
This article was also posted on Drupal.org and Ubercart.org.
