Latest Entries »

Making Configuration Files with YAML: Revised

So back in July 2007 I posted a blog on making configuration files with YAML, and I’ve been noticing a lot of readership on the old article. Because it seems that a lot of people are reading it I felt it was important to show how I apply this nowadays.

First I put my config.yml file within the /config/ directory within my Rails application. It looks something like this:

development: &non_production_settings
  :google_analytics:
    :api_key: "[Enter Google ID]"
  :site:
    :title: "[Title]"
    :address: "http://localhost:3000/"

test:
  <<: *non_production_settings

production:
  :google_analytics:
    :api_key: "[Enter Google ID]"
  :site:
    :title: "[Title]"
    :address: "[Address]"

Then, I create a new file called load_config.rb within the /config/initializers directory. You can name the file whatever you want – that’s just what I call it. This is where the actually YAML loading is going to happen – and this is what it looks like:

raw_config = File.read(RAILS_ROOT + "/config/config.yml")
APP_CONFIG = YAML.load(raw_config)[RAILS_ENV]

Now any time I want to all one of these variables I just call it like:

<%= APP_CONFIG[:site][:title] %>

To start 2009 this will be one of the first of many business oriented posts coming to this blog. It’s great to be a technologist, but it’s important we as technologists can do something with our ideas. So I hope to provide some benefit to those of you willing to listen.

The biggest thing every executive needs to run a successful company is a vision – you can’t do crap without a vision of what it looks like. I’m not talking about a 5-year plan, or a 10-year plan… I’m talking about an idea. What do you want to be? Who are you in the realm of all of your competitors? If you don’t know this, why come in the office in the morning? What pushes you to get up everyday? There has got to be something… and that’s the first step – figure out what it is.

Once you’ve got the idea figured out, don’t tell everyone about it by commanding they follow behind you, because people will get lost and it will slow the entire process down.

Think about it for a second. If a group of people in several cars are all trying to get to the same place, but only the person in the front of the line knows how to get there. With every stop sign and stop light, every turn, and every interruption the people in the line have to check where the leader is… and in turn the leader needs to check that everyone is behind him. So instead of commanding, give everyone the map, explain the vision, and explain how they fit into the vision of what’s going on. Then with the map in hand they can get to the destination in their own right. Give your people the freedom to make small course changes on the way, side streets or pit stops, they’ll meet you at the finish line.

Let’s say part of the corporate vision is to provide a superior user experience in all of your software. If you share the map and embed that ideal in your corporate culture you’ll see how people will take charge. Jill in QA will consider it when testing. Bob in design will research the best user experience paradigm in his interface, just as Sam will do the same when programming the front end.

Have a vision, build a culture around the vision, and then let the smart people work.

Professional Goals for 2009

So I’ve seeing a lot of people writing on their blogs about their general goals for the upcoming year. So I thought for the purpose of reminding myself every time I came here I would write mine up as well.

  1. Continue my work/learning Ruby and Rails
  2. Go back to learning C
  3. Learn Objective-C
  4. Continue my business/executive training
  5. Blog more of course
  6. Continue advancing my knowledge of Agile methodologies
  7. See team camaraderie at my day job increase
  8. Really start following TDD/BDD principles

So with that in mind… HAPPY NEW YEAR!

Optimizing the RedCloth Helper

In my previous post I posted several small Rails tips, one of which was a cleaner RedCloth helper. Unfortunately, this helper requires that the textile is parsed each time the page is loaded, and that can get nasty. So it our item is a text field called details, just add a details_html field to your model… then create a private conversion method that you call using a before_filter.

Something like:

before_filter :convert_details

def convert_details
  return if self.details.nil?
  self.details_html = RedCloth.new(self.details).to_html
end 

Then just display details_html in your view instead. This way the textile only gets converted when you save and make changes to it.

Rails Tip Roundup

I’ve been working on a few new projects lately and wanted to share a few little tips I’ve started doing.

Conditional Buttons for Shared Forms

Something that I like to do is use a shared form for both my edit and new views. Doing this however means I need to be friendly to the user interface and make sure the submit button is properly instructional. So for example if I have a Customer model with an instance variable @customer my button would look like this:

<%= f.submit((@customer.new_record? ? "Create" : "Update") + " Customer") %>

With this I’m checking to see if the @customer instance variable belongs to a new record and if so it’s outputs Create, otherwise it’s an Update button.

Cleaner RedCloth Helper

