Houston, We Have A Problem

Years ago I had a college professor tell me, “…the most successful people are those that communicate effectively under conflict.” I’ve held this mantra with me over the years, and feel strongly that this phrase applies just as much to developing web applications as it does when talking to a hostile client or handling those potential PR catastrophes. Many companies put contingency plans in place in the event that something goes wrong, allowing them to explore and prepare for any eventuality of worst-case scenarios.

You will read a lot of information about how to communicate your product and branding message on the web through marketing copy, sales promotions, and advertising campaigns. But what about when something goes wrong? What happens when a visitor to your site, or a user of your application reaches a dead-end? Do you just sit back and trust that they have the patience to figure out what went wrong? You are likely going to need a lot more than just a smiling face and a call to action button; you need to get them back on track, and do it quickly. The technique is called “Contingency Design” (a term made popular by 37Signals, I believe) and it involves thinking a bit pessimistically when theorizing that your user will immediately get from “Point A” to “Point B” without running into an issue.

For years even large corporations like Microsoft, Federal Express, Target, Amtrak, Ticketmaster, and Sony have had issues in dealing with online customers when conflicts arise. Historically, managers and decision-makers have pushed off the responsibility of communicating error scenarios to programmers. An endeavor I’ve always compared to asking a gun manufacturer to handle a hostage negotiation. They may have built the tools… but in the end someone is going to get hurt. That being said, whether you are a business professional or a web application developer it’s time to think about contingency design when working on your projects, and here are a few tips to get you started on the basics.

1. Just Be Nice

Often called the “Golden Rule”, the most important thing to always remember when something goes wrong is to just be nice. Start by changing the way you look at the people that are viewing your site and stop labeling them; they aren’t customers, they aren’t a use-case persona, they aren’t statistics; they are people. People like to be happy and when something goes wrong they don’t want to be accused of causing it. Be kind, use words like “we’re sorry”, “thank you”, and “please” to revitalize their experience. Avoid taking an accusatory tone when telling the user of an error using phrases like, “you missed,” “you forgot,” or “you didn’t,” that can point blame. It’s also a good practice to stay away from all capitalized letters in your error messages. All “caps” tends to give the reader the perception that you are speaking loudly or screaming at them and can be distracting when trying to calmly inform them of an error that needs resolving.

2. Make The Problem Clear and Consistent, Then Offer a Solution

It’s tough to get through a problem when you aren’t sure what the problem is. With that in mind, it’s important to always be clear when telling the user what the error is and always show the error messages in the same fashion.

To really make some of these points easy to understand, let’s take a look at a sample login form that we might find on any various website offering specific content to a “members only” group.

image1.png
Image 1: An Example Login Form

Now using the rules that we’ve set-forth, if a user accidently tries to login using an incorrect username or password a clear and concise error message might look something like this:

image2.png
Image 2: An Example Login With Conflict

All of our basic rules are here. We’ve first shown the error message in a way that makes it clear a problem exists, using the red color along with an exclamation point to grab our users attention. It is then up to us to make sure that we continue using this format for any other errors. Next we stated a clear problem, the username and password information that was entered didn’t seem to match anything on file. The user can now try their information again in case they made a typo, or they can click for help which could take them to a way to recover their forgotten information. Stay away from generic error messages such as “An error occurred while processing your request,” or that discuss overly technical material like “The connection to the database DB_FINANCE has timed out,” as it is rare that your users would be able to interpret them to solve their problem.

It’s also a good idea to give the user a “Plan B” in case all else fails that gives them a direct way to receive your attention. Providing a live chat, support email, or a toll-free number is a good way to show your users that you are happy to provide them the special attention they need when a problem arises that they are unable to solve on their own.

3. It’s a Brand, So Use It!

