Thursday, December 20, 2007

CSS Inadequacies x Poor Browser Support = Hell

I don't spend as much time as most web designers probably do, creating CSS and XHTML layout from scratch. As a "corporate" designer, most of my time is spent maintaining an existing site. I only have to do substantial CSS and markup work when I redesign the site or add a substantial portion of content to it. So when I am tasked with creating a new CSS layout, I am always reminded of how I hate so many of the problems that exist with CSS and the browser support for it; especially in contrast with Flex (which I've been working with a lot lately). Although Flex has its own set of CSS and layout issues none are as severe as those with XHTML/CSS.

This post sums up a lot of the problems:

I'm not a n00b to CSS. I've been working with it since Netscape 4 barely supported CSS text formatting, and I was doing CSS-P well before most of my designer / developer peers were. But I still struggle with it for many reasons.

It's nearly impossible to create a complex layout without resigning to at least one of the following: employing hacks, giving in to div-itis, compromising your design, or breaking in anything but the most bleeding edge, standards-supporting browsers.

How often does separating content from presentation really work so well that you don't have to change your markup? I know, CSS Zen Garden does it. But that's ONE PAGE. If I have a site of 100+ pages, and maybe 5 or so different layouts (and possibly a mobile version) with umpteen variations in content, and I have to redesign, I have a lot more work cut out for me than just rewriting a style sheet and slicing some new images. Let the DRY approach belong to the programming, and use the "include" and layout rendering features of dynamic development languages. I'm going to be putting all my presentational markup in a couple CF templates anyhow. Semantic and clean markup is still good, and will prevent too much markup rewriting, but the bottom line is that you will still have to rework it.

The C in CSS should stand for Crap. The Cascade does not work. Oh, I know it "works." But more often than not, it gets in the way because it's not supported well enough to rely on it, but it works just enough to create random trickle-down issues. Dreamweaver actually created the "Relevant CSS" panel just to demystify the Cascade. If you can't get better control of where you're inheriting from, and what's relevant, then it just creates inheritance headaches.

I want to create a code-clean, reliably cross-browser compatible hack-free elastic layout without compromising my design or missing my deadline. Is that too much to ask? Apparently so.

End this war, impeach CSS.

Monday, December 17, 2007

Extending the Flex Currency Formatter

I was faced with a puzzling challenge this week on a Flex app I've been working on. I have a Flex DataGrid that is showing financial metrics - projected vs actual and the variance...a very common sales type of report. It breaks these metrics down by year, quarter and month.

Imagine it's September. Now you'll see in the grid above that October through December show 0's for the actual column, and a negative variance, but they are just months that haven't happened yet. One requirement we had for how these metrics display was that for time periods that haven't happened yet this year (IE next month, next quarter), we show a dash in the grid instead of a 0. It's all about the psychology of not making the report look overly negative :)

The challenge was that the way these numbers are displaying within the grid is via an ItemRenderer with a CurrencyFormatter. From within that item renderer, I don't have any access to data columns outside the immediate column. For instance, I could not refer to the Month column. Moreover, if I ever returned a value for that column that was a string and not numeric (I'm using a CFC on the back end), I couldn't use the CurrencyFormatter to nicely format my numbers with dollar signs and thousands separators.

I mulled over several evil sounding ways to make this work, and as I went to implement one of them, a much simpler solution struck me.