There is the built-in textile helper that comes with Rails, it’s carage return rendering is a bit lame so most people typically upgrade their RedCloth gem and using something like:

<%= RedCloth.new("My copy that requires formatting").to_html =>

I prefer to instead create an application level helper for redcloth (some people might instead overwrite the textile helper here, but I find that can be confusing to some people looking at your code for the first time). My helper looks like this:

def redcloth(str)
   RedCloth.new(str).to_html
end

So now when I want to redcloth something I just call:

<%= redcloth("My copy that requires formatting") %>

Simple Little Permalink

When I have a simple object that I want to create more user-friendly URLs for, I’ll create a basic permalink. In the instance of the same Customer model from tip 1 above, I like to use the customer name as the permalink. To do this of course the name has to be unique so make sure you are validating it’s uniquiness above all. Then I create a permalink column in the database table and write something like this in my model.

def name=(value)
  write_attribute :name, value
  write_attribute :permalink, value.gsub(/\s/, "-").gsub(/[^\w-]/, '').downcase
end

def to_param
  permalink
end

This uses the value of the name that is entered, clears it of puncuation, replaces spaces with hyphens and drops the casing. The first line makes sure it still remembers it needs to write the value itself to the name column in the model.

Now it’s still important that you confirm that the permalink is unique too, but I’ll let you do that on your own.

So that’s it – I hope you guys find it useful.

I’ve noticed that I have a tendency to prefer CVS as my general drug store. Now, while any prescriptions I need filled are done at Publix, I let CVS handle the generalities. But several years ago CVS did something… they created a loyalty program. At first I didn’t mind so much, they handed me card that I was required to fill out and send it in and with that I would receive “special discounts”. I went home unpacked my purchases and there the form sat for about a week until I got tired of seeing it and threw it away. But every time I go to CVS they try to give me another one. Sometimes if I just said “no, thanks” they would covertly add it into my shopping bag to be discovered once I returned home. I’ve gotten to the point now that I say, “no thank you, I have about 6 of your cards at home and I never bring a single one with me.” Sometimes I would watch as the clerk would simply scan their own cards, a ritual I could tell they had done more then once from people not wishing to jump on the card-carrying program. Some stores held a barcode right on their registers that read, “For customers not wishing to join the program, still wishing to receive the special discounts.” The stores were doing what I often refer to as “Hacking the Interface”, they had something that they knew wasn’t working, that people didn’t want, and they found a way to easily get around the policy.

The bookstore that I once frequented (and was a member of their “discount” customer loyalty program) has changed their direction in the way they wish to represent their business and the products they offer. After a few experiences with this bookseller after their makeover I realized that my discount card didn’t mean much to me if I didn’t like going to the store anymore. I paid $10 a year for that card, but the savings seemed of little value to me when I no longer enjoyed the experience of the store. I have since started shopping at another bookstore and have thrown their discount card away.

It’s About Gradual Engagement

Customer loyalty is a funny thing, something we often confuse with customer satisfaction. But customer loyalty will never be found in a card-carrying membership program or a points system. Often these programs guarantee that I (the customer) will have to maintain my information within your system to win awards that I don’t really care about, want, or that have any weight on my desire to do business with you as a company. They just stand in my way, and are annoying.

What customers want is a long-term engaging experience. Customer loyalty is created by several gradual experiences that cause that customer to continue to want a relationship with your company. Recently I purchased some Dvorak labeled covers for both my laptop and my keyboard at the office. Having not been satisfied by a previous cover I once purchased, I went to Google to find another company. The company I came across had one of the covers I was looking for but nothing for the office. I sent them an email saying what I was looking for and received an email back in about 30 minutes telling me that they were currently developing that product and that it would be available at the end of the month. He said, “Sorry we don’t have it for you now. I’ll send you an email when it’s finished up and we’ll give you free shipping on the order.” Sure enough around the end of the month I received an email from him telling me that they were available with a link to the product. Now the email could have been computer generated, but it was personalized and had his name on it, giving me the satisfaction that this individual emailed me back as promised.

So far I’ve had two great experiences with them. 1) They apologized for not having the product I hoped they would, gave me a discount on shipping when it was going to come in; and 2) Followed through on their promise to notify me when the product was available making it convenient for me to place my order. When I receive the covers, and if they are of the quality I expect – I will most definitely use them again, as the entire experience of my interactions with them have been very personable.