If you currently have a branded product or service that customers purchase from you, let the brand be used consistently throughout the web address to allow for easy guessing. This can assist your more tech-savvy users in finding the products or services they are looking for. Some great examples of this would be:

  1. http://www.adobe.com/photoshop forwards users to the page to read more about Photoshop as well as purchase it. This works with the majority of their products.
  2. http://www.microsoft.com/windows forwards users to all things having to do with versions of Microsoft’s Windows operating system.
  3. http://www.apple.com/itunes takes the users to information and download instructions about Apple’s popular iTunes product.

One important thing to remember is to plan for people to incorrectly type the case of your product names. The iTunes product from Apple, Inc. capitalizes the T and lowercases the i when branding it’s product. However going to http://www.apple.com/itunes or http://www.apple.com/iTunes will take me to the same place. Apple, Inc. fails however to do this properly with their iPhone product (as of this writing). Spelling it exactly as the brand identifies with http://www.apple.com/iPhone will bring the user to an error, while http://www.apple.com/iphone brings the user to the correct page.

Essentially, help your users find their way easier by consistently allowing products to be seen by guessing the web address, it allows continued branding from the marketing end as well as being more efficiently pulled from the users visual memory when remembering the page they were previously visiting at your site. Lastly, don’t punish the user for using all lowercase or not spelling the product name exactly as you do, try to make sure all your site paths are not case sensitive.

4. Speak Their Language and Prepare for Typos

As the community of online users continues to increase their trust in commerce websites it becomes more important to get potential buyers to the products they are interested in. Unfortunately, the Internet has one major disadvantage to it’s brick-n-mortar retail store cousin, and that’s the ability to say, “I’m looking for a black hoodie with a picture of Time Square on it,” to a store employee offering assistance.

Online stores have search systems that allow you to type in keywords to make your search, however these search systems have a fundamental flaw; they aren’t human and are programmed to understand a product vocabulary as it is interpreted by the products vendor. Most of these searches will look through the name of the product and it’s description. If a product titled, “Black Sweatshirt with Hood” was available I might never know if I searched for “hoodie” the typical slang for such apparel.

So what do you do? When developing an online store it’s important to plan for administratively entered “meta data” keywords to describe the products that are also searched for when a user enters a word or two within your search box. This way when you create a new product, you can add its title, description, and some additional keywords related to it. Enter the slang, or commonly misspelled words within this area of your site allowing for more users to find the correct product they are looking for even if their search is flawed.

It’s important to mention too, however that planning for typos shouldn’t end at product searches. You should plan for common misspellings wherever possible, including the web address itself. As I recommended in my previous tip, it is important to continue brand and product names through the web address, and those too can contain spelling errors. For those of you more technical types, several products exist that allow for spell checking address paths on a web address (warning: some technical verbiage is coming). For sites being hosted on a Windows server running IIS consider looking into URLSpellcheck as for sites running Linux or UNIX based operating systems and Apache 1.3 or later, enable mod_speling (yes, there is only one “l”, it’s meant to be ironic) and use the CheckSpelling directive of “on.” Both of those products have their own documentation and own companies that support them, so it’s important that you research to judge the pros and cons of these various products and find the product that best fits your needs before jumping into a solution. Spell checking the web address takes a little bit of technical know-how, if you aren’t a technical person yourself you may want to contact your hosting company to look into options that might be available to you.

One last suggestion when it comes to planning for spelling errors. Have you ever been rushed going to a website only to find that you’ve entered only two w’s (such as ww. instead of www.)? Well, you’re not the only one. Top online retailer, Amazon, has planned for situations just like this. If any of their users attempt to go to http://ww.amazon.com by accident, they will quickly find themselves pointed to the right spot and redirected without a single sign that something went wrong. This of course is another option to consider when running a website and more information should be available to you by talking with your hosting company.

5. Create Results, Not Dead-Ends

No one wants to work for nothing, so don’t make your users do it either. If a user isn’t able to select an option on a search form because of another selection on the form, don’t make it an option. The last thing your users want to do is fill out a search form only to be told that have made an “invalid selection.” So, plain and simple, if they can’t do anything with it – it shouldn’t be there. Period.