1. Within the CFC where I'm creating a collection of objects, I have access to other columns of data within the grid. Thus I can evaluate if the time period is in the future with a just a line of code.
2. Rather than returning the actual character I want to display (which won't work with the formatter), I replace the actual value of the "future" data with -1. This way, the data is still numeric, but it's not a number that will ever happen naturally. This seems to be a common programming trick - using negative numbers for "non-real" values. But because it's numeric, I can still use the currency formatter on the front end.
3. I create a custom ActionScript formatter on the front end which extends the CurrencyFormatter class. This formatter has two extra properties: replaceValue and replaceChar. replaceValue is the "fake" value I'm looking to replace, replaceChar is the character I want to replace it with . That way I can customize it at any time if say, we decide we want an x instead of a dash. Then within the formatter, I just compare the actual value with the replaceValue, and if they're equal, I return the replaceChar instead of the formatted string. Otherwise, I return the normal formatted string.

Here's the completed code for my ForecastCurrencyFormatter solution.

ColdFusion/Back End

<cfif dateOfMetric GT month(now())>

<cfset actualAmount = -1>

<cfset varianceAmount = -1>


Flex Formatter


package com.myFormatters {

import mx.formatters.CurrencyFormatter;
public class ForecastCurrencyFormatter extends CurrencyFormatter {

/*value to replace - defaults to -1*/

public var replaceValue:Number = -1;

/*character to replace with - defaults to a dash*/

public var replaceChar:String = '-';

public function ForecastCurrencyFormatter() {



//override the format method with my custom formatting

override public function format(value:Object):String {

/*if the number value is the value to replace, return the replacement character instead*/

if (value == replaceValue) {

return replaceChar;


/*otherwise just format according to the standard currency formatter*/

else {

return super.format(value);





Using the Formatter

<!-- at the root, declare a namespace for the formatter components -->

<?xml version="1.0" encoding="utf-8"?>

<mx:Canvas xmlns:mx=""
<!-- this is just one column within my datagrid, showing use of the formatter -->

<mx:DataGridColumn textAlign="right" headerText="Actual" sortable="false" dataField="actual">



<mx:VBox clipContent="false">

<fm:ForecastCurrencyFormatter replaceValue="-1" replaceChar="-" id="fcf" precision="0" thousandsSeparatorTo="," currencySymbol="$" alignSymbol="left" />

<mx:Text width="100%" text="{fcf.format(data.actual)}" />





That's about it. We now have a formatter that behaves just like the standard currency formatter, but with an additional formatting option.

Monday, December 3, 2007

People Who Inspire Action

In my day to day work, I deal with a variety of people of varying personalities and "working styles." I can be a real procrastinator when it comes to making and returning phone calls from these people because it requires putting down my work to make a call to someone who may not be there, to play phone tag, to end up on the phone with them for longer than necessary while they whine about a list of things they need from me resulting in hours of work on my part. Not necessarily something I'm motivated to do. Ok, not every exchange is like this, but in a support role such as that I'm in, it's very often the case.

However there are a few people I will always call back right away, and it's not because they never ask for anything (in fact many of them ask for a lot). The reason I'm motivated to call these people back? They have a positive attitude (it's not going to be a complainy conversation). They are willing to work together to get things done, and not try to shove all the work onto me. They keep it short and sweet. They are usually there when I call, or return my call within a few minutes. And when I give them what they ask for, they are appreciative and make me feel like the work I do is valuable. Working with - and calling these people is always a pleasure.

So...just a word of advice from my experience. If you want to inspire immediate action, develop a rapport with people such that they know you won't waste their time, and have an attitude that makes you pleasant to work with. It makes all the difference in your ability to get what you need from other people.

Friday, November 30, 2007

Sys-Con Does it Again

I never subscribed to CFDJ under my own name. I never signed up for a thing on their site (in fact I avoid going there at all costs). To my knowledge, I have never once given anyone there my email. Yet somehow, I got this email yesterday:

Dear Rachel,

Thank you for subscribing to ColdFusion Developer's Journal, published by
SYS-CON Media. ColdFusion Developer's Journal's commitment is to keep, by
email, its subscribers current on products and services from third party
advertisers that might be of interest to them. Each email message will
be preceded by the name of the company offering the product or service,
so that you know the source and purpose of the email before opening it.

If you do not wish to receive these informative emails, please follow
this link {removed} It will not affect your customer status in any manner.

Thank you,

577 Chestnut Ridge Road
Woodcliff Lake, NJ 07677-8409

Soooo.... not only have they falsely accused me of subscribing to CFDJ, but they're basically notifying me I've been added to their spam list. Great. Now I've got to click a link to be removed, confirming the validity of my email address for their future spam efforts.

I have no idea how they got my email... I hope for their own sake (ok, I really don't care about them all that much) they aren't harvesting emails off of community sites or other questionable sources.


Monday, November 19, 2007

I never thought I'd say this but...THANK YOU, Microsoft

Microsoft Announces that "click to activate" will be removed from IE effective April, 2008.

I've only wasted countless hours over 2 years of my life bothering with this stupid patent lawsuit fallout issue, and now that the general public of mediocre web designers have finally figured out what they need to do (or upgraded Dreamweaver) to get around it, it's not a necessity any more. Bah.

Nevertheless, it's nice to see M$ making a good choice. And I found it a little humorous that the reason they cite for making this change is "As a result of recent technology licenses acquired." Haha, I can just imagine the back office conversation: "What, they want to sue us for supporting embedded objects? Hell, just buy the damn company already!"

Wednesday, November 14, 2007


Sorry about the super geek-cliche title. I just wanted to make a quick post about the fact that my blog will soon have a point! I've been wallowing about posting on random topics over the past few months, hoping that a theme would emerge. I've drafted several posts and not actually posted them, because I was trying to decide if they are relevant to the purpose my blog does not yet have. Well, now I can say that with some thinking and Adam's strong urging, I've decided that my primary focus will be on the designer-developer, something I am intimately familiar with.

Being a designer and a developer, a front-to-back website or application creator is fun and challenging. I've asked myself many times if I should focus on one more heavily than the other, but it's so hard to choose. Ultimately, I think that being able to do both can be of immense value in many situations (at least my current employer seems to think so), so I'm going to work to promote a diverse skill set and to provide resources that help designer-developers grow in both directions.

Stay tuned!

Wednesday, October 31, 2007

You Too, Can be an AIR Developer!

Mozilla recently announced Prism, a tool for bringing web applications to the desktop. One of their first comments is comparing it to Adobe AIR and Silverlight, in an almost ignorant fashion:

"Unlike Adobe AIR and Microsoft Silverlight, we’re not building a proprietary platform to replace the web. We think the web is a powerful and open platform for this sort of innovation, so our goal is to identify and facilitate the development of enhancements that bring the advantages of desktop apps to the web platform."

It's a cool idea, clearly they see the need and are jumping on the bandwagon. But I think they, like many others, really misunderstand AIR. I'm surprised how many times I've seen Adobe AIR called a "proprietary" or closed technology platform lately, and how tightly its reputation is coupled to Flex and Flash. So many standardista/open source fanboys & girls are chasing alternatives because they think that AIR requires an investment in Flex and that you have to maintain a separate code base between AIR applications and "regular" web applications. Many confused developers think they need to learn something new to build apps for AIR. That is simply not the case! So I would like to point out a few facts:

  • AIR development does not require a specialized IDE or cost a thing to get started
    (download the free SDK)
  • AIR development can be done with any combination of static HTML, JavaScript, AJAX, dynamic HTML (IE server back end such as ColdFusion, ASP, PHP, Ruby...) AND Flash and Flex
    (About AIR)
  • Creating an AIR application out of an existing applications (or a new one) only requires configuration of a simple XML file. There are plugins for Dreamweaver and FlexBuilder to make it even easier.
    (getting started)
  • The FlexBuilder IDE which has a super simple AIR app wizard is available as a free public beta, and is also free for educational use
    (the education announcement)
  • The Flex SDK is STILL FREE if you want to develop for AIR in Flex and for some reason can't use FlexBuilder
    (download the free SDK)
  • Over and over, Adobe makes the point that they have designed AIR in such a way that developers can use their existing skills to develop desktop applications.
    (right on the AIR home page)
  • Prism does have the unique and interesting feature to give the user the choice to move an app to their desktop (IE Gmail), but does not yet include the first-class desktop presence or local data storage that AIR does. AIR, although in Beta, is really much farther along that Prism.

There you have it. There are no excuses to not learn AIR and start using it today. Adobe is not some evil mega-software company, they are creating kick-a** tools for developers that will become (or already are) incredibly valuable in our daily jobs.

Other web-to-desktop platforms sweating AIR's style:

Friday, October 19, 2007

Sunday, October 14, 2007

Practical Implementation of User Centered Design and Customer Focused Business

Last week I attended Adobe MAX in Chicago, which was by and large an excellent conference. You can see some of the many "wrap up" posts online for the good, bad and the ugly so I won't get into that. But I will talk about a few things that stuck out to me while I was there.

There was a track called "Inspire," which were several sessions given by gurus of various disciplines, speaking at a loftier, more theoretical level than most, designed to do as their name suggests. That and the inspire sessions had extra big projection screens and color changing stage lights (I kid you not). Actually, two of the Inspire sessions I attended left me feeling they were the best sessions of the conference, because I did come away inspired - and when you've seen it all from the technical sessions, inspiration is the best thing you can hope to get at these events. Along with a couple of these sessions I attended, there seemed to be a strong movement at the conference and among the people I spent time with there towards User Centered Design, and its marketing cousin Customer Focused Business.

You may say this is nothing new, but I have seen a deeper level of understanding and a higher level of awareness come to a predominantly developer audience than in previous years. And this is not limited to MAX, I'm seeing it everywhere. Every blog-reading, conference-attending, best-practicing, self-respecting web developer/designer knows that the purpose of design is not merely to "make it pretty" but rather to "make it usable", moreso than ever before. And this is great. But what bothers me is that if you ask most of these people for examples, or try to get into a deeper discussion with them, the conversation turns to the worn out examples of the iPod and the Wii, and also about how none of their bosses or project managers understand these things or will allow them time to accomplish them, and how they know how it should be done but it's somehow not happening in their job. What's more, I know from personally seeing the vast amount of crap on the web, that most of these designer-developers are not practicing the theory they are so passionate about.

When this really hit me was reflecting on my own work and attempting to measure to what extent I was practicing these principles I found so inspiring (yet not at all new). I somberly realized that I was probably not doing as good a job at this as I believe I have the capability to do. And why? I have a lot of the same excuses: I create a design that's centered around my understanding of what the users want, but when a boss comes along and says "I think we need to give more attention to this element" with no user-centered grounds for doing so (it's always a company objective), I diligently make the change and rarely argue. Usually under the guise of picking my battles. But what would really give me the confidence to argue against such a change is more experience, more practical knowledge and more history under my belt with such design.
And that's where I meander to my point. There is a plethora of information in this industry about the importance of user centered design and customer focused business, but so little information about the practical implementation of it!

Designers have all the forces of traditional businesses and non-web-savvy clients pushing them in the opposite direction, and it's going to be years until most businesses catch up with Apple and Target and Nintendo and Land's End. We need to be told step by step how to start such a movement from our lowly production positions and how to make it work, proving results, so that it can continue.

In parts 2 and 3, I will discuss my experience and thoughts on the practical aspects of User Centered Design and Customer Focused Business (because it so often ties into design).

Tuesday, September 18, 2007

Is it better to please everyone, or just the ones that matter?

A few different blog posts I've read today have somehow converged in my mind to make this point.

First is Seth Godin's Mean vs Median. This is a very important distinction that I first made a few years ago in analyzing statistics. Mainly, that Mean (average) means almost nothing. That's a blanket statement, but as far as analyzing marketing data, website statistics, etc, especially when your database is small, looking at the Median can give you a much clearer picture than looking at the Mean. The Median often gives you much more polarizing information.

Which brings me to my second point. Jason Delmore asked what people wanted from the next version of CF. He got a huge variety of disparate answers, they were all over the map. John Nack announced the new PhotoShop logo (which, by the way, I think is excellent - maybe I'll get around to writing more details about why) and got a hundred acid responses from designers about how their 3-year old nephew could have done better.

My point here? You can't please all the people, all of the time, and really - why would you want to? Pick who matters, pick the audience who is going to affect your bottom line, and do what they want. To hell with what everyone else wants. Be prepared to be unpopular, be prepared to be reviled. As long as those who hate you aren't the ones you're trying to please. I've worked in too many situations where people are afraid of polarizing opinions. But really that's the information that is most useful, because it gives you a very clear picture of what you need to do to improve. The worst feedback you can get is "average, so-so, 5 out of 10..." - how does that help? A product/service/widget that is only measured against an average can only ever be, well...average!

More on the importance of polarization in marketing:
Jeffrey Zeldman - "Maybe is one option too many"

Monday, September 10, 2007

Long Time Coming, Death of CFDJ

I think enough has been said about this on other blogs that adequately express my feelings on the subject, but I just love this blooper that Cliff caught...

Great find!

Tuesday, August 21, 2007

Hosting, the Happy Ending

Last weekend I completed the process of moving my site to Edge Web Hosting. It was the quickest, easiest, smoothest host move I've ever experienced. While in large part I believe this is actually due to my use of the ModelGlue framework which resulted in centralized configuration that takes minutes to update, I also have Edge to thank for getting my database moved before I even had my files uploaded.

I'm already liking several things about my new host. For one, their emails don't get automatically blocked by our office email firewall (more our mail host issue than the web host, but convenient nonetheless). They are also less restrictive on site settings - they configure the server for CFMAIL from the sandbox so I don't have to pass a server or password within my CFMAIL tags. Nice! The only tags they limit are CFREGISTRY and CFEXECUTE. At any rate, they have completely absolved me of any hesitation or anxiety that I had about moving off HostMySite.

Yesterday while attending the Air Tour I got an email notification from HostMySite that they would be upgrading my (new) CF7 Server (the one they moved me to given the issues we had) to CF8 this week. Instead of panicking, I just breathed a big sigh of relief that our site was moved and hell would not be repeating itself this week.

Friday, August 17, 2007

Hosting, Continued

So after spending the better part of my day (and night) working on getting my site back online, It was finally fully operational again around 7 this morning.

HostMySite's support was good - although I was talking to so many different people it was hard to keep track and I don't think they were talking much amongst themselves. At my pleading (around 4pm yesterday when it still wasn't online), they set me up with a new account on a different, CF 7 server. So I put the site to that server, and everything worked fine, with the exception of a few settings, DSN's and the like that had to be transferred too. Because they set up the new server with my same Control Panel login info, when I would log into the Control Panel to make changes, it would only affect the old site. I had to request all those updates directly from support, requests which they promptly (I was getting emails throughout the night) took care of.

However, the thing that has bothered me most about this ordeal is that with the last round of emails before I moved servers, support told me "it appears the timeout is happening at this CFLOOP tag, so why don't you try optimizing that section of the code and then it should run". Now, I hadn't uploaded anything to the site in days that should cause this sudden slowdown, and there is no part of my site that's complex enough (it's all basic database interaction, mostly selects, with small data sets) to bring a server to its knees like that. So after I took a few deep breaths, I emailed my rebuttal.

First off, the error I'm getting is inconsistent. It's always the same 500 - request timeout error. But the CFLOOP and line of code in the stack trace that it references varies between several different places. I've seen at least three different locations. They are all within the ModelGlue core, and once I saw an error within the ColdSpring core. Now I'm not saying anyone is exempt from bugs, but I just could not buy the idea that ModelGlue and ColdSpring are taking the server out with an infinite loop or such nonsense. These frameworks are used by hundreds of developers in major applications without such issues. And with all the talent and brains that's gone into developing them, the chance that the framework code, of all the code on my site, is what's causing the problem is about...oh...well...IMPOSSIBLE! No, the problem is that the server chokes at the first somewhat intense processing it comes across while loading the site, and the frameworks just happen to load first.

This is essentially what I told HMS, along with providing some screen shots of the different stack traces I was getting. Then I begged them - if there's any way they can explain how my code is causing the problem, and provide me with some more details (using the handy dandy CF server monitor that they should have), then I would be more than happy to investigate and fix whatever the problem is. Because I certainly don't want the problem to come back after I switch servers.

However the answer I got was "I can see what you are saying from the random errors however that was not what I experienced when attempting to troubleshoot the errors.

Please let us know when you have moved the site to the CF7 Server and we will do some comparing to see if we cannot narrow down the exact problem in the code and possibly even fix it."

So they've kindly offered to help, but still haven't provided me with any more details. If you ask me my personal opinion, I'd really like to stick with them on this. They have been (mostly) helpful and have catered to my demands. I'm sure that upgrading to CF8 has not been an easy thing for them, and I know they were offering beta hosting way back when, so they have probably tested the hell out of it. But then business decisions come into play, and my boss (CEO) and IT Director don't have the rapport with them that I do. So I have to make a tough decision to switch hosts.

I was not feeling very comfortable with the idea (I wanted to be sure the problem was not my code or CF8, rather than their server). But I talked to Edge Web Hosting, and they helped me feel a little better about it. Ok, I talked to a salesperson. But he definitely knew what he was talking about. They have an uptime guarantee that isn't limited to the network and hardware (after some investigation I saw that HMS only limits their guarantee to these items), and they have a maximum of 60 sites/users on any server at once with their Master CF plan. They seem more focused on quality than price, so it's more expensive. But it's still not a bad deal.

Is it just showing "action" without purpose to switch? Maybe. But I do feel like I'm getting a better plan with Edge. And it's not like I'll never go back to HMS. I'm still going to use CF 7 for the time being, just because I'm a little gun shy about jumping on the upgrade bandwagon before the host can prove they're ready, and I don't have an immediate need to switch to CF8 on the website.

To be sure that I wasn't going to have these same problems with a new host, and to confirm in my own mind that I'm not holding the host responsible for my errors, I played around with the old site on HMS' server and tried running some CFDUMPs without loading a framework. Voila, they worked. I tried just loading the application and framework but then aborting...500 error/timeout. Now a couple dumps are hardly enough to take down a server under heavy load, but I found it sort of disturbing that I simply could not get a framework to load, but was able to run CF without the frameworks just fine. My best guess is that the server is just really overloaded, and it can handle a couple variables but not say, parsing an xml file. I am determined to find out why my Model Glue site won't run on their CF8 server.

But I'll probably still spend my weekend moving hosts. Argh. I'll keep updating as I figure this out.

Thursday, August 16, 2007


You can now add me to the never-ending list of bloggers and commenters on the topic of "my once-trusty web host is failing me, who do you recommend?"

I've used HostMySite for years with multiple sites at multiple companies. They have always been outstanding. Never a problem, never unscheduled downtime, great support and communication. But last week, they upgraded to CF8, and in the process, seem to have fubar'd the server my site is on (the problem is not CF, it's a configuration issue). Since last week, my company's site has been completely down (as in server error 500) for at least 13 hours during business hours (that I have been counting, who knows what happens while I sleep). It's also been sluggish on several occasions. I'd like to stick it out with HMS because of their history of quality, and even as I search for alternatives, it seems no one can say enough about how great they are. It's just too bad that I'm not having the same experience with them anymore.

I've used CrystalTech, which I would rate "merely ok" - mostly because their control panel sucked (this was a few years ago - CF6.1 era - it's probably improved since then), and because their SQL Server was totally overloaded (it would take 30 minutes to load the list of databases on the server in to Enterprise Manager). I might consider going back, but considering HMS gets far better reviews, I have a hard time believing that CrystalTech would be a step up.

I've looked at CFDynamics but they are too limited in capabilities, and their bandwidth and storage limits are puny for the price (compared to HMS and CT).

Now I'm looking at Alentus, an Adobe-recommended host that also seems to get some good reviews. They do seem a little more expensive for the space. I'm not opposed to paying more than I do at HMS, although I don't feel our site is quite at a point where we need dedicated hosting. Mostly I just want to be sure that if I'm paying the higher prices, that the service level is better. Alentus does offer 99.999% uptime, compared to HostMySite's "99.9+" (as they list it on their site - what does + mean, anyway?!), and those last two 9's are looking mighty nice to me right now, since my current uptime (depending on how you calculate it) is around 99.98%. I'm not going to get into the whole BS-of-the-99.99%-claim... right now.

I'd give HMS another chance, except right now I'm looking like a big fat idiot to the other folks at my company who I sold on the switch to HMS when I started (because we were moving to CF)...and with my boss tossing out "99% uptime" bla bla bla's, I can't afford to tolerate a vendor that doesn't deliver.

Anyway, if anyone can recommend a fantabulous CF host or has experience with Alentus, I'd love to hear it.

Monday, August 6, 2007

The Value of a Good Brand & Reputation

One of the best little hole in the wall restaurants in this area was closed and then recently reopened when the owners were indicted on numerous charges of laundering money, embezzling and employing illegal immigrants.

Here's the thing. If you read this news story, on their first day of reopening, customers were lined up outside the restaurant before it opened, and it was packed all day. Perhaps some were there to show support for this favorite char broil-chicken joint, but I am willing to be the majority were there just for the great food.

You see, every time I've been to this restaurant, no matter what time of day or what day of the week, there is a line out the door. But it's not for service, the workers there speak little to no english and aren't particularly friendly (they seem to care more about speed, and serving the line as quickly as possible). And it's not for atmosphere; the restaurant is basically a dump and even if you could find an empty table, it would be dirty from the last person to sit there. No, the people go there because it is simply the best chicken you will ever eat, and you'll pay the same price you would at any other limited service/carry out restaurant - around $8 for a generous entree with a side.

Why am I making a big deal out of this? Because your product, your reputation, your brand, has to be truly amazing to have this sort of a comeback after the way this places was shut down a few weeks ago. I can say with some certainty that any other restaurant in the county would be gone for good if something like this happened to them.

Think what you want about the fact that the owners broke the law in so many ways, you have to congratulate them for having such an outstanding product. We'll see how things go in the longer term (who knows if they will be able to remain open when the law suit pans out), but just remember that if your business' product is really remarkable, the benefits can be beyond measure.

Tuesday, July 10, 2007

Free AIR! (e-book)

The Adobe AIR team has made their O'Reilly book, Adobe AIR for JavaScript Developers available for free under Creative Commons License:

Download the Free AIR Book

I understand you can also get a free print version by visiting one of the AIR bus tour events. Thanks, AIR team!

Friday, July 6, 2007

Create a custom Excel color palette

Microsoft Excel was never meant to be a graphic layout tool, but that doesn't eliminate the need for Excel documents to look nice. I work for a financial firm, so naturally we do a LOT with Excel, and I'm always being sent Excel files to "make pretty", or given spreadsheets for reports and presentations that must look nice. After getting really tired of manually tweaking Excel colors to match company colors and de-uglify spreadsheets, I finally put together a complete custom palette that incorporates our company colors, logo colors, and coordinating colors of various hues.

Did you know that you can actually customize every color available in the Excel palette, and then apply it to any spreadsheet? Here's how to design a custom Excel color palette so you can define your colors once and never have to worry about them again...and easily apply your color variations to existing spreadsheet.

1. Plan the palette
Take a look at the standard Excel color palette. It contains black, white, a range of grays and then several primary colors in varying tints. In other words, a selection of primary colors and tings and shades of those colors. When you design your own color palette, consider how your company color palette maps to these swatches. So if your company color is green, you probably want to replace all the greens in the Excel palette with tints (lighter) and shades (darker) of your company's green color. Most likely you also have other colors you frequently use, so in your custom palette you'll want to place these colors in the location that's closest to that color.

Keeping your custom colors in the closest possible palette location to their equivalent in the standard Excel palette ensures that when you apply your palette to a document with colors already used, that the colors stay relatively the same, but with the proper shades assigned.

2. Set up the document
The way I went about designing my custom palette was to create a series of square blocks in Illustrator (you can also use PhotoShop or any good graphics tool with color capabilities, but you'll see in a minute why Illustrator is great for this), 8 blocks wide and 5 blocks high. This replicates the number and location of the swatches in Excel.

Set up the document - notice I've pasted a screen shot of the Excel color menu for a reference

3. Define the colors you know you'll need
Then, I colored the blocks corresponding to their location on the palette with the colors I knew I wanted - black, white, grays, and my company's main logo color, picking the location on the grid that was closest to my custom color. This left me with about 75% of my blocks still uncolored. Then I used Illustrator's Color Guide palette and Live Color dialog to expand on these colors (which makes it super fast and easy to create complete palettes - hence the reason for using Illustrator!).

These were my starting colors - colors from our existing palette.

4.Fill in any missing color spots with a coordinating equivalent
The color guide can show lots of variations on the selected color, by tint/shade or vivid/muted, so most of the work of creating new shades of my primary colors was already done for me, it was just a matter of picking what looked good. I added lighter tints and darker shades of my starting colors. Then I picked a coordinating color from each hue in the spectrum (red, orange, yellow, green, blue and purple) to be my "base" colors. I put these colors in the second row from the top, which seemed to be the closest hue/value match for them.

For the blocks directly below those colors (lighter shades of those colors), I created a discreet series of tints, starting with 80%, then 60%, 40%, and 20%. This created a nice variation of tints that should work for many uses. After this there were a couple blocks left over, so I filled those with neutral browns and tans.

My complete Palette, in Illustrator

5. Bring your palette into Excel
Now I had a complete color palette, which I needed to bring into Excel. This was the "there's no way around it" un-fun part. Open a blank spreadsheet, go to Tools > Options and pick the Color tab. Here you can select each color in the palette and hit the "Modify" button to change it. If you go to the custom tab in the Modify dialog, you can type in custom RGB values. Go back to Illustrator, and get the RGB value of each color block, and transfer it to Excel. Having the color palette open and displaying the RGB values for the selected color in Illustrator makes this easier. Manually go through every color in the Excel palette and change it to your custom color. Don't forget to save the document early on so it starts auto saving, because this takes awhile and God forbid you lose this work!

6. Use the palette
Once you've assigned all your colors, save the document in a place you'll remember. Then to use it, open up both your color palette spreadsheet and the document you want to colorize. Go to Tools > Options in your working document, and go to the Colors tab. You'll see at the bottom of this dialog there is a drop down of all open documents, with an option to "Copy colors from" (see figure above). Select your palette document, and hit OK, which copies the colors from it to your new document. Viola, your custom colors are now available in your new document! If there were colors already assigned in your new spreadsheet, they should have shifted to match your new palette.

I also colored the cells in the first sheet of my custom palette spreadsheet with one cell corresponding to each color in the palette, just so it was obvious what was in that document (since the color settings are not initially invisible) and so you can get a bigger preview of all the colors for future modifications. This is also helpful for when you share the sheet with others. You may also want to try printing your swatches just to be sure they still look good when printed.

Update: if you'd like a copy of this palette, you can download it from the link below, via Adobe SHARE!

Tuesday, July 3, 2007

Amateur Alert: "site designed by..."

One of my favorite "mean things to do on the web" is to click on those little links some web design firms put on their clients' sites that say "site designed by" or "powered by" (insert company name and link here)...then I visit the designer's site and point and laugh. Better than flaming someone, right?

Don't I sound horrible and cruel? But seriously, I don't know that I've ever seen this "stamp" on a well-designed, professional site. If your site looks like this, the last thing you want to do is draw attention to the fact that it's your work. Some may claim that their clients don't mind this, but I don't buy that. When I started at my first company, the first think they asked me to do to their website was to remove all references to the design company that created it. They did not realize that they had a choice in whether to put it there in the first place.

Putting your name on a client's site is rarely an acceptable practice. The one case where I really think it's ok to add a credit is if you have volunteered design services for say, an open source or community site. Then, you've probably donated the design and perhaps you deserve a link. But still, the more professional way to handle it is to mention your company as a news item or press release on the new site when it launches. For example, "we're pleased to announce the launch of our new site, designed by XYZ Web Design".

Or you could take it a little farther and spin it as a "partnership" project between your company and the client, with some nice quotes about how you worked together to develop an innovative site. If you constrain your "credit" to the launch of the site, it also limits your implied responsibility for the design of the site years down the road when it's horribly outdated and your work has drastically improved!

Just putting your name and link on your client's site (no matter how small or out of the way) because it's part of your contract and that's how you intend to spread your name is simply not professional. Your work should speak for itself. If your client is truly happy, they will spread your name on their own. People will compliment their site and the client will say "thanks, I had this great little company develop it..."

Instead, use your portfolio on your own website, and show off your client sites there with actual links to demonstrate that the site is still being used and it works, and that it's not student work or spec work. A quote from the client can also validate this. And nothing looks worse than when you show a pixel-perfect mock-up in your portfolio, but if you actually visit the site it's a mess. You can't fake good work.

Let your work speak louder than a link that some client was forced to put on their site.

Wednesday, June 20, 2007

Web/HTML editors that won't die

I may be a little late to the party in discussing this, but I just came across some info on the MS Office website about FrontPage going away. It's not surprising with the release of MS Expression Web, but it's been around for so long I thought it would never go away. After all, Adobe recently released a new version of GoLive! (I will never understand.) However, MS appears to be reincarnating FrontPage as SharePoint Designer, the new tool for designing and customizing SharePoint pages.

For those who haven't had the joy of working with SharePoint, you have to use Front Page to edit Sharepoint pages (beyond the built in tools) because of how everything is stored in the database. "Normal" web editor tools don't understand SharePoint-ese. SharePoint is the only reason I had FrontPage on my computer at my last job.

As much as I <3 Sharepoint, it sort of irks me that I have to buy a separate tool to modify HTML and CSS for it when I have thousands of dollars worth of other software designed just for that already on my machine. (Speaking of which, after about 3 days of use, I have determined that SharePoint 3.0 rocks.)

I was never much of a FrontPage fan otherwise (as soon as I had to write any substantial amount of HTML I snagged myself some Dreamweaver 3.0), but I thought I would never see the day that FrontPage dies, and here we are... where are the tears?

Speaking of dead software, CFMX 6.1 has been EOL' about that?! That actually seemed soon to me, but then again I'm not sure how long they typically keep these products around. From what I have read it seems to be a very good decision. I always like being on the bleeding edge of software versions, and I hate to think of all the time that goes to maintaining old versions that could be put towards new features. Or those poor developers who work on products that have been replaced by newer and better products within the same company...

So here's to euthanizing old software!

Monday, June 11, 2007

Apollo is Now AIR (and in Beta!)

Last week I finally got around to poking around in Apollo, and I'm really excited about it. I went back today, and it's now called Air, and in Beta! Super Cool.


I'm going to use it to deploy a Flex application to desktop at my company. This particular application was originally "dreamed" to be everyone's desktop. Not ON everyone's desktop, but their actual desktop (the vision was that everyone would have it open all the time). Being able to have it on the desktop without a browser is going to be great for us. My users have also requested system tray notifications, so I'm looking forward to learning more about that with Air. I'll make updates as I figure it out :)

Thursday, May 31, 2007

Microsoft Surface: BA Interface

If you haven't seen this yet, you have to check out Microsoft Surface:

When someone else told me about it, I was kind of ho-hum on the idea. But seeing it in action with this video makes it look really bad ass! The surface of the table-computer is multi-touch, so you can manipulate the screen at multiple points, such as for interacting with images, video, and maps. One really cool feature is how it recognizes objects that you set on it, such as wireless devices, so it can read images and files that are stored in the device. Place a digital camera on the surface, and it pulls up all the images on the camera. I want one, now!

This is quite possibly the coolest thing I have seen Microsoft do. I hope it runs on a somewhat standard Windows OS because it's a prime candidate for Flash/Flex interfaces (or as MS sees it, for Silverlight...).

Friday, May 18, 2007

Book Review: Pop!

I knew when I started this blog that doing book reviews would be a frequent topic, but I have yet to write one. I guess things have been pretty busy over the past couple months and I haven't read as many books as usual. But I am indeed a bookworm, and reading tech books has probably exponentially multiplied the number of pages I will read in my life. So with this, I am to share some of that bookwormedness with the world.

This review is for the book POP! Stand Out in Any Crowd, by Sam Horn. It may seem redundant to review this book when it's getting such great reviews on Amazon, but I really enjoyed it.

The topic of POP is just what it sounds like from the title. The interesting thing is that it's not just about business, or design, or marketing. The principles can apply in almost any circumstances where standing out is important. Which is everywhere.

POP stands for "Purposeful", "Original" and "Pithy". The book covers, in a very methodical way (great for analytical people like me), several processes, methods and inspiration sources for creating original ideas and "buzz" to surround them. So you've got a great idea? How do you make it exciting and unique to the rest of the world?

Purposeful, the first P, is for "accurately articulating the essence of you and your offering." Your message must have meaning. O is for Original, because "no matter what you are saying or selling, you are one of many" and you need to distinguish yourself. Pithy is short - it must be concise so that people remember and it "sticks". No one has a long attention span these days, so your message must be conveyable in just a few words. Being purposeful (focused) helps here too.

Beginning with Purposeful, it goes into a very in-depth, soul-searching analysis of your subject, whether it is your product, business, or yourself - and forces you to define its meaning and purpose. Sam has you create what she calls a "W9" form. That terminology bugged me a little (I have been known to argue semantics...) as the "W9" form in the book has nothing to do with IRS forms (which had also been on my mind because of the HR kit we're developing at work, and the recent tax season). But get past the choice of title, and the W9 is something every business needs. The W9 is a series of 9 questions, all beginning with W.
  1. What am I offering?
  2. What problem does my idea solve?
  3. Why is it worth trying and buying?
  4. Who is my target audience?
  5. Who am I and what are my credentials?
  6. Who are my competitors and how am I different from them?
  7. What resistance or objections will people have to this?
  8. What is the purpose of my pitch?
  9. When, where and how do I want people to take action?
Now if you've read other books about branding, these will sound familiar, and probably feel a little regurgitated. But what follows in the book are excellent examples and definitions of how to answer these questions that is quite different from what you might come up with if you only read that list. Trust me, I've been through this exercise with my employer(s) too many times to count, and I got so tired of hearing the same old automatic responses that we always spouted, none of which were, well, POP! But the way the author teaches you to explore these questions can and will yield much better results than you thought possible. In fact, I did it for a project I was working on at the time, and I've probably never been happier with the results.

The writing of the W9 leads to a list of "core words" that are related to your product, which then become a resource for the rest of the book: techniques for creating interesting phrases, terms and ideas relating to your product.

Some of these techniques you probably already employ in your brainstorming, many are "old standbys" but there are also some new and different ones. And most importantly, they are all here, explained and exemplified and in one place. In addition, completing the first section of the book with the W9 and Core Words before trying these techniques will make you more productive than ever in using these techniques. So even if you have used them before, they will yield new results given your new focus. By the time you exhaust these techniques with your list of core words, if you've really tried, you WILL have come up with some real breakthroughs.

Along the way, the book gives some good advice for presenting and pitching, and connecting better with your audience. Overall, I found this book to be very useful with "real" benefits, unlike many branding books that are fun to read but don't ultimately get you anywhere. I would recommend this book, whether or not your job involves marketing and branding. It will help you discover creativity you didn't know you had!

Tuesday, May 15, 2007

Calculate Business Days with ActionScript

Here's a quick function for calculating business days with ActionScript 3. I've found similar functions in other languages but there doesn't seem to be anything out there yet for here ya go!

public static const millisecondsPerDay:int = 1000 * 60 * 60 * 24;

public function businessDaysElapsed(date1:Date,date2:Date):int {
var numberOfDays:int = 0;

while (date1 < date2) {
//increment date by a day
date1.setTime(date1.getTime() + millisecondsPerDay);
//if day is between monday and friday, add one day
if ( >= 1 && <=5) {
numberOfDays ++
return numberOfDays;

Friday, May 11, 2007

Belated CF Objective Wrap Up

I'm finally starting to get my head back above water at work after returning from CF.Objective(), so I thought I'd share some of my experience. The conference was great! A huge improvement over last year, which itself was excellent, and what high quality content. I can't say enough.

The big topics at the conference this year were Scorpio and ColdSpring. Maybe I say ColdSpring because about half the sessions I attended at least mentioned it, or maybe because I was hanging out with Adam (ColdSpring's self-appointed agent) , Chris and Dave. But since I've been using ColdSpring and MG:Unity, without really understanding ColdSpring all that well, I thought I should get to know it a little better. Hey, I'm a designer - it takes me awhile to grasp these things!

And of course, what everyone wants to hear...what's coming with Scorpio? I'm really excited about several things that were announced
  • AJAX tags - there are 12 new ones! Not just new UI widgets using the YUI library while wrapping it up into the ever-simple CF syntax; but also JSON serialization for CFCs, data binding, error handling, and a JavaScript debugger. A lot of the concepts seem to echo Flex, so if you've done any work with Flex these features will come very naturally. This is just one more step towards my life goal of never having to write JavaScript again :)
  • PDF tags - not just improvements to , but which allows you to manipulate PDFs in dozens of ways (combining docs, watermarking, rotating pages, etc), and process Acrobat Forms. The functionality is taken from LiveCycle, and from what I hear, we should all be very appreciative of the power that's being added to CF at a fraction of what it would cost to get LiveCycle. A very SMALL fraction. A few people grumbled that you won't be able to create PDF forms with CF, but I say to those people, just wait and I think you will find out that you really don't need that functionality. If you need to create a dynamic form so badly, ever heard of...ahem...HTML? Or how about that thing they call Flex?
  • Geek features - I didn't attend the Scorpio 1337 session (features only geeks could love) because there was something else on the schedule I wanted to see at the same time (although that seemed to happen every time slot, there were so many great topics). But there were promises of some very geeky features like Interfaces, the debugger, and well, I don't remember them all because I didn't attend this session, but I'm sure if you are a geek there will be lots of things for you to appreciate.
  • The new CFAdmin interface and server monitoring features are sweet. You can drill down into every connection and request on your site, to see where the load is and what exactly is going on at any moment in time (right down to the values of variables in various scopes), along with completely customizable alerts (you can even write a CFC to do your own alert handling). It's really amazing that you can find out so much about what's happening on your server in such a simple way.
  • There's lots more, but this post is getting long.
It's not common that I leave a conference with no complaints. In comparison to CFObjective, other conferences are too long (by the last day I'm not interested or up to seeing any more sessions), don't have enough good content (all three sessions I want to see will inevitably be at the same time, while there are entire afternoons full of nothing I want to see), have too many sales pitches, have crappy food (hey, details matter), have bouncers working the door at every session to ensure no unwanted guests get in (bad vibes), or cost too much (something you begin to question when you go to an extravagant social even that's actually kinda lame, and realize that half your registration fee went to pay for that one night). Great job Jared, Steven, Jim and team...I'm looking forward to next year!

New Google Analytics

A new version of Google Analytics is coming:

Google Analytics is already a great tool, but this new version seems to still be an improvement. The features being promised for the new GA are much needed - scheduled email of reports, custom dashboard, and better trends-over-time. I hope they can also get the Site Overlay feature working better on CSS-based layouts. Maybe it's not really that useful, but it sure looks cool!

The interface looks simpler also, to which I say "it's about time!" So many web analytics tools, for so long, have used such non-intuitive, cryptic menus and language for their interfaces. Granted, I've never been fortunate enough to use WebTrends, which I hear is great, but LiveStats, SmarterStats and Urchin/Google Analytics, despite improvement over the years, still don't quite give me the information I'm looking for, and they all require pulling multiple reports just to see what you'd think should be the same information every webmaster wants to see! Not only that, it's difficult to understand exactly what you're looking at, sometimes the explanations about the reports don't really provide any helpful information. Maybe that's why Mint gets such rave reviews, but I can't use it because it's LAMP. So, yay for better, more usable web analytics tools!

Thursday, May 3, 2007

Adobe Stock Photos is teh kewl

I didn't really use Adobe stock photos before now, I pretty much used Getty and a couple alternates when I couldn't find what I need on Getty, and that was it. I somehow felt like I would not get as good a deal if I didn't go through the manufacturer.

However, over the past year or two, I've seen a lot of excellent new royalty-free stock photography houses blossoming. There's the trend towards all-you-can-download pricing (Shutterstock, LiquidLibrary), and the super-inexpensive, community-based sites (iStockPhoto). These have turned out to be a real boon for me when I needed simple, generic images. Need a picture of a plain old book? Or just a smiling dude? You'll find hundreds.

But when it comes to a large campaign with a 15000-piece print run, maybe you want something more unique. In those cases, I've moved away from the majors (Getty and Corbis) because they are not only expensive, but they are so popular there is a good chance that someone else will have used your image. Veer and Creatas are popular with a lot of designers, and they do tend to carry more unique images, but with a smaller selection.

After awhile, all this searching among several sites gets tedious. And some stock websites are considerably better than others - pricing at your fingertips, convenient comps and zoomed views, as well as how painful it is to page through 1100 images...the amenities vary widely from site to site. I find myself sometimes wishing one site had the xyz feature of another.

Enter Adobe Stock Photos. A convenient, robust, fast and slick interface that brings together the selection of dozens of stock houses, with fairly consistent and reasonable pricing. The only other thing I can ask for would be the ability to search for disks of images, or find the disk associated with an image if available (if I find one I really like, chances are there are others from the same photographer or shoot). And perhaps some additional "smart" search tools, but really when the interface works this well I don't mind looking through a few more images. I just bought my first three photos there, and I'm really pleased!

Off to CF.Objective!

I'm about to sign out and leave for the airport to head to Minneapolis for the 2nd ever CF.Objective() conference. From what I've heard about this year's conference so far, it sounds like it's going to be great and I'm excited! I'll try to blog some talks I attend if I'm not too distracted...if you're going too, see you there!

Monday, April 30, 2007

Grow up, web design field!

ALA is conducting a Web Design/Development Survey...I'm interested to see the results. In a small way, it's a sign of the industry (slowly) maturing, something ALA has done a great deal to push forward.

Thursday, April 26, 2007

Upgrading to Creative Suite 3? Use caution!

Just a word of advice from someone who did this upgrade in a much more painful manner than necessary! Make sure you understand what you are buying!

Last summer, I started my job at my current company, and got an entirely new computer with all new software. Naturally I needed all my Adobe goodies. This was shortly after the completion of the Adobe/Macromedia merger, so I was able to get it all by purchasing the Creative Suite Web Bundle, which included Creative Suite 2 Premium and Studio 8 Pro.

When CS3 came out I was all in a tizzy about upgrading as quickly as possible, because I had been on the PhotoShop and Fireworks CS3 betas and was already addicted. I checked out all the new suite options, and decided that Master wasn't for me - I didn't need all the video apps. And Design Premium didn't include Fireworks or Contribute.

I bought Web Premium, which I thought had everything I needed. I failed to notice that InDesign was not part of Web Premium. I think it was a mixture of my hurry and excitement to purchase (bad idea), and my assumption that anything called "Creative Suite" would include InDesign because it always has. Again, "to assume just makes an ass of u and me"...

Well, as I was going through my installation woes with CS3 Web Premium, I discovered the missing InDesign upgrade, and went on Adobe's site to see what I missed. I looked at the cost of upgrading InDesign alone, and figured that's what I was going to have to do. The "upgrade eligibility" page on the site was ambiguous - it said I could upgrade if I owned InDesign CS2, which I do. I wasn't sure if that would be allowed, so I chatted online with a customer service rep who told me it would work. Cool. So I bought the inDesign upgrade, and installed it, but when it came time to register, it would not accept my previous serial number for the upgrade or locate my previous installation. Argh.

I called support for like the 10th time in the past 2 days and was told that in fact that upgrade could not be done, I couldn't upgrade twice off the same product. Yeah, I get it, I understand, I see their point when they put it that way. But think about it, I OWN the previous version! I have done nothing shady or illegal here, I just want the shiny new versions of everything that I've already bought!

So, now I'm in a position where none of the suite products allow me to upgrade my previous purchase in full without purchasing another product as a standalone.

I ended up having to return CS3 Web Premium to get CS3 Design Premium, and forego Fireworks, because it's not as essential to my workflow (I was looking forward to some of its Flex comping and skinning features...too bad) . I can't bring myself to pay full price for a full version of a product I don't use that much that I already own. CS3 is also very pricey, my company has put $1700 into this suite so far! I'm disappointed in this oversight of Adobe's, at the lack of clarity on the website, and at the lack of education of the customer service rep I chatted with online.

I'm sure a lot of this has to do with the merger. I know Adobe can't be expected support infinite variations of their suites. I'm probably an edge case. But I still feel a little shafted here.

On the flip side, the new versions of everything in CS3 are fantastic, you should buy them...just watch what you're doing before you do!

Adobe to Open Source Flex

Wow, this is big news! Adobe has just announced that they will be releasing Flex under the Mozilla Public License. If you think about it, it's not that big of a jump since the Flex SDK is already available for free, they are just releasing additional developer resources, docs and build information...and enabling outside developers to contribute.

The press release:


This seems like a smart move to me for many reasons. First off, it's hugely positive PR. The public loves open source. Adobe has gotten a bad rap for the cost of some of their enterprise products, despite the fact that they have contributed to many open source products and released their own (Tamarin). This is a big step towards broad acceptance of Flex by the web development community, and it's going to have a great impact on the success of Apollo. If Adobe wants to rule the web, this is how they are going to do it.

Wednesday, April 25, 2007

CS3 Blues

(To any blues tune)

Da na na na nuh…

I’ve got the blues
Da na na na nuh…
The CS3 blues
I can’t install!
I can’t activate …
Watched the progress bar creep
I just sit and wait
Support got it working…
With a magical code
Is this a light
At the end of the road?
Finally running
Got nothing done today…
Adobe why…
do you hurt me this way?
I’ve paid lots of money
Used your software for years
For my excitement I get
Inconvenience and tears

Friday, April 20, 2007

Drawing Maps with Illustrator

I did a fun little project this week that I’ve done a few times before, but this time I thought I’d write up a little tutorial on it to share. I’ve you’ve done any amount of graphic design, you’ve probably had to draw maps, maybe as directions to an event or office. Illustrator has some cool features that come in handy for this type of illustrated map. The map I’m doing here is pretty simple, but using these techniques, you can go as fancy and stylized as you want. Maybe when I have time I’ll update these images to show alternate styles.

Find your source map – a real map that you can trace. (cough*google*cough)

Scan it, or grab a screen shot and paste it into your Illustrator document as a template. Place it where you want it, and lock the layer.

Create a new layer for your roads. You may want to have a couple layers, one for major roads, one for minor roads, one for highways, etc. Trace the roads you want to show on this layer, using the line and pen tools. It helps to draw these paths in a color that contrasts with your map so you don’t give yourself a headache looking at all those lines.

Tip – to make it easier when you add the labels to these roads, pay mind to the direction you draw them in. Start to the left and work your way towards right. This will make your path go in the direction your text should go. Draw your strokes down the center of where the road should be. Pay attention to street names you’re tracing and try to use one path per street, this will make it easier to label them later. If you draw multiple streets with a single path, you’ll have to break them up later.

If you’re tracing several roads, you may want to style them differently. Once you have your major roads traced, lock the layer, and create another for minor roads. You will probably want this one under your major roads layer. Keep each set of roads on its own layer for easy access.

You can style the roads a couple ways. Brushes work well for complex styles. To define a custom brush, draw the shape you want to represent your road, select it, and then hit the “new brush” button in the brushes palette, or drag it into the brushes Palette. Choose “Art Brush” as the type of brush. This will tell Illustrator to stretch the shape you’ve drawn over the length of the path. You can also adjust the scale of it later if you decide you want your roads wider. Because we’ve separated our major and minor roads onto different layers, you can define separate brushes for each.

An alternate way to style the roads is to customize the stroke for the road – make it wider and apply a color. You don’t have as much flexibility or styling options as you do with creating a brush, but this makes it easier to flatten the roads later. After you're done, you’ll want to expand the appearance of the brushes, or strokes. Another reason we made a backup of those layers!

Make the stroke wide as you wish the road to be:

Color it to match the road:

Expand the path:

Add desired borders:

Duplicate your first road layer to keep a backup (you’ll need it later - lock it and turn its visibility off to get it out of the way), then apply the brush you created for major roads to those paths, or style those paths with your desired strokes. Do the same for all other road layers – keeping a copy of the original paths for each. You can turn the visibility of your traced template layer on and off to see how it looks.

Once you’re done, you may notice that the intersections of the roads may look a little funky from your brushes or strokes, and that any borders around the road lines cross over eachother rather than intersecting.

To fix this, we'll use the Pathfinder to add the shapes together for the desired effect. This is much simpler with strokes than it is with brushes, another reason to use a stroke if you can. With strokes, you can select all of the expanded strokes, hit the “add” button, and you’re done. With brushes you’ll have to carefully expand the appearance of each, and add them together one at a time.

Much better!

Now we’re going to add labels. Create another copy of your backed up road path layers, this one will be where we add the text labels. Using the text tool, add street names to each road path. You can use the baseline adjustment on the Character palette to align the text it where you’d like it to appear in relation to the road path. Drag the slider handles around the text with the arrow tool to position the text where you want it, or flip it to the opposite side of the path.

Insert text along the path:

Adjust the text style and baseline:

Drag the text to the desired location:

As you can see from these screen shots, I'm turning the visibility of the template on for reference and off for clarity.

Once all of your roads are labeled, you can draw in icons, placemarks, pushpins and landmarks. These all go on separate layers for convenience. If you want to use lots of cute little landmark or interstate icons, create symbols from your icons for easy duplication and editing.

Here’s my finished map…directions to my office! Now I know this article was cool, please try to refrain from stalking me.

Thursday, April 19, 2007

cf_drama and fake Prada bags

There's been a lot of buzz in the blogosphere this week having to do with sniping between Adobe and New Atlanta/BlueDragon. I'm getting really sick of hearing about it, particularly because I'm very close to one side of the argument (if you know me, you already know who). I've followed along and sided with Adobe because, well, my entire career revolves around using Adobe products, I love them, I love ColdFusion and I hate imitations. Frankly I don't know how some people at New Atlanta can sleep at night when their flagship product is a rip off. But seriously folks, all this ranting is not worth it.

Do you think that Prada cares about the street vendors peddling knock-offs of their bags?
As a successful and well respected brand, they continue to produce innovative and sophisticated fashion without looking over their shoulder at a tiny portion of the market share that's going to some random guy on the street (or some overseas producer of such products). Sure, a Prada designer might not like walking down the street and seeing a cheap imitation of a bag they designed last year selling for $30, but they aren't worried for their livelihood. Besides, anyone who buys one of those fake bags probably wasn't in the market for a real one to begin with.

The last nail in the coffin that made me waste my time posting a blog entry about this was reading the article that is being attributed as the source of much of this drama:

What a totally lame article! It was barely coherent. What hostility some disreputable reporter attempted to conjure up was just an attempt to turn vapor-rumors into a good story. Since said reporter utterly failed on that, had we all left it alone, the only time wasted would have been his own. The media does it again.

PS. For the record, I believe that Adrock's (honk if you don't know who that is) statement drawing similarities between buyers of BD and buyers of fOakleys was scarily true. Think about it.

PSS. Sorry for making such a useless post. I had fun writing it.

Tuesday, April 10, 2007

Launch of, my latest project

I'm pleased to announce the launch of my company's new website:

It's been in the works for awhile, but since I'm the lone wolf doing all the content, design and development, it's taken awhile. Needless to say I'm happy it's done and quite pleased with the results. Of course, it's never really done! I had to hold back on many of the features I wanted to build, because we really just needed to move away from our old, static HTML tag-soup site. However like all sites, it's a work in progress and will continue to change over the coming months.

For the geeks, it's built with ColdFusion 7 and utilizing the Model-Glue framework. It also uses YUI for the menus and some of the layout, and SPRY for some of the other AJAX/DHTML stuff. The markup is XHTML/CSS, it did validate at one point but the YUI menus don't validate...bummer. Oh well! I've never been that sort of standardista...

Friday, April 6, 2007

Dreamweaver Extensions for Model-Glue XML (and FB and M-ii)

On a couple of occasions I have thought that someone needs to write a Dreamweaver extension for ModelGlue, as well as the other frameworks, especially a tag library (and a file browser/inspector wouldn't hurt - those ModelGlue.xml files can get long...). I can't tell you how many times I've habitually hit ENTER after typing "na..." to add a name attribute, which auto-completes in CF but not for XML.

Well at least there is a solution to my first desire! The ever-productive Massimo Foti has a series of Dreamweaver tag libraries for the popular frameworks. They can be found on The site seems to have a thing against deep linking, but you can find the .mxp file downloads under the Dreamweaver > ColdFusion section.

Thank you, Massimo!

(now I just need to find a file inspector, perhaps any good XML one would work...)

Monday, April 2, 2007

Serving a Downloadable File with ColdFusion in Model Glue

I thought maybe it's time for another "real" blog post. I learned a little something today (with some help from Adam) so now I'll share. A hyperlink to download a PDF file - seems simple and straightforward enough. But I've been building this site using the Model Glue framework (and learning MG in the process -- so far so good!), and I wanted to serve the file with <cfcontent>, not just a plain hyperlink, so it wasn't as straightforward as just <a href="myfile.pdf">Download It</a>...

Here's my solution, I'd be interested to hear how others have done this. It seemed like a little bit overkill as I was writing it, but I also realized that I would never need to write this snippet of code again, so that kind of makes up for the long-windedness of it.

The solution is composed of all the standard files and snippets in a Model Glue application.
  • the "model" CFC - in this case, a simple object
  • a .cfm view file where the "cfcontent" resides
  • a function in the Controller.cfc to create the download object and add it to the event
  • a message broadcast, listener, and event handler in the ModelGlue.xml file
  • all the views, which compose my page and contain the links to download the file

First, let's look at the "Download" Bean CFC: Download.cfc represents my "file" object that stores my file information. It basically just stores values for the file name, file path, and mime type of the file I'm serving for download. It lives in my "model" folder.

<!--- Download.cfc --->
<cfcomponent displayname="Download" hint="retrieves a file for download to be served with cfcontent">

<!--- init() --->

<cffunction name="init" access="public" returntype="any">

<cfargument name="fileName" type="string" required="yes" hint="name of file once downloaded">

<cfargument name="filePath" type="string" required="yes" hint="full path of file to be served">

<cfargument name="fileType" type="string" required="yes" hint="mime type of file">

<cfset filename =" ARGUMENTS.fileName">
filepath =" ExpandPath(ARGUMENTS.filePath)">
filetype =" ARGUMENTS.fileType">

<cfreturn this>


<!--- getters --->

<cffunction name="getFilename" returntype="string" access="public" output="false">
<cfreturn filename>

<cffunction name="getFilePath" returntype="string" access="public" output="false">
<cfreturn filepath>

<cffunction name="getFileType" returntype="string" access="public" output="false">
<cfreturn fileType>


Notice that the CFC uses ExpandPath() so that a relative url can be passed in as the location of the file, which is much easier when it comes time to build your link, and then the app is not server-dependent. Yes, I could write setters and use those setters to construct the CFC, but I'm never going to build these objects to say, insert into a database, so I didn't bother.

Then I have the actual "download" include. It's called _download.cfm because the underscore preceding the filename is a common convention for files that should not be called directly, but need to be included in another file, it also differentiates it clearly from your "template" view files.

This file gets dynamically included on the page when the "download" viewState value is present. It also only serves the file if it's not a simple value (to ensure the values we need are there). It lives in the "views" folder. Notice there are separate values for the file path and the file name. The file name is what the user sees when they download the file, the file path tells CF where to locate the file. Being able to set the file name in the header is nice because you can use a short, sweet and simple file name for the end user, but your own convoluted, datestamped , purpose-coded file naming convention for the actual file (ok maybe that's just me).

Also we use the http header so that the user will be prompted with the browser "download" dialog, rather than leaving it to the browser to try and open the file directly. It prevents us from having to list some weird instructions like "right-click and choose Save Target As" for the less-savvy users (arent' they all).

<cfset download =" viewState.getValue('download')">

<cfif NOT isSimpleValue(download)>
<cfheader name="Content-Disposition" value="attachment; filename=#download.getFileName()#">
<cfcontent type="#download.getfiletype()#" file="#download.getfilePath()#" deletefile="no">

My Model Glue Controller.cfc contains this function to build the Download object. It just calls the Download.cfc, creates the "download" object, and then adds the instance of said object to the event so it can be found when the page is rendered.

<!--- Controller.cfc --->

<cffunction name="getMyDoc" access="public" returntype="void" output="false">
<cfargument name="event" type="any" required="yes">
<cfset fileDownload = createObject("component","model.Download").init('MyDoc.pdf','assets/docs/MyDoc_123.pdf','application/pdf')>
<cfset arguments.event.setValue("download", fileDownload)>

In My ModelGlue.xml file, I hook my application into the above function with this XML snippet.

<message-listener message="getMyDoc" function="getMyDoc" />

The event handler for that message is...

<event-handler name="download.mydoc">
<message name="getMyDoc" />
<result do="page.mydoc" />

The broadcast, obviously, requests the download object via the Controller.cfc. The result - "do" is the same page that my link is on - so the user does not leave that page when they click the "download" link, they are just served the file. Lastly, on the page where I want the link that is clicked to download this file, this is the <a> tag:

<a href="#viewState.getValue('myself')#download.mydoc">Download My Doc</a>

Nice. That's all there is to it.

Of course this sample doesn't show any security or anything, this would only be appropriate for a public download. Sorry if the spacing and indentation is ugly, Blogger's code formatting is a pain! Hope you find it helpful!