So what I’m trying to say is simple, the experiences you provide will build the loyalty that you are looking for. Don’t put programs in the way of buyers, most of them don’t care and find it a pain to deal with (and a poor experience by always being asked if they have their card). In a business world where things change just as fast as the technology we use to measure them it’s time to throw away our 12 year old copies of The Loyalty Effect and start building a more permanent bridge with customers that want to do business with us… not because they have our card in their wallet, but because they prefer the experience that our company provides and would come to us even while being a member of a competitor’s program.

Thoughts on Simplicity

Of the people who know me well, I think most of them would say that if I were fanatical over anything it would be the basic act of simplicity.  It sounds a bit funny, who would want to make something more difficult, right?  But simplicity is far more difficult then just making something basic (or for that matter mediocre), it’s about a number of things.

Simplicity is about having a strong understanding of the people you are trying to assist in your desire to simplify.  Too often businesses seem to “simplify” processes for their own purpose, while making it much more difficult for their customers.  They don’t think about the benefits of simplification for those people using their products and services.  When was the last time you called the power, cable, or phone company only to be lead through a series of “press 1 now” circles thinking, “wow, this is really helpful to me”?  I can only imagine that you’ve never felt helped, but rather pushed away when reaching such a phone system.

As a programmer, I see simplicity in the foundations of our technologies.  Never have I heard from another developer, “I love this [programming] language, because it takes me so long to figure out how to solve a problem.”  Most of the developers I know select their preferred programming language because it follows a syntax their brain comprehends well and solves a problem effectively.  To them, it’s simple.

As a designer, I am reminded that simplicity is contextual.  Simplicity requires that you not forget your expert customers, allowing complexity when it might be needed.  It’s important that we consider balance in product design and in doing so we reduce the information we share with consumers to the most essential; by either its removal or by simply hiding it until it becomes essential.  Simplicity is partially the elimination of excess, as well as our effective use of emptiness and space to bring focus to the things that are important.  When was the last time you went to a website and didn’t know where to go to find what you were looking for, or spent 15 minutes trying to understand an online registration form?  It is about reducing the confusion and easing the minds of the people interacting with you.

Simplicity is about having a great understanding of the subject matter you are communicating, allowing you to speak of it concisely.  As a presenter and a writer, I find the more I speak or write about something, the less I need to say about it to share my point of vie.  Not that I know less, but simply I have a deeper understanding of the meaning behind the points I’m discussing.  Take the time to dig deeper into your area of expertise, know it from multiple angles.  It might just provide you with insight on how others view what you are communicating.

The next chance you get, think strongly about simplicity.  Whether it’s a new company policy, a new product, or maybe a new form you would like your clients to fill out.  Not just for your benefit, but for your clients, your employees, coworkers, vendors, and your family.  It just might change the way you see the world.

Genuinely Impressed By Rosenfeld Media

Let me start off my saying that no one is paying me or asking me to write any of this (or blackmailing me for that matter).  A few weeks ago I participated in Rosenfeld Media’s UX Zeitgeist and purchased their first published book Mental Models, by Indi Young around that time as well.  Rosenfeld Media is the new kid on the block for publishing houses, but I’m a fan of books written by co-founders of Adaptive Path (Observing the User Experience, Subject to Change, The Elements of User Experience, you get the idea).

I really enjoyed everything about my interaction with this company.  During my participation in the UX Zeitgeist I had a few questions for them and received really quick responses from Lou Rosenfeld, the company’s owner.  When I ordered the book, you also receive a copy of in PDF format (at no extra charge) so you can instantly start reading while you wait for the paper version to come by mail, that’s smart.  As they were working up their plan for publishing obviously someone realized that people would actually be reading the PDF documents on the screen because you can tell they were definitely optimized for screen display.  Seriously everyone; the book is amazing.  When the mailed book came (a few business days later) I was amazed at the thickness of the cover and the quality of the print.  Amongst all this praise for Rosenfeld I have to extend my hand to Indi as well for such a quality book.  Her concepts on really getting into the heads of users are amazing, and as I continue my way through the book you can expect a full review when I am finished.  For those of you interested in the book now, Rosenfeld Media is offering a special 10% discount to you, my readers, because I told them I’d be writing about my positive experiences and enjoyment of their first book.  Just order the book from their site, and use the discount code FOKNIGHT during your order to get the discount.

Rosenfeld Media’s next book is Web Form Design by Luke W., a person familiar to most of you I’m sure.

This is definitely the publishing company to keep your eyes on if you are a designer of user experiences.

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.

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