It’s important to know however that this concept of creating results goes beyond just hiding things they can’t do. It’s important to give them as much ability to do business with you as possible. If the customer searches for a product but finds the product out of stock, don’t hide it in this case. Show them when you expect to have more in stock and allow them to sign up to receive a notification when that product has become available. You may even consider accepting pre-orders for the item that will be in stock shortly.

So in short, customers like the ability to communicate and buy the product they are interested in now. It’s hard enough to get a customer to press that “buy” button so there is no reason to stand in their way once the decision has been made. Always do what you can to minimize dead-end warnings or those “sorry, not in stock – please go to my competitor” scenarios.

To Err Is Human So Learn to Forgive Yourself

More then anything it’s important to know that you are not perfect. Even large companies have a hard time grasping their users’ behavior. A Lead Designer of Netflix, Inc. (the popular online movie rental outlet) has been quoted saying, “Predictions color our thinking. So, we continually make things up as we go along, keeping what works and throwing away what doesn’t. We’ve found that about 90% of it doesn’t work.”

Now all of us don’t have the resources that Netflix, Inc. has, but it is an important quote to remember when considering features that you might want to add to your website, don’t be upset if you don’t get it right the first few times. Test. Get Feedback. Rework. Test. Rinse. Repeat. Succeed. You get the idea.

Wrapping It Up

Contingency design, behavioral design, and other forms of user experience design are not always easy to grasp, but I hope I’ve been able to give you several basic tips to get you started. The key is always very simple, be on the side of your users, consider basic human behavioral needs, and your bottom line will grow from there.

As always, I’d love to hear the experiences you’ve had with your users when you’ve tested their behavior, used contingency design, or acted in favor of your user when developing a site feature – feel free to leave me a comment.

Advertisements

Rolling with Rails 2.0RC1

I’ve never been a fan of using rake to download EdgeRails. To me it never seemed to make sense that you would make a Rails project generated by one version and then download the Edge version into the plugins directory. So with that in mind I’m going to tell you how I roll out EdgeRails projects and in turn show you how to download Rails 2.0RC1 and generate a project with it.

Before I get into it though, I’m expecting that you have a development environment already running. I expect that you already have rake, ruby, rails, svn, and all that other stuff installed. If you don’t, please see one of the thousand Internet posts on how to do that or the many chapters in books that cover it. Okay, now that we are on the same page – let’s get moving.Let’s open up your command line terminal. Go into wherever you create your projects in Rails and make a new directory for your new project:

mkdir -p new_project/vendor

The -p variable creates both the new_project directory and the vendor directory inside it (depends of course on your OS, you could always just create both manually). Go into the directory:

cd new_project

Now, run SVN and checkout 2.0RC1 into the vendor/rails directory.

svn co http://dev.rubyonrails.org/svn/rails/tags/rel_2-0-0_RC1 vendor/rails

Now from the project directory (new_project) run the rails script within the vendor directory.

ruby vendor/rails/railties/bin/rails .

That will execute the rails script on the current directory. You basically just did the same thing as executing “rails new_project”. That’s it, you’ve now checked out Rails 2.0RC1 and created the base project. Now get started…Have fun.

Update:

This morning (November 29th) the Rails team has released RC2 so if you are wanting to check out RC2 – use the svn checkout command of:

svn co http://dev.rubyonrails.org/svn/rails/tags/rel_2-0-0_RC2 vendor/rails

Making Configuration Files with YAML

Update: A newer version of how I load YAML into configuration files in my projects can be found here.

Since being introduced to YAML I’ve loved using it for configuration files in both Ruby and Ruby on Rails. YAML means “YAML Ain’t Markup Language”. Yes, there is an infinite loop in the title – it’s programmer humor. Those of you familiar with Ruby on Rails are somewhat familiar with YAML because that is the format of the database.yml configuration file. So this is a sample of what a YAML file typically looks like:

development:
	adapter: mysql
	database: project_development
	username: root
	password:
	socket: /tmp/mysql.sock

This is a snippet out of the database.yml file. But one of the great things about Ruby is that writing code to read YAML is extremely simple. Let’s say I want to make a website configuration file, this is what that might look like:

config:
	title: My Rails Website
	author: Santa Claus
	email: email@company.com
	css_file: default.css

The hardest part is thinking about what type of information you want to store in your configuration, the Ruby is extremely easy. Check it out…

First we require the YAML library:

require 'yaml'

Ok, now we can make a read_config method:

def read_config
	config = YAML.load_file("config.yaml")
	@title = config["config"]["title"]
	@author = config["config"]["author"]
	@email = config["config"]["email"]
	@css_file = config["config"]["css_file"]
end

Seriously, that’s it (of course you need to execute the method). We just load the YAML into a local variable. Then we spider down the YAML document using the local variable that we assigned the loaded YAML document. So where you see “config” in quotes that is referring to the “config:” within the YAML document. Of course, were I say “config.yaml” you would actually put the path to your specific YAML document. One the information is loaded, I pull the data I want into a few instance variables making them accessible to my views (in Rails).

Update:

A more efficient way to do this would be to loop through the hash that is created by the read_config method and just set the key to an instance variable, like so:

config["config"].each { |key, value| instance_variable_set("@#{key}", value) }

Update: A newer version of how I load YAML into configuration files in my projects can be found here.

Formatting Names Using Ruby

Getting information from users is a common task that we have to deal with in building an application. This typically happens either in creating a user account, commerce orders, or any other time when the application has to ask “who are you?”. Often times we’ll create a field for both a firstname and a lastname allowing the user to separate their names to make it easier for us (the application developer) to display either/or both. In this post, I’m going to talk about how we can format full names given to the application by the user without necessarily worrying about creating two textfields. Of course, you would use this code in the methods within a Rails app.

So let’s say I have a variable for creative purposes, I’ll call it ‘name’ and ‘name’ has a value.

name = “James Earl Jones”

And I want to only display the first and last name of my ‘name’ value I could do this:

names = name.split
firstname = names.first
lastname = names.last

Now this splits the three words in ‘name’ into an array. I then set firstname as the first item from the array, and set lastname as the last item from the array.

Running:
p “#{firstname} #{lastname}”

Would then output:
“James Jones”

How about we do another common formatting task we can to show the last name first separated with a comma the rest of the name, we could do this:

names = name.split
lastname = names.pop
firstname_remaining = names.join(‘ ‘)

Here we split the name up again, put then ran the pop method which pulls the last time of the array out of the array and then returns it. This would leave only the remaining name left to work with as the firstname_remaining variable. I them join the rest of the array with spaces for the firstname_remaining (which would include the first name and any remain name information like a middle name).

Running:
p “#{lastname}, #{firstname_remaining}”

Would then output:
“Jones, James Earl”

Lastly, a common thing I’ve been seeing lately is the usage of the last initial when showing a user’s name. We could do something like this:

names = name.split
firstname = names.first
lastinitial = names.last[0,1]

Here I’m introducing some trimming for the lastinitial variable. You see this with a bracket and two numbers. The first number is the offset in the string that I’m trimming (zero is the first letter is a string), the next number is how many characters I’m showing from that offset.

Running:
p “#{firstname} #{lastinitial}.”

Would then output:
“James J.”

So that’s it for now. Of course you might think about adapting this to users that will have items at the end of their name like “Jr.” – this can sometimes just be solved using a drop-down.  I’m hoping that perhaps I have introduced you to some things in Ruby that you might have been previously unaware of. Until next time.

Card Sorting Your Way to an Improved User Experience

The Internet really brings some great benefits in further making information that normally wouldn’t be easy to find more accessible to the masses. The phrase “information in power” is often quoted, and just as with power, with great information comes great responsibility to those users who might need to find something amongst that information. Card sorting is a common practice in information organization that has been used in the web by information architects and designers since the mid 90’s.

All of us have our own way of looking at multiple items and categorizing them into groups, often times however the people we might be categorizing them for would have sorted them a far different way. This is where card sorting plays it’s role, it offers us a peek at how the users of a website might categorize (and thus search for) information on an ecommerce or large-scale information rich website.

It’s really simple to get started; a card sorting session doesn’t need to be overly technical by any means and is very cheap to execute. A Sharpie or pen and a stack of index cards are all the supplies you will need. Then there are the participants… if you have a physical store, ask some of your repeat customers. If it’s a company or organization, ask your clients or members. The key rule is, if you are a stakeholder in the website you aren’t allowed to do any sorting. Just watch and listen.

Using the index cards, write the names of the items you are trying to sort on the cards. Use only one item per card. For example, if I am making a cooking website perhaps I want to sort recipes, so my first card might read, “Lasagna”. Then for each additional recipe I would continue to write the name of a recipe down on it’s own individual card.

card-sorting-web.jpg

TWO TYPES OF CARD SORTING EXERCISES
With your cards ready to go there are two primary ways a participant might work with the cards:

Open Sorting is a session in which there are no pre-established groupings. It is up to the participants themselves to determine the groups of items and the names they would call the groups. If you can, this is by far the best way that you will understand how a user of your website will be looking for information. You will be able to gather far better results if you ask them to sort the items without restriction.

Closed Sorting is a little less helpful in my personal opinion as you have already created pre-established groups for the participant to sort their items into. For example, on my fictitious cooking website I might have told the participant to sort them into groups of “Italian”, “Mexican”, “Desserts”, and “Other”. To really mix things up I could add groups of “Pasta”, “Pastry”, and “Poultry” to give them some options that might give me a further understanding on how people might use my cooking website. Most designers and architects, myself included, do not encourage closed sorting because of the general restrictions on the results gathered.

The procedure is really just that simple. Take your stack of index cards and ask your participant to sort the items on the cards, as they feel most comfortable. There are no rules, or wrong answers. Don’t give clues of, “well that item has pasta in it, are you sure you want to put it there?” Just hand them the cards, and get out of their way. When the sorting is over feel free to ask questions to better understand their approach so you might best understand your website users behavior when looking through your products or information.

Remember also that your results will vary. You might find in some cases that your various participants are very consistent in their organizational style, while other times you might find that they vary widely. Don’t get discouraged, and realize that this is just a tool to help you understand your users, it is not a silver bullet to perfect organizational design and it may not apply as well to all websites being developed. No one is grading you here, so take your time and have fun with it.

Silencing Rails Logs for Security

For those of you that are already familiar with the Rails framework you already know that the Rails logs are completely invaluable when it comes to debugging and troubleshooting issues.  However, just as with any form of transaction logs they introduce a major security issue.

Just think about some of that information that you might be storing in your database… credit card numbers?, social security numbers?, or what about passwords?  Imagine someone getting a hold of those logs and seeing all the session parameters being passed into the database.  Inserting the credit card numbers into an order, selecting the user information based on a username and password combination.  See the point I’m making here?  Let’s look at a quick example of what you’ll see in your logs:

Parameters: {“model”=>{“username”=>”John”, “password”=>”hax0r”}…

Not good.

Thankfully Rails makes it simple to filter this important material from your logs.  Just open up the model that you want to filter and add a single line just below the class definition:

class Model < ActiveRecord::Base
filter_parameter_logging :password

end

In this case I just filtered “password”, but you could filter whatever else you wanted to for that model, separating each parameter with a comma, like such:

filter_parameter_logging :password, :confirm_password, :ssn, :creditcard_number, :etc

It’s that’s simple.  So keep those Rails logs secure and filter out the stuff that others don’t need to know.