<?xml version="1.0" encoding="utf-8"?>
			
			<rss version="2.0">
			<channel>
			<title>Stephen (Steve) Withington - Web Usability</title>
			<link>http://www.stephenwithington.com/blog/index.cfm</link>
			<description>Blog Thoughts and Ramblings of a ColdFusion Programmer/Developer</description>
			<language>en-us</language>
			<pubDate>Wed, 08 Sep 2010 08:59:17 -0700</pubDate>
			<lastBuildDate>Tue, 27 Oct 2009 08:35:00 -0700</lastBuildDate>
			<generator>BlogCFC</generator>
			<docs>http://blogs.law.harvard.edu/tech/rss</docs>
			<managingEditor>steve@stephenwithington.com</managingEditor>
			<webMaster>steve@stephenwithington.com</webMaster>
			
			
			
			
			
			<item>
				<title>Mobile, Handheld Computing Devices: Where Does the Web Developer Fit In?</title>
				<link>http://www.stephenwithington.com/blog/index.cfm/2009/10/27/Mobile-Handheld-Computing-Devices-Where-Does-the-Web-Developer-Fit-In</link>
				<description>
				
				&lt;p&gt;Recently, I was involved in a lively discussion at a ColdFusion and Flex developer conference (&lt;a href=&quot;http://bflex.info/&quot; target=&quot;_blank&quot;&gt;BFusion/BFlex&lt;/a&gt;) held on the campus of Indiana University in beautiful Bloomington, Indiana. &lt;a href=&quot;http://www.digitalprimates.net/aboutus.html&quot; target=&quot;_blank&quot;&gt;Michael Labriola&lt;/a&gt; led the discussion, which took place during his keynote presentation, between a panel of many other developers who are active in the ColdFusion and/or Flex communities. Sometimes it&apos;s difficult to articulate your thoughts at the time of a discussion, hence I&apos;m using this medium to do a sort of brain flush at the moment. I&apos;m doing this also because I think the topic of discussion is an important one to consider for those of us who primarily develop applications for the web.&lt;/p&gt;
&lt;p&gt;As for expanding the definition of &apos;&lt;em&gt;who&lt;/em&gt;&apos; actually develops applications for the web, I hope to include anyone who is involved in the process of creating rich internet applications (stakeholders, account executives, creative&apos;s, designers, developers, etc.).&lt;/p&gt;
&lt;h3&gt;Mobile Phone vs. Handheld Device&lt;/h3&gt;
&lt;p&gt;First, I think it&apos;s important for &apos;web&apos; developers to try to disassociate the word &apos;mobile&apos; from the word &apos;phone.&apos; I myself prefer to use the word &apos;handheld&apos; when referring to any type of &apos;mobile&apos; device. &apos;Handheld&apos; feels much more inclusive to me than &apos;mobile.&apos; Whereas &apos;mobile,&apos; while by itself is probably a more appropriate descriptor, can be more exclusive sounding due to its association with the more specific type of handheld device commonly known as a &apos;cell phone.&apos; So when I use the word &apos;handheld,&apos; I am attempting to include &apos;any type of compact, portable  computing device.&apos; I am purposely using a broad definition here since mobile phones only constitute one slice of the larger &apos;handheld, mobile computing&apos; marketplace.&lt;/p&gt;
&lt;h3&gt;Don&apos;t Hate Apple Because Their Beautiful&lt;/h3&gt;
&lt;p&gt;Let&apos;s face it, &lt;a href=&quot;http://www.apple.com/&quot; target=&quot;_blank&quot;&gt;Apple&lt;/a&gt; has definitely shaken up the market with their lineup of handheld devices including the &lt;a href=&quot;http://www.apple.com/iphone/&quot; target=&quot;_blank&quot;&gt;iPhone&lt;/a&gt; and &lt;a href=&quot;http://www.apple.com/ipodtouch/&quot; target=&quot;_blank&quot;&gt;iPod touch&lt;/a&gt;. Whether you love, hate or are indifferent to Apple&apos;s handheld products, you can&apos;t deny that Apple&apos;s use of interface design and touchscreen technology has transformed the way other companies are designing and building handheld devices. Not to mention the number of features and available applications! I&apos;m sure that there have been, and will continue to be, many conversations around conference tables about what works, what doesn&apos;t work and how the iPhone and iPod touch interfaces can be improved upon. Rather than throw my own subjective opinions into the mix at the moment, I will say that as an iPhone user, I certainly have my list of gripes. However, Apple has most certainly revolutionized how people can actually use a handheld device and interact with each other, the web and beyond.&lt;/p&gt;
&lt;h3&gt;Application Distribution&lt;/h3&gt;
&lt;p&gt;Take a moment to review this  &lt;a href=&quot;http://en.wikipedia.org/wiki/List_of_digital_distribution_platforms_for_mobile_devices&quot; target=&quot;_blank&quot;&gt;list of digital distribution platforms for mobile devices&lt;/a&gt; from &lt;a href=&quot;http://en.wikipedia.org/&quot; target=&quot;_blank&quot;&gt;Wikipedia&lt;/a&gt;. Considering the fact that the &lt;a href=&quot;http://en.wikipedia.org/wiki/App_Store&quot; target=&quot;_blank&quot;&gt;Apple App Store&lt;/a&gt; opened on July 10, 2008 and as of September 28, 2009 there are over 85,000 third-party applications available and over 2 billion application downloads to iPhone and iPod touch users, I&apos;d argue Apple has definitely made some in-roads with software developers and end-users alike. Compare that with Google&apos;s Android Market with 10,200 applications as of September 2009 and you just might agree.&lt;/p&gt;
&lt;p&gt;I&apos;m not suggesting that the model Apple used to create their &apos;Application Empire&apos; is the right one, but without a doubt, they appear to be doing &lt;em&gt;something&lt;/em&gt; right. I most definitely don&apos;t agree with some of their practices, but one can&apos;t deny their level of success when compared to any other digital distribution platform.&lt;/p&gt;
&lt;h3&gt;Distributing Handheld Applications via the Web&lt;/h3&gt;
&lt;p&gt;As of today, reliably deploying an application on the web that is specifically targeted to handheld devices with a web browser is extremely difficult to do, assuming you want to offer anything more than some basic text and a few form fields. While work is &lt;a href=&quot;http://www.w3.org/standards/webofdevices/&quot; target=&quot;_blank&quot;&gt;currently being done to improve standards&lt;/a&gt; on &apos;technologies to enable Web access anywhere, anytime, using any device,&apos;  developers are pretty much left in the rain waiting for handheld manufacturers to adopt these standards and turn them into practices.&lt;/p&gt;
&lt;p&gt;Once again, Apple has made significant strides in getting their handheld users online. In &lt;a href=&quot;http://metrics.admob.com/2009/09/august-2009-mobile-metrics-report/&quot; target=&quot;_blank&quot;&gt;AdMob&apos;s Mobile Metrics August 2009 report&lt;/a&gt;, iPhone&apos;s worldwide operating system share has grown from 33 percent to 40 percent in the preceding six months. In addition, iPhone represented 50 percent of US smartphone usage in AdMob&apos;s network in August 2009, followed by RIM and Android devices at 14 and 13 percent, respectively. &lt;/p&gt;
&lt;p&gt;What truly makes these numbers phenomenal is that Apple&apos;s handheld devices actually account for &lt;a href=&quot;http://brainstormtech.blogs.fortune.cnn.com/2009/08/13/iphone-market-share-grew-375-in-q2/&quot; target=&quot;_blank&quot;&gt;less than 15% of the overall Smartphone OS Market Share&lt;/a&gt;. Yet, this small group of users account for half of the US smartphone usage within AdMobs&apos;s network. This information more than suggests, it screams that iPhone and iPod touch users are  actually &lt;em&gt;using&lt;/em&gt; their handheld devices to go online.&lt;/p&gt;
&lt;p&gt;As a side note however, it is frustrating that Adobe Flash is not yet supported on Apple&apos;s iPhone or iPod touch. Sure, &lt;a href=&quot;http://labs.adobe.com/technologies/flashcs5/appsfor_iphone/&quot; target=&quot;_blank&quot;&gt;efforts have been made so that iPhone and iPod touch applications can be developed with Flash and ActionScript 3&lt;/a&gt;, but users still won&apos;t be able to view Flash content delivered via the browser. To be clear, this is not the fault of Adobe. Apple, for whatever reason(s), has chosen &lt;em&gt;not&lt;/em&gt; to support Flash at this time.&lt;/p&gt;
&lt;h3&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;I think it&apos;s important for those of us who primarily develop applications for the web to continue our discussions and thoughts on how we can better address the needs of the ever-growing handheld device marketplace. &lt;/p&gt;
&lt;p&gt;I believe we can learn from Apple&apos;s strengths and weaknesses to find and improve a model of &apos;handheld application development and distribution.&apos; &lt;/p&gt;
&lt;p&gt;I think if designers and developers can learn how to better account for users of handheld devices regardless of whether or not they visit a web site, overall usability can be improved for these users as they look for goods, services and/or information.&lt;/p&gt;
&lt;p&gt;These are merely thoughts, and obviously they&apos;re constantly evolving ... even while I&apos;ve been writing this article. I hope my thoughts also inspire you to think about this topic and look forward to reading and/or hearing your thoughts on this subject as well.&lt;/p&gt;
&lt;h3&gt;Disclaimer&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;I don&apos;t work for Apple nor have I received any compensation from Apple for writing this article. I wouldn&apos;t mind it if they decided to do so, but as of the date of publication, this has not actually happened. Finally, no handheld devices were harmed in the writing of this article.&lt;/em&gt;&lt;/p&gt;
				
				</description>
						
				
				<category>ColdFusion</category>				
				
				<category>ActionScript</category>				
				
				<category>Flex</category>				
				
				<category>Flash</category>				
				
				<category>Web Usability</category>				
				
				<pubDate>Tue, 27 Oct 2009 08:35:00 -0700</pubDate>
				<guid>http://www.stephenwithington.com/blog/index.cfm/2009/10/27/Mobile-Handheld-Computing-Devices-Where-Does-the-Web-Developer-Fit-In</guid>
				
			</item>
			
		 	
			
			
			<item>
				<title>MySpace Can Update Your Twitter Status ... Who Cares?</title>
				<link>http://www.stephenwithington.com/blog/index.cfm/2009/9/21/MySpace-Can-Update-Your-Twitter-Status--Who-Cares</link>
				<description>
				
				&lt;p&gt;&lt;a href=&quot;http://www.myspace.com/sync&quot; target=&quot;_blank&quot;&gt;MySpace has announced&lt;/a&gt; users can now automatically sync their status updates with Twitter. Is having the ability to create a &amp;quot;Global Social Status&amp;quot; (yes, you can use that ... I just made it up) really such a good thing?&lt;/p&gt;
&lt;p&gt;Not long ago I ran across an application in Facebook that would pull in my Twitter updates and automagically update my Facebook status. I quickly learned that this was not exactly the best idea in the world (and I&apos;ll tell you why in a moment), so I&apos;m not so certain the efforts of MySpace are going to bring about any kind of improvements in the social media communities.&lt;/p&gt;
&lt;p&gt;Let&apos;s think about this for a minute ... if you&apos;re a friend of mine on &lt;a href=&quot;http://www.facebook.com/addfriend.php?id=764848873&quot; target=&quot;_blank&quot;&gt;Facebook&lt;/a&gt; (or MySpace)&lt;em&gt; AND&lt;/em&gt; you follow me on &lt;a href=&quot;http://twitter.com/stevewithington&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt; ... do you &lt;em&gt;really&lt;/em&gt; want to read my status updates &lt;em&gt;everywhere&lt;/em&gt; you go? For serious, does it make sense to &amp;quot;shotgun&amp;quot; your updates to every single social community you belong to? I think not.&lt;/p&gt;
&lt;p&gt;Sure, there are &lt;em&gt;rare&lt;/em&gt; occasions that you &lt;em&gt;might &lt;/em&gt;want to do this ... but I say resist the temptation! I&apos;ve found that for the most part, people I follow on Twitter are a completely different group of people than I have on Facebook. Sure, there is some overlap and that&apos;s to be expected, but the vast majority of people I know of Facebook (or MySpace) are people I&apos;ve actually met, am friends with, family with, grew up with, you get the picture. Many of the people (and/or companies) I follow on Twitter are people I&apos;ve never personally met (although many I hope to meet someday) but we share some commonalities ... maybe it&apos;s programming, maybe it&apos;s music, maybe it&apos;s geography. You know?&lt;/p&gt;
&lt;p&gt;Where I&apos;m going with this is that something I might &amp;quot;tweet&amp;quot; about may not necessarily be something I want to update my &amp;quot;Global Social Status&amp;quot; with. The audiences are completely different and often warrant their own unique message, even &lt;em&gt;if&lt;/em&gt; the messages are very similar.&lt;/p&gt;
&lt;p&gt;The flip side to this is if you like to Twitter ... and you know who you are ... you have the potential of overwhelming your family and friends with updates like &amp;quot;RT @stevewithington CF9 is the bees knees ... I have ORM, do you?&amp;quot; or &amp;quot;This site rocks: &lt;a href=&quot;http://tinyurl.com/nv62na&quot; target=&quot;_blank&quot;&gt;http://tinyurl.com/nv62na&lt;/a&gt; #muracms #mura #coldfusion #sql&amp;quot;&lt;/p&gt;
&lt;p&gt;Heck, I don&apos;t know about you, but I already get a little irritated having to scroll through things like &amp;quot;Help Me on Mafia Wars&amp;quot; or the ever popular &amp;quot;Steve Withington took the &apos;What Kind of Car Are You?&apos; quiz and got the result: You&apos;re a 1969 Bitchin&apos; Camaro. Read more ...&amp;quot;&lt;/p&gt;
&lt;p&gt;So if you&apos;re goal in life is to annoy the crap out of people in your social communities, then go right ahead and applaud the efforts of MySpace and others in their quest to become THE place to go to update your Global Social Status. In the mean time, I&apos;ll continue along, grumbling and complaining about silly things like this.&lt;/p&gt;
				
				</description>
						
				
				<category>ColdFusion</category>				
				
				<category>Twitter</category>				
				
				<category>Web Usability</category>				
				
				<category>Family + Friends</category>				
				
				<pubDate>Mon, 21 Sep 2009 12:22:00 -0700</pubDate>
				<guid>http://www.stephenwithington.com/blog/index.cfm/2009/9/21/MySpace-Can-Update-Your-Twitter-Status--Who-Cares</guid>
				
			</item>
			
		 	
			
			
			<item>
				<title>Using ColdFusion to Handle HTTP 404 Page Not Found Errors</title>
				<link>http://www.stephenwithington.com/blog/index.cfm/2008/12/30/Using-ColdFusion-to-Handle-HTTP-404-Page-Not-Found-Errors</link>
				<description>
				
				&lt;p&gt;This article will &lt;em&gt;not&lt;/em&gt; address the &lt;a href=&quot;http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=AppEvents_07.html&quot; target=&quot;_blank&quot;&gt;onMissingTemplate method&lt;/a&gt; which only runs when a CFML page does not exist (i.e., wwwroot/directory/thisPageDoesNotExist.cfm). In addition, this article will &lt;em&gt;not&lt;/em&gt; address using custom headers or a &lt;a href=&quot;http://en.wikipedia.org/wiki/Htaccess&quot; target=&quot;_blank&quot;&gt;.htaccess file&lt;/a&gt; with Apache. This article will address those &lt;em&gt;other&lt;/em&gt; &amp;quot;page not found&amp;quot; errors often found in Windows hosted environments.&lt;/p&gt;
&lt;p&gt;Let&apos;s start by assuming  someone tries to visit www.yourdomain.com/thisDirectoryDoesNotExist, or www.yourdomain.com/thisPageDoesNotExist.html and neither the directory, nor the page actually exist on your site. Or, better yet, you&apos;ve just spent months building a new, dynamic site for a client using ColdFusion and their old site was an old, yucky plain HTML site with pages everywhere. Now, your client, who&apos;s a little savvy in the SEO department, (that&apos;s &lt;em&gt;search engine optimization&lt;/em&gt; for you non-seo-knowing folk), has requested you setup redirects for each of his &lt;em&gt;old&lt;/em&gt; pages to the &lt;em&gt;new&lt;/em&gt; ones you&apos;ve created.&lt;/p&gt;
&lt;p&gt;If you&apos;re anything like me, I used to dread the thought of taking care of this. I used to spend a ton of time on this by creating a separate page for each of the &amp;quot;old&amp;quot; pages and directories, then using either JavaScript to handle the redirects (if the old page was vanilla HTML) or the &amp;quot;old&amp;quot; dynamic language (i.e., ASP, PHP, etc.) to create custom headers, etc. Regardless, it was a major pain to do this, especially because it cluttered my site with a bunch of extra files that were essentially useless.&lt;/p&gt;
&lt;p&gt;Then, I had one of those &amp;quot;light bulb moments.&amp;quot; I thought, &amp;quot;Hey, I&apos;m already using a custom tag to handle &apos;page not found&apos; requests, so if I could somehow capture the requested page, match it against a list of &apos;known-to-be-missing&apos; pages, then I could code a way to forward to the &apos;new&apos; destination.&amp;quot; Sounds simple enough, eh?&lt;/p&gt;
&lt;p&gt;For those of us using a shared-host provider such as CrystalTech or HostMySite, they&apos;re kind enough to allow us to create custom pages to handle certain HTTP errors, such as 404. It&apos;s usually found in the service provider&apos;s &amp;quot;control panel&amp;quot; under something like &amp;quot;IIS &amp;gt; Custom Error Pages.&amp;quot; Once there, you usually have three options to pick from: 1) Default, 2) File and 3) URL. In most cases, &amp;quot;Default&amp;quot; loads the standard error page provided by our friends at Microsoft. &amp;quot;File&amp;quot; is just that, a flat, static, HTML page. What we want to use is &amp;quot;URL,&amp;quot; so that we can use ColdFusion to help us out. In fact, I&apos;ll be nice and even provide a link to both &lt;a href=&quot;http://www.webcontrolcenter.com/Knowledge_Base/frmKB.aspx?KBID=244&quot; target=&quot;_blank&quot;&gt;CrystalTech&apos;s process&lt;/a&gt; and &lt;a href=&quot;http://www.hostmysite.com/support/cpanel/customerror/&quot; target=&quot;_blank&quot;&gt;HostMySite&apos;s process&lt;/a&gt;. But before you do this, you&apos;ll need to at least set up a .CFM file somewhere on your site so you know what to enter into the URL path, right? So for now, let&apos;s assume you&apos;ve created a file call &amp;quot;404.cfm&amp;quot; and placed in a directory structure like so: &amp;quot;/extensions/customtags/404.cfm&amp;quot;&lt;/p&gt;
&lt;p&gt;So, assuming you&apos;ve got your custom error page setup properly, you will now be able to capture a query string which contains the &amp;quot;requested URL&amp;quot; that really didn&apos;t exist. The easiest way to test this would be to enter this code onto your 404.cfm file, upload it to your site, then try a non-existent directory such as www.yourdomain.com/abcd/.&lt;/p&gt;
&lt;code&gt;
&lt;cfset request.queryString = getPageContext().getRequest().getQueryString() /&gt;
&lt;cfoutput&gt;#request.queryString#&lt;/cfoutput&gt;
&lt;cfabort /&gt;
&lt;/code&gt;
&lt;p&gt;You should see something like this: &amp;quot;&lt;strong&gt;404;http://www.yourdomain.com:80/abcd/&lt;/strong&gt;&amp;quot;&lt;/p&gt;
&lt;p&gt;There&apos;s some great information coming through here. First, you&apos;ll notice that you&apos;re receiving the error number (404). Next, you&apos;ll see your domain also includes the port number being used. For example, if using HTTP, then you will most likely see the number 80, or if your using HTTPS, then you should probably see 443.&lt;/p&gt;
&lt;p&gt;For this next part, you might have to adjust this if you ever use a colon ( : ) in your directory or page naming conventions (this is not generally used, so I wouldn&apos;t expect this to be much of an issue).&lt;/p&gt;
&lt;p&gt;Look again at the query string that we&apos;ve been given, what we really want to grab is everything &lt;em&gt;after&lt;/em&gt; the port number. Or, the absolute path to the page or directory being requested. So this is what I came up with:&lt;/p&gt;
&lt;code&gt;
&lt;!--- perform some manipulations to the &apos;requested url&apos; to get at the actual request ---&gt;
&lt;cfif isDefined(&quot;request.queryString&quot;)&gt;
	&lt;cfset requestedPage = listlast(request.queryString, &quot;:&quot;) /&gt;
&lt;/cfif&gt;
&lt;cfif len(trim(requestedPage))&gt;
	&lt;!--- after removing everything before the port, we now need to remove the port number ---&gt;
	&lt;cfset requestedPage = listdeleteat(requestedPage, &quot;1&quot;, &quot;/&quot;) /&gt;
	&lt;!--- quick fix to create an absolute path from the site root to the requested page ---&gt;
	&lt;cfset requestedPage = &quot;/&quot; &amp; requestedPage /&gt;
&lt;/cfif&gt;
&lt;cfoutput&gt;#requestedPage#&lt;/cfoutput&gt;
&lt;cfabort /&gt;
&lt;/code&gt;
&lt;p&gt;So, now if we use the same url we tried earlier, I should see something like: &amp;quot;&lt;strong&gt;/abcd/&lt;/strong&gt;&amp;quot; Now, I&apos;ve got a variable that I can use to match against to see if this is a &amp;quot;known&amp;quot; directory or page from our old site. Now we just need something to handle the &amp;quot;matching&amp;quot; and then receive a response to make decisions against.&lt;/p&gt;
&lt;p&gt;Luckily, I&apos;ve created a rather simple .CFC which can easily be modified to accommodate any &amp;quot;known&amp;quot; directories and/or pages, including .ASP, .PHP, etc.&lt;/p&gt;
&lt;code&gt;
&lt;!------------------------------------------------------------------------------------------------------------

	Document:		/extensions/components/redirect.cfc
	Author:			Steve Withington
	Creation Date:	12/30/2008
	Copyright:		(c) 2008 Stephen J. Withington, Jr. | www.stephenwithington.com
	
	Purpose:		Handles redirects of old pages to new ones.

	METHODS/VAR:	1) getLocation() / newLocation
	
	Revision Log:	
	MM/DD/YYYY - sjw - comments.

-------------------------------------------------------------------------------------------------------------&gt;
&lt;cfcomponent displayname=&quot;Handles redirects&quot; hint=&quot;Pass me an old location, I&apos;ll give you the new location.&quot; output=&quot;no&quot;&gt;

	&lt;!---	1)  getLocation()	---&gt;
	&lt;cffunction name=&quot;getLocation&quot; 
					displayname=&quot;Get a new location for old links.&quot; 
					access=&quot;public&quot; 
					returntype=&quot;string&quot; 
					output=&quot;no&quot;&gt;
	
		&lt;cfargument name=&quot;oldLocation&quot; required=&quot;false&quot; default=&quot;&quot; /&gt;
	
		&lt;cfset var newLocation = &quot;&quot; /&gt;
	
		&lt;cfswitch expression=&quot;#arguments.oldLocation#&quot;&gt;

			&lt;cfcase value=&quot;/index.html&quot;&gt;
				&lt;cfset newLocation = &quot;/index.cfm&quot; /&gt;
			&lt;/cfcase&gt;

			&lt;cfcase value=&quot;/about/news/default.php,/about/news/,/about/news&quot;&gt;
				&lt;cfset newLocation = &quot;/news/index.cfm&quot; /&gt;
			&lt;/cfcase&gt;

			&lt;cfcase value=&quot;/contact-us.asp&quot;&gt;
				&lt;cfset newLocation = &quot;/contact/index.cfm&quot; /&gt;
			&lt;/cfcase&gt;

			&lt;cfdefaultcase&gt;
				&lt;cfset newLocation = &quot;&quot; /&gt;
			&lt;/cfdefaultcase&gt;

		&lt;/cfswitch&gt;
	
		&lt;cfreturn newLocation /&gt;
	
	&lt;/cffunction&gt;

&lt;/cfcomponent&gt;
&lt;/code&gt;
&lt;p&gt;Now, we just need to invoke the ColdFusion Component to see if there&apos;s a match.&lt;/p&gt;
&lt;code&gt;
&lt;!--- check to see if the page requested matches any &apos;known&apos; pages from the old site ---&gt;
&lt;cftry&gt;

	&lt;cfinvoke component=&quot;extensions.components.redirect&quot; method=&quot;getLocation&quot; returnvariable=&quot;newLocation&quot;&gt;

		&lt;cfif isDefined(&quot;requestedPage&quot;) and len(trim(requestedPage))&gt;
			&lt;cfinvokeargument name=&quot;oldLocation&quot; value=&quot;#requestedPage#&quot; /&gt;
		&lt;/cfif&gt;

	&lt;/cfinvoke&gt;

	&lt;cfif isDefined(&quot;newLocation&quot;) and len(trim(newLocation))&gt;
		&lt;cfset newPage = newLocation /&gt;
	&lt;/cfif&gt;

	&lt;cfcatch&gt;
		&lt;cfset newPage = &quot;&quot; /&gt;
	&lt;/cfcatch&gt;

&lt;/cftry&gt;
&lt;/code&gt;
&lt;p&gt;As you can see, if no match has been found, a variable called &amp;quot;newPage&amp;quot; is merely left blank. So, now we can write a little more code to accommodate both &amp;quot;known-to-be-missing&amp;quot; and &amp;quot;truly-unknown-and-really-missing&amp;quot; directories and pages. If a page is &amp;quot;known-to-be-missing&amp;quot;, I can pass a search engine friendly header so that everything runs as smoothly as possible.&lt;/p&gt;
&lt;p&gt;Here&apos;s the final document, aside from the .CFC above which should be kept separate.&lt;/p&gt;
&lt;code&gt;
&lt;cfsilent&gt;
&lt;!------------------------------------------------------------------------------------------------------------

	Document:		/extensions/customtags/404.cfm
	Author:			Steve Withington
	Creation Date:	12/30/2008
	Copyright:		(c) 2008 Stephen J. Withington, Jr. | www.stephenwithington.com
	
	Purpose:		Handles requests for missing pages (HTTP 404).

	Notes:			Test this set up before using in a live environment. The 404 custom error page needs to be
					set up in IIS (or via control panel in a third-party hosted environment).
	
	Revision Log:	
	MM/DD/YYYY - sjw - comments.

-------------------------------------------------------------------------------------------------------------&gt;
&lt;!--- scope local variables ---&gt;
&lt;cfparam name=&quot;requestedPage&quot; default=&quot;&quot; /&gt;
&lt;cfparam name=&quot;newPage&quot; default=&quot;&quot; /&gt;
&lt;!--- use a little of the underlying java to grab the queryString ---&gt;
&lt;cfset request.queryString = getPageContext().getRequest().getQueryString() /&gt;
&lt;!--- perform some manipulations to the &apos;requested url&apos; to get at the actual request ---&gt;
&lt;cfif isDefined(&quot;request.querystring&quot;)&gt;
	&lt;cfset requestedPage = listlast(request.queryString, &quot;:&quot;) /&gt;
&lt;/cfif&gt;
&lt;cfif len(trim(requestedPage))&gt;
	&lt;!--- after removing everything before the port, we now need to remove the port number ---&gt;
	&lt;cfset requestedPage = listdeleteat(requestedPage, &quot;1&quot;, &quot;/&quot;) /&gt;
	&lt;!--- quick fix to create an absolute path from the site root to the requested page ---&gt;
	&lt;cfset requestedPage = &quot;/&quot; &amp; requestedPage /&gt;
&lt;/cfif&gt;
&lt;!--- check to see if the page requested matches any &apos;known&apos; pages from the old site ---&gt;
&lt;cftry&gt;
	&lt;cfinvoke component=&quot;extensions.components.redirect&quot; method=&quot;getLocation&quot; returnvariable=&quot;newLocation&quot;&gt;
	&lt;cfif isDefined(&quot;requestedPage&quot;) and len(trim(requestedPage))&gt;
		&lt;cfinvokeargument name=&quot;oldLocation&quot; value=&quot;#requestedPage#&quot; /&gt;
	&lt;/cfif&gt;
	&lt;/cfinvoke&gt;
	&lt;cfif isDefined(&quot;newLocation&quot;) and len(trim(newLocation))&gt;
		&lt;cfset newPage = newLocation /&gt;
	&lt;/cfif&gt;
	&lt;cfcatch&gt;
		&lt;cfset newPage = &quot;&quot; /&gt;
	&lt;/cfcatch&gt;
&lt;/cftry&gt;
&lt;/cfsilent&gt;
&lt;cfif isDefined(&quot;newPage&quot;) and len(trim(newPage))&gt;
&lt;!--- requested page is a known &apos;old page&apos; from prior site ---&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
&lt;cfheader statuscode=&quot;301&quot; statustext=&quot;Moved permanently&quot; /&gt;
&lt;cfheader name=&quot;Location&quot; value=&quot;http://www.yourDomainHere.com#newPage#&quot; /&gt;
&lt;title&gt;This page has moved to http://www.yourDomainHere.com&lt;cfoutput&gt;#newPage#&lt;/cfoutput&gt;&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
This page has moved to &lt;cfoutput&gt;&lt;a href=&quot;http://www.yourDomainHere.com#newPage#&quot;&gt;http://www.yourDomainHere.com#newPage#&lt;/a&gt;&lt;/cfoutput&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;cfelse&gt;
&lt;!--- requested page is NOT a known &apos;old page&apos; from prior site and doesn&apos;t exist ---&gt;
&lt;cf_layout 	title=&quot;Hmm, the page you&apos;re looking for can&apos;t be found.&quot; 
				keywords=&quot;404,page,not,found&quot; 
				description=&quot;Hmm, the page you&apos;re looking for can&apos;t be found. You may have clicked a bad link or mistyped the web address.&quot;&gt;
	&lt;h1&gt;Hmm, the page you&apos;re looking for can&apos;t be found.&lt;/h1&gt;
	&lt;p&gt;You may have clicked a bad link or mistyped the web address.&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;/&quot;&gt;Return home&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;javascript:history.back();&quot;&gt;Go back to the previous page&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
&lt;/cf_layout&gt;
&lt;/cfif&gt;
&lt;/code&gt;
&lt;p&gt;As you can see, I like to use a custom tag to handle the layout of my pages, etc. You can find out more about that at &lt;a href=&quot;http://www.coldfusionjedi.com/index.cfm/2007/9/3/ColdFusion-custom-tag-for-layout-example&quot; target=&quot;_blank&quot;&gt;Raymond Camden&apos;s site&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I hope this helps a fellow ColdFusion developer. Thanks for reading!&lt;/p&gt;
				
				</description>
						
				
				<category>ColdFusion</category>				
				
				<category>Web Usability</category>				
				
				<category>Search Engine Optimization</category>				
				
				<pubDate>Tue, 30 Dec 2008 18:37:00 -0700</pubDate>
				<guid>http://www.stephenwithington.com/blog/index.cfm/2008/12/30/Using-ColdFusion-to-Handle-HTTP-404-Page-Not-Found-Errors</guid>
				
			</item>
			
		 	
			
			
			<item>
				<title>Why is My Browser NOT Supported?</title>
				<link>http://www.stephenwithington.com/blog/index.cfm/2008/11/17/Why-is-My-Browser-NOT-Supported</link>
				<description>
				
				&lt;p&gt;I don&apos;t know about you, but whenever I run into a &amp;quot;Browser Not Supported&amp;quot; message, I just start to growl. Here&apos;s a screen grab of one I ran into this morning from Eloqua.com.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://www.stephenwithington.com/blog/images//blog/uploadimages/eloqua.gif&quot; width=&quot;450&quot; height=&quot;306&quot; hspace=&quot;5&quot; vspace=&quot;5&quot; border=&quot;0&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Um, yeah, here we are, coming into the year 2009 and there are still several companies in the marketplace that throw &amp;quot;Browser Not Supported&amp;quot; messages to the end user. It&apos;s not like I&apos;m using some antiquated, or completely custom browser either, I&apos;m using Firefox here. This is &lt;em&gt;not&lt;/em&gt; what I call user friendly, &lt;em&gt;&lt;strong&gt;especially for a company that tracks user behavior&lt;/strong&gt;&lt;/em&gt;, among other services. I&apos;m quite surprised by this. Am I alone here?&lt;/p&gt;
				
				</description>
						
				
				<category>Web Usability</category>				
				
				<pubDate>Mon, 17 Nov 2008 10:24:00 -0700</pubDate>
				<guid>http://www.stephenwithington.com/blog/index.cfm/2008/11/17/Why-is-My-Browser-NOT-Supported</guid>
				
			</item>
			
		 	
			
			
			<item>
				<title>CFMail Best-Practices for Sending Web-Generated E-mail (e-cards, forward-to-a-friend, etc.)</title>
				<link>http://www.stephenwithington.com/blog/index.cfm/2008/7/10/CFMail-BestPractices-for-Sending-WebGenerated-Email-ecards-forwardtoafriend-etc</link>
				<description>
				
				&lt;p&gt;There are a number of ColdFusion articles available addressing CFMail being detected as spam, etc. which primarily deal with the &amp;quot;Message-ID&amp;quot; contained in an email&apos;s header. &lt;a href=&quot;http://www.carehart.org/&quot; target=&quot;_blank&quot;&gt;Charlie Arehart&lt;/a&gt; has a couple of detailed examples on his blog which I recommend other ColdFusion developers consider reading:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://carehart.org/blog/client/index.cfm/2007/12/7/cfmail_messageid_solution_for_CF8&quot; target=&quot;_blank&quot;&gt;CF8 Hidden Gem: CFMAIL auto-generated message-id uses specified mail server name&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://carehart.org/blog/client/index.cfm/2008/4/8/cfmail_messageid_solution_for_CF6and7&quot; target=&quot;_blank&quot;&gt;CFMAIL being detected as spam? Some solutions for CF 6, 7, and 8&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While we will also be dealing with email headers, this article is primarily concerned with addressing suggestions brought forth by the &lt;a href=&quot;http://www.openspf.org/&quot; target=&quot;_blank&quot;&gt;Sender Policy Framework (SPF)&lt;/a&gt; and their article titled &lt;a href=&quot;http://www.openspf.org/Best_Practices/Webgenerated&quot; target=&quot;_blank&quot;&gt;How web-generated e-mailers can avoid looking like forgers&lt;/a&gt;. In addition, the vast majority of projects I&apos;m involved with are hosted in a shared-hosting environment. So we won&apos;t be modifying anything in the CFAdmin area. &lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you&apos;re wondering how to view email headers, I found a pretty good link on the &lt;a href=&quot;http://128.175.24.251/headers.htm&quot; target=&quot;_blank&quot;&gt;University of Delaware Police Computer Forensics Lab web site&lt;/a&gt; (I know, sounds pretty serious, doesn&apos;t it).&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The code examples I use here have been tested on ColdFusion  8.0.1. However, these should work with CF 6, 7 and 8.0.0 with very little, if any, modifications.&lt;/p&gt;
&lt;p&gt;To send a web-generated email, you should collect at a minimum the &amp;quot;From&amp;quot; email, the &amp;quot;To&amp;quot; email, a &amp;quot;Message,&amp;quot; and preferably the senders &amp;quot;Name.&amp;quot; Obviously, there are several other things you could collect such as &amp;quot;Subject&amp;quot; and who to &amp;quot;Cc&amp;quot;  or &amp;quot;Bcc,&amp;quot; but let&apos;s just keep this simple for now. So let&apos;s create a form to send a simple message using the following code:&lt;/p&gt;
&lt;code&gt;
&lt;div style=&quot;padding:20px; background-color:#CCCCCC; border:1px solid #000000; width:325px;&quot;&gt;
	&lt;cfform id=&quot;form1&quot; 
			name=&quot;form1&quot; 
			method=&quot;post&quot; 
			action=&quot;#cgi.SCRIPT_NAME#?#cgi.QUERY_STRING#&quot;&gt;
		&lt;p&gt;&lt;label for=&quot;messageFromName&quot;&gt;From Name:&lt;/label&gt;&lt;br /&gt;
		&lt;cfinput 	type=&quot;text&quot; 
					name=&quot;messageFromName&quot; 
					id=&quot;messageFromName&quot; 
					value=&quot;Suzie Visitor&quot;  
					validate=&quot;noblanks&quot;
					size=&quot;30&quot; 
					required=&quot;yes&quot; 
					message=&quot;Name is required.&quot; /&gt;&lt;/p&gt;
		&lt;p&gt;&lt;label for=&quot;messageFromEmail&quot;&gt;From Email:&lt;/label&gt;&lt;br /&gt;
		&lt;cfinput 	type=&quot;text&quot; 
					name=&quot;messageFromEmail&quot; 
					id=&quot;messageFromEmail&quot; 
					value=&quot;suzie.vistor@gmail.com&quot; 
					validate=&quot;email&quot; 
					size=&quot;30&quot; 
					required=&quot;yes&quot; 
					message=&quot;A valid email FROM is required.&quot; /&gt;&lt;/p&gt;
		&lt;p&gt;&lt;label for=&quot;messageTo&quot;&gt;To:&lt;/label&gt;&lt;br /&gt;
		&lt;cfinput 	type=&quot;text&quot; 
					name=&quot;messageTo&quot; 
					id=&quot;messageTo&quot; 
					value=&quot;friend@theirdomain.com&quot; 
					validate=&quot;email&quot; 
					size=&quot;30&quot; 
					required=&quot;yes&quot; 
					message=&quot;A valid email TO is required.&quot; /&gt;&lt;/p&gt;
		&lt;p&gt;&lt;label for=&quot;messageText&quot;&gt;Message:&lt;/label&gt;&lt;br /&gt;
		&lt;cfinput	type=&quot;text&quot;
					name=&quot;messageText&quot;
					id=&quot;messageText&quot; 
					value=&quot;My simple message goes here.&quot; 
					validate=&quot;noblanks&quot;
					maxlength=&quot;160&quot; 
					size=&quot;50&quot; 
					required=&quot;yes&quot; 
					message=&quot;Message is required.&quot; /&gt;&lt;/p&gt;
		&lt;p&gt;&lt;cfinput type=&quot;hidden&quot; name=&quot;submitted&quot; value=&quot;1&quot; /&gt;
		&lt;cfinput 	type=&quot;submit&quot; 
					name=&quot;submit&quot; 
					value=&quot;Submit&quot; 
					validate=&quot;submitonce&quot; /&gt;&lt;/p&gt;
	&lt;/cfform&gt;
	&lt;!--- place cursor in the first form element ---&gt;
	&lt;script type=&quot;text/javascript&quot; language=&quot;JavaScript&quot;&gt;
		document.forms[&apos;form1&apos;].elements[&apos;messageFromName&apos;].focus();
	&lt;/script&gt;
&lt;/div&gt;
&lt;/code&gt;
&lt;p&gt;Running the code should  produce something similar to this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://www.stephenwithington.com/blog/images//blog/uploadimages/emailformsample1.gif&quot; alt=&quot;Form Sample 1&quot; width=&quot;250&quot; height=&quot;224&quot; border=&quot;0&quot;&gt;&lt;/p&gt;
&lt;p&gt;The form doesn&apos;t do anything just yet other than post to the page/template it resides on. So let&apos;s go over the important stuff and then add some processing to the page.&lt;/p&gt;
&lt;p&gt;According to &lt;a href=&quot;http://www.openspf.org/Best_Practices/Webgenerated&quot; target=&quot;_blank&quot;&gt;SPF&apos;s article previously mentioned&lt;/a&gt;, when a web site sends web-generated e-mail, a user interacts with the web site, and an e-mail goes out on their behalf. Unfortunately, under SPF, mail from this type of service appears to be a forgery thereby being flagged as spam &amp;mdash; &lt;em&gt;unless&lt;/em&gt; certain precautions are taken. SPF claims that &lt;em&gt;evite.com&lt;/em&gt; and &lt;em&gt;egreetings.com&lt;/em&gt; have made the necessary changes and holds them up as examples  other developers should emulate.&lt;/p&gt;
&lt;p&gt;Your knee-jerk reaction to creating a CFMail to handle the form submission above might look like this:&lt;/p&gt;
&lt;code&gt;
&lt;!---
	in a shared-hosting environment, you&apos;ll need to supply &quot;server&quot;
	and more than likely &quot;username&quot; and &quot;password&quot; too
---&gt;
&lt;cfmail	to=&quot;#trim(FORM.messageTo)#&quot;
		from=&quot;#trim(FORM.messageFromName)# &lt;#trim(FORM.messageFromEmail)#&gt;&quot;  
		server=&quot;mail.yourdomain.com&quot;
		username=&quot;info@yourdomain.com&quot; 
		password=&quot;y0urP@55w0rdH3r3&quot;  
		subject=&quot;Message from: #trim(FORM.messageFromName)#&quot;
		type=&quot;text&quot; 
		charset=&quot;utf-8&quot;&gt;
&lt;cfmailpart type=&quot;text/plain&quot; charset=&quot;utf-8&quot;&gt;
#trim(FORM.messageText)#
&lt;/cfmailpart&gt;
&lt;/cfmail&gt;
&lt;/code&gt;
&lt;p&gt;However, this  might (probably will) appear to be spam because it would generate something like this whilst using &lt;em&gt;&lt;strong&gt;mail.yourdomain.com&lt;/strong&gt;&lt;/em&gt; to send it:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Return-Path: suzie.visitor@gmail.com&lt;br /&gt;
	From: &amp;quot;Suzie Visitor&amp;quot; &amp;lt;suzie.visitor@gmail.com&amp;gt;&lt;br /&gt;
Subject: Message from Suzie Visitor&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;SPF claims that &amp;quot;messages that use the user&apos;s address, but come from your mail servers are considered suspicious by SPF. To solve this problem, just change the headers ...&lt;/p&gt;
&lt;p&gt;Here&apos;s a recommended example from SPF:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Return-Path: &lt;strong&gt;&lt;em&gt;info@yourdomain.com&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
	From: &amp;quot;Suzie Visitor&amp;quot; &lt;strong&gt;&lt;em&gt;&amp;lt;info@yourdomain.com&amp;gt;&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
	&lt;strong&gt;&lt;em&gt;Reply-To: &amp;quot;Suzie Visitor&amp;quot; &amp;lt;suzie.visitor@gmail.com&amp;gt;&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
Subject: Message from Suzie Visitor&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keys to remember:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Choose a general address from your domain (info@yourdomain.com)&lt;/li&gt;
	&lt;li&gt;Add / Change the return-path (or &amp;quot;failto&amp;quot; in the CFMail tag) to that address&lt;/li&gt;
	&lt;li&gt;Change the &amp;quot;From&amp;quot; header (&amp;quot;from&amp;quot; in the CFMail tag) to that same address&lt;/li&gt;
	&lt;li&gt;Add a &amp;quot;Reply-To&amp;quot; header  (yep, you guessed it, &amp;quot;replyto&amp;quot; in the CFMail tag) that contains your user&apos;s email address&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, to summarize, you can simply add the following code directly after the form and update the appropriate fields as necessary:&lt;/p&gt;
&lt;code&gt;
&lt;cfparam name=&quot;REQUEST.errors&quot; default=&quot;&quot; /&gt;

&lt;!--- PROCESS FORM SUBMISSION ---&gt;
&lt;cfif isDefined(&quot;FORM.submitted&quot;) and FORM.submitted EQ 1&gt;

	&lt;!--- create an implicit empty array to track form validation errors ---&gt;
	&lt;!--- if using CF 6 or 7, you will have to modify the following line by
	changing the square brackets [] to ArrayNew(1) ---&gt;
	&lt;cfset REQUEST.errors = [] /&gt;

	&lt;!--- validate required form field entries ---&gt;
	&lt;cfif NOT len(trim(FORM.messageFromName))&gt;
		&lt;cfset ArrayAppend(REQUEST.errors, &quot;Name is required.&quot;) /&gt;
	&lt;/cfif&gt;
	&lt;cfif NOT isValid(&quot;email&quot;, trim(FORM.messageFromEmail))&gt;
		&lt;cfset ArrayAppend(REQUEST.errors, &quot;A valid email FROM is required.&quot;) /&gt;
	&lt;/cfif&gt;
	&lt;cfif NOT isValid(&quot;email&quot;, trim(FORM.messageTo))&gt;
		&lt;cfset ArrayAppend(REQUEST.errors, &quot;A valid email TO is required.&quot;) /&gt;
	&lt;/cfif&gt;
	&lt;cfif NOT len(trim(FORM.messageText))&gt;
		&lt;cfset ArrayAppend(REQUEST.errors, &quot;Message is required.&quot;) /&gt;
	&lt;/cfif&gt;

	&lt;!--- as long as there are NO errors, then process the contents ---&gt;
	&lt;cfif NOT ArrayLen(REQUEST.errors)&gt;

	&lt;cftry&gt;
		&lt;!--- send the email ---&gt;
		&lt;cfmail	to=&quot;#trim(FORM.messageTo)#&quot;
				from=&quot;#trim(FORM.messageFromName)# &lt;info@yourdomain.com&gt;&quot; 
				failto=&quot;info@yourdomain.com&quot; 
				username=&quot;info@yourdomain.com&quot; 
				password=&quot;y0urP@55w0rdH3r3&quot; 
				replyto=&quot;#trim(FORM.messageFromName)# &lt;#trim(FORM.messageFromEmail)#&gt;&quot; 
				server=&quot;mail.yourdomain.com&quot; 
				subject=&quot;Message from: #trim(FORM.messageFromName)#&quot;
				type=&quot;text&quot; 
				charset=&quot;utf-8&quot;&gt;
		&lt;cfmailpart type=&quot;text/plain&quot; charset=&quot;utf-8&quot;&gt;
		#trim(FORM.messageText)#
		&lt;/cfmailpart&gt;
		&lt;/cfmail&gt;
		&lt;cfcatch&gt;
			&lt;cfoutput&gt;#cfcatch.Message#&lt;/cfoutput&gt;
		&lt;/cfcatch&gt;
	&lt;/cftry&gt;

	&lt;!--- show friendly message to submitter ---&gt;
	&lt;cfoutput&gt;
		&lt;p&gt;Your message has been sent at &lt;em&gt;#dateformat(now(), &quot;long&quot;)# #timeformat(now(), &quot;long&quot;)#&lt;/em&gt; as follows:&lt;/p&gt;
		&lt;p&gt;TO: #FORM.messageTo#&lt;br /&gt;
		SUBJECT: Message from: #FORM.messageFromName#&lt;br /&gt;
		MESSAGE:&lt;br /&gt;&lt;/p&gt;
		#htmleditformat(FORM.messageText)#		
	&lt;/cfoutput&gt;
	
	&lt;cfelse&gt;
		&lt;!--- if required form values weren&apos;t given, show message to submitter ---&gt;
		&lt;cfoutput&gt;
			&lt;h4&gt;Please review the following issues:&lt;/h4&gt;
			&lt;ul&gt;
				&lt;cfloop index=&quot;intError&quot; from=&quot;1&quot; to=&quot;#ArrayLen(REQUEST.errors)#&quot; step=&quot;1&quot;&gt;
					&lt;li&gt;#REQUEST.errors[intError]#&lt;/li&gt;
				&lt;/cfloop&gt;
			&lt;/ul&gt;		
		&lt;/cfoutput&gt;
	
	&lt;/cfif&gt;

&lt;/cfif&gt;
&lt;/code&gt;
&lt;p&gt;By following this example, you should be able to create some pretty interesting web-generated email applications that fit within the Sender Policy Framework guidelines.&lt;/p&gt;
&lt;p&gt;If you have additional information, please feel free to share it! I hope this helps you in your next project.&lt;/p&gt;
				
				</description>
						
				
				<category>ColdFusion</category>				
				
				<category>Web Usability</category>				
				
				<pubDate>Thu, 10 Jul 2008 13:57:00 -0700</pubDate>
				<guid>http://www.stephenwithington.com/blog/index.cfm/2008/7/10/CFMail-BestPractices-for-Sending-WebGenerated-Email-ecards-forwardtoafriend-etc</guid>
				
			</item>
			
		 	
			
			
			<item>
				<title>How to Opt-Out of IE8 Standards Mode and Other Useful Internet Explorer Troubleshooting Information</title>
				<link>http://www.stephenwithington.com/blog/index.cfm/2008/7/3/How-to-OptOut-of-IE8-Standards-Mode-and-Other-Useful-Internet-Explorer-Troubleshooting-Information</link>
				<description>
				
				&lt;p&gt;As a web designer/developer, we should strive to make each visitors experience as pleasant as possible. So, whether you like it or not, if you&apos;ve chosen the web designer/developer career, you &lt;em&gt;have&lt;/em&gt; to work with Windows&amp;reg; Internet Explorer&amp;reg; (IE).&lt;/p&gt;
&lt;p&gt; I use &lt;a href=&quot;http://www.microsoft.com/windows/downloads/virtualpc/default.mspx&quot; target=&quot;_blank&quot;&gt;Microsoft&apos;s Virtual PC&lt;/a&gt; to test web site display and functionality on various versions of IE (6, 7 and 8 at the moment). Unfortunately, I was experiencing a display issue only in IE8. Now, I realize the number of people currently using IE8 is extremely small. Soon enough though, there will be tens of thousands of people using it right? I might as well try to correct it now rather than pull my hair out later.&lt;/p&gt;
&lt;p&gt;Rather than go into the display issue itself, I found a very useful technique to opt-out of IE8 standards mode. Or, in regular terms, how to make IE8 display a web page as if it were IE7.&lt;/p&gt;
&lt;p&gt;First, I should explain &lt;em&gt;why&lt;/em&gt; I chose this route. For one thing, it quickly fixed the display issue. Is there a better reason?&lt;/p&gt;
&lt;p&gt;All I had to do was include a simple meta tag to the page(s) where the problem was occurring.&lt;/p&gt;
&lt;code&gt;
&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=7&quot; /&gt;
&lt;/code&gt;
&lt;p&gt;Personally, I like to wrap IE specific tags with a bit of ColdFusion:&lt;/p&gt;
&lt;code&gt;
&lt;cfif cgi.HTTP_USER_AGENT contains &quot;msie&quot;&gt;
	&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=7&quot; /&gt;
&lt;/cfif&gt;
&lt;/code&gt;

&lt;p&gt;The downside to using this technique is that you will &lt;em&gt;not&lt;/em&gt; be able to use the latest rendering features available in IE8. Sniff, sniff (cue smallest violin in the world) &amp;hellip; oh well.&lt;/p&gt;
&lt;p&gt;According to information I found on the &lt;a href=&quot;http://www.microsoft.com/windows/products/winfamily/ie/ie8/readiness/&quot; target=&quot;_blank&quot;&gt;IE8 Readiness Toolkit&lt;/a&gt;, you can also address this on a per-site bases by adding a HTTP header:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; X-UA-Compatible:IE=EmulateIE7&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Alternatively, you could use a slightly different meta tag on a per-page basis while still accessing &amp;quot;all Internet Explorer 8 has to offer.&amp;quot;&lt;/p&gt;
&lt;code&gt;
&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=EmulateIE7&quot; /&gt;
&lt;/code&gt;
&lt;p&gt;Word of caution here, using the &amp;quot;EmulateIE7&amp;quot; technique &lt;em&gt;did not&lt;/em&gt; fix my display issue though. I ended up using the first technique with &amp;quot;IE=7&amp;quot; to &amp;quot;correct&amp;quot; the problem.&lt;/p&gt;
&lt;p&gt;Here are some other helpful links relating to working with Internet Explorer, IE8 (Beta 1), etc.:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/windows/downloads/virtualpc/default.mspx&quot; target=&quot;_blank&quot;&gt;Microsoft Virtual PC 2007&lt;/a&gt;
		&lt;ul&gt;
			&lt;li&gt;Software virtualization tool that allows for running a variety of operating systems (OS) on one machine/PC.&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/windows/products/winfamily/ie/ie8/readiness/&quot; target=&quot;_blank&quot;&gt;Internet Explorer 8 (Beta) Readiness Toolkit&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/windows/products/winfamily/ie/ie8/default.mspx&quot; target=&quot;_blank&quot;&gt;Windows Internet Explorer 8 Beta Download&lt;/a&gt;
		&lt;ul&gt;
			&lt;li&gt;If possible, I would actually recommend using Virtual PC instead&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://go.microsoft.com/fwlink/?LinkID=70868&quot; target=&quot;_blank&quot;&gt;Internet Explorer Application Compatibility Virtual PC (VPC) Image&lt;/a&gt;
		&lt;ul&gt;
			&lt;li&gt;This is a link for the Virtual PC Hard Disk Images for testing web sites on IE (including IE6 XP SP2, IE7 Vista, IE8 XP SP2)&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?familyid=E59C3964-672D-4511-BB3E-2D5E1DB91038&amp;amp;displaylang=en&quot; target=&quot;_blank&quot;&gt;Internet Explorer Developer Toolbar
		&lt;/a&gt;
		&lt;ul&gt;
			&lt;li&gt;A pretty decent tool for discovering web page display issues&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/ie/default.aspx&quot; target=&quot;_blank&quot;&gt;Windows Internet Explorer Developer Center&lt;/a&gt;
		&lt;ul&gt;
			&lt;li&gt;Web Developer Resources pertaining to Internet Explorer (and other web design/development activities)&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
&lt;/ul&gt;
				
				</description>
						
				
				<category>ColdFusion</category>				
				
				<category>Internet Explorer</category>				
				
				<category>Web Usability</category>				
				
				<pubDate>Thu, 03 Jul 2008 13:40:00 -0700</pubDate>
				<guid>http://www.stephenwithington.com/blog/index.cfm/2008/7/3/How-to-OptOut-of-IE8-Standards-Mode-and-Other-Useful-Internet-Explorer-Troubleshooting-Information</guid>
				
			</item>
			
		 	
			
			
			<item>
				<title>How to Dynamically Check a Radio Button (and Checkbox) in ColdFusion</title>
				<link>http://www.stephenwithington.com/blog/index.cfm/2008/6/27/How-to-Dynamically-Check-a-Radio-Button-and-Checkbox-in-ColdFusion</link>
				<description>
				
				&lt;p&gt;Although this may seem to be a simple task, dynamically checking a radio button in ColdFusion is not always as easy as dynamically checking a checkbox in ColdFusion. It&apos;s definitely not difficult either. I just thought it might be worth a mention here.&lt;/p&gt;
&lt;p&gt;Let&apos;s first look at how to dynamically check a checkbox in ColdFusion.&lt;/p&gt;
&lt;p&gt;Checkboxes are cool. You see them everywhere in forms throughout the web. And, let&apos;s face it, they&apos;re extremely easy to use. When used in conjunction with XHTML labels, they&apos;re even easier to use for visitors. For example, if you have a label next to a checkbox input, you can wrap the label with a &amp;quot;label tag&amp;quot; which then makes the label itself &amp;quot;clickable.&amp;quot; Simply match the label tag with the checkbox input tag name. Here&apos;s an example:&lt;/p&gt;

&lt;code&gt;
&lt;cfform action=&quot;javascript:void();&quot; 
		method=&quot;post&quot; 
		name=&quot;form1&quot; 
		id=&quot;form1&quot;&gt;

	&lt;div class=&quot;formItem&quot;&gt;
		&lt;cfinput 	type=&quot;checkbox&quot; 
					name=&quot;ckAgree&quot; 
					id=&quot;ckAgree&quot; 
					value=&quot;1&quot; /&gt; 
		&lt;label for=&quot;ckAgree&quot;&gt;I agree&lt;/label&gt;
	&lt;/div&gt;

	&lt;div class=&quot;formSubmit&quot;&gt;
		&lt;cfinput 	type=&quot;submit&quot; 
					name=&quot;submit&quot; 
					label=&quot;Submit&quot; 
					value=&quot;Submit&quot; 
					validate=&quot;submitonce&quot; 
					onkeyup=&quot;javascript:alert(&apos;Submitted!&apos;);&quot; 
					onclick=&quot;javascript:alert(&apos;Submitted!&apos;);&quot; /&gt;
	&lt;/div&gt;

&lt;/cfform&gt;
&lt;/code&gt;

&lt;p&gt;For me, the most common use of a checkbox input is in back-end admin areas to determine whether or not a particular record is active or not. This only requires me to have an &amp;quot;IsActive&amp;quot; field for the record in the database table with a boolean type (yes or no, true or false, 0 or 1). I usually set the default value to true so that when a record is added to the database, it automatically becomes &amp;quot;active&amp;quot; on the back-end. When a back-end user attempts to update the &amp;quot;active&amp;quot; record, they will (or should) see a &amp;quot;checked&amp;quot; checkbox with an &amp;quot;Is Active&amp;quot; label next to it. Once the back-end user no longer needs the record to be active, they simply un-check the &amp;quot;Is Active&amp;quot; checkbox and click submit.&lt;/p&gt;
&lt;p&gt;Now that the item has been archived, when the back-end user attempts to update the record again, the &amp;quot;Is Active&amp;quot; checkbox shouldn&apos;t be &amp;quot;checked&amp;quot; now, should it? So, how do I dynamically check the checkbox?&lt;/p&gt;
&lt;p&gt;Since I&apos;m updating a database record, I&apos;ll need a query to get the current values of the records&apos; fields. So we&apos;ll want to make sure the  query contains  the &amp;quot;IsActive&amp;quot; field. Assuming it does, just call the query and set the checked value to the query&apos;s &amp;quot;IsActive&amp;quot; value. Like so:&lt;/p&gt;

&lt;code&gt;
&lt;!--- get details for the current record ---&gt;
&lt;cfinvoke 	component=&quot;extensions.components.myqueries&quot; 
			method=&quot;getQueryDetails&quot; 
			returnvariable=&quot;returnQueryDetails&quot;&gt;
&lt;cfif isDefined(&quot;URL.id&quot;) AND isNumeric(val(URL.id))&gt;
		&lt;cfinvokeargument name=&quot;id&quot; value=&quot;#val(URL.id)#&quot; /&gt;
&lt;/cfif&gt;
&lt;/cfinvoke&gt;

&lt;cfif returnQueryDetails.recordcount EQ 1&gt;

	&lt;cfform action=&quot;#CGI.script_name#?#CGI.query_string#&quot; 
			method=&quot;post&quot; 
			name=&quot;form1&quot; 
			id=&quot;form1&quot;&gt;
	
		&lt;div class=&quot;formItem&quot;&gt;
			&lt;!--- dynamically check the checkbox ---&gt;
			&lt;cfinput 	type=&quot;checkbox&quot; 
						name=&quot;ckIsActive&quot; 
						id=&quot;ckIsActive&quot; 
						value=&quot;1&quot; 
						checked=&quot;#returnQueryDetails.IsActive#&quot; /&gt; 
			&lt;label for=&quot;ckIsActive&quot;&gt;Is Active&lt;/label&gt;
		&lt;/div&gt;
	
		&lt;div class=&quot;formSubmit&quot;&gt;
			&lt;cfinput 	type=&quot;submit&quot; 
						name=&quot;submit&quot; 
						label=&quot;Submit&quot; 
						value=&quot;Submit&quot; 
						validate=&quot;submitonce&quot; 
						onkeyup=&quot;javascript:alert(&apos;Submitted!&apos;);&quot; 
						onclick=&quot;javascript:alert(&apos;Submitted!&apos;);&quot; /&gt;
		&lt;/div&gt;
	
	&lt;/cfform&gt;

	&lt;cfelse&gt;
	&lt;p&gt;Sorry, the selected record is no longer available.&lt;/p&gt;
&lt;/cfif&gt;

&lt;/code&gt;

&lt;p&gt;In the update query, to capture the new value, I use something similar to the following:&lt;/p&gt;

&lt;code&gt;
&lt;!--- IsActive ---&gt;
, IsActive=&lt;cfif IsDefined(&quot;FORM.isActive&quot;) AND isBoolean(FORM.isActive)&gt;
&lt;cfqueryparam value=&quot;#FORM.isActive#&quot; cfsqltype=&quot;cf_sql_bit&quot; /&gt;
&lt;cfelse&gt;&lt;cfqueryparam value=&quot;0&quot; cfsqltype=&quot;cf_sql_bit&quot; /&gt;&lt;/cfif&gt;
&lt;/code&gt;

&lt;p&gt;If you&apos;re not using a query, the following code might also be helpful in dynamically checking a checkbox:&lt;/p&gt;
&lt;code&gt;
&lt;!--- scope var ---&gt;
&lt;cfparam name=&quot;isActive&quot; default=&quot;0&quot; type=&quot;boolean&quot; /&gt;

&lt;!--- set the current value of the variable ---&gt;
&lt;cfset isActive = 1 /&gt;

&lt;cfinput 	type=&quot;checkbox&quot; 
			name=&quot;IsActive&quot; 
			value=&quot;1&quot; 
			checked=&quot;#IsActive#&quot; /&gt;
&lt;/code&gt;

&lt;p&gt;Another reason for showing the code above is because it&apos;s similar to how I&apos;ll be dynamically checking a radio button. The previous code snippet should be easy enough to follow. We&apos;re simply setting the value of the variable &amp;quot;isActive&amp;quot; to equal true. Then, the checkbox input&apos;s &amp;quot;checked&amp;quot; state is set to be dependent upon the &amp;quot;isActive&amp;quot; variable. I guess it&apos;s easier to read the code than it is to articulate the meaning, eh?&lt;/p&gt;
&lt;p&gt;So, as you may already know, radio buttons are used when you want to offer one, and only one, option from a list of options. We keep the list of options tied together with the &amp;quot;name&amp;quot; attribute. The &amp;quot;name&amp;quot; attribute simply groups the options together, so that of all options sharing the same &amp;quot;name,&amp;quot; only one is actually selected. There are two differentiating attributes, one of which is obviously the &amp;quot;value&amp;quot; which is needed for passing to the database, etc. The other differentiating attribute is the &amp;quot;id.&amp;quot; I use the &amp;quot;id&amp;quot; attribute to tie to the label tag. For usability, you should also use the &amp;quot;label&amp;quot; tag which will also allow the user to simply click the option label to select the desired radio button.&lt;/p&gt;
&lt;p&gt;Let&apos;s assume you have two queries to work with. One contains the list of possible options for the radio buttons. The other query pulls the existing values for the specified record. The idea here is that we&apos;ll output all possible options for the radio button, then check to see if our current record has selected the option being looped over. If so, then &amp;quot;check&amp;quot; it. If not, don&apos;t. Simple enough, eh? Let&apos;s take a look at the code I&apos;ve come up:&lt;/p&gt;
&lt;code&gt;
&lt;!--- get details for the current record ---&gt;
&lt;cfinvoke 	component=&quot;extensions.components.myqueries&quot; 
			method=&quot;getQueryDetails&quot; 
			returnvariable=&quot;returnQueryDetails&quot;&gt;
&lt;cfif isDefined(&quot;URL.id&quot;) AND isNumeric(val(URL.id))&gt;
			&lt;cfinvokeargument name=&quot;id&quot; value=&quot;#val(URL.id)#&quot; /&gt;
&lt;/cfif&gt;
&lt;/cfinvoke&gt;

&lt;!--- get options for radio buttons ---&gt;
&lt;cfinvoke 	component=&quot;extensions.components.myqueries&quot; 
			method=&quot;getRadioButtonOptions&quot; 
			returnvariable=&quot;returnRadioButtonOptions&quot; /&gt;

&lt;!--- scope var ---&gt;
&lt;cfparam name=&quot;IsChecked&quot; default=&quot;0&quot; type=&quot;boolean&quot; /&gt;

&lt;cfif returnQueryDetails.recordcount EQ 1&gt;

	&lt;cfform action=&quot;#CGI.script_name#?#CGI.query_string#&quot; 
			method=&quot;post&quot; 
			name=&quot;form1&quot; 
			id=&quot;form1&quot;&gt;

		&lt;cfoutput query=&quot;returnRadioButtonOptions&quot;&gt;

			&lt;!---
				This should be self-explanatory, but just in case, this is where we
				set the current value of the isChecked variable based on whether or
				not the currently outputted query item matches the value of the
				currently selected record.
			---&gt;
			&lt;cfif returnQueryDetails.OptionID EQ returnRadioButtonOptions.OptionID&gt;
				&lt;cfset isChecked = 1 /&gt;
				&lt;cfelse&gt;
				&lt;cfset isChecked = 0 /&gt;
			&lt;/cfif&gt;

			&lt;div class=&quot;formItem&quot;&gt;
				&lt;cfinput 	type=&quot;radio&quot; 
							name=&quot;OptionID&quot; 
							id=&quot;Choice#OptionID#&quot; 
							value=&quot;#OptionID#&quot; 
							required=&quot;yes&quot; 
							message=&quot;Please select a radio button.&quot; 
							checked=&quot;#isChecked#&quot; /&gt; 
				&lt;!--- usability: if user clicks the title, the option should also be selected ---&gt;
				&lt;label for=&quot;Choice#OptionID#&quot;&gt;#htmleditformat(OptionTitle)#&lt;/label&gt;
			&lt;/div&gt;

			&lt;div class=&quot;formSubmit&quot;&gt;
				&lt;cfinput 	type=&quot;submit&quot; 
							name=&quot;submit&quot; 
							label=&quot;Submit&quot; 
							value=&quot;Submit&quot; 
							validate=&quot;submitonce&quot; 
							onkeyup=&quot;javascript:alert(&apos;Submitted!&apos;);&quot; 
							onclick=&quot;javascript:alert(&apos;Submitted!&apos;);&quot; /&gt;
			&lt;/div&gt;

		&lt;/cfoutput&gt;

	&lt;/cfform&gt;
	
	&lt;cfelse&gt;
	&lt;p&gt;Sorry, the selected record is no longer available.&lt;/p&gt;
&lt;/cfif&gt;
&lt;/code&gt;
&lt;p&gt;That&apos;s pretty much it folks. If you have a different way to handle this, please feel free to share. Hope this helps!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;To learn more about the CFInput tag, visit &lt;a href=&quot;http://cfquickdocs.com/cf8/?getDoc=cfinput#cfinput&quot; target=&quot;_blank&quot;&gt;http://cfquickdocs.com/cf8/?getDoc=cfinput#cfinput&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
				
				</description>
						
				
				<category>ColdFusion</category>				
				
				<category>Web Usability</category>				
				
				<pubDate>Fri, 27 Jun 2008 11:26:00 -0700</pubDate>
				<guid>http://www.stephenwithington.com/blog/index.cfm/2008/6/27/How-to-Dynamically-Check-a-Radio-Button-and-Checkbox-in-ColdFusion</guid>
				
			</item>
			
		 	
			
			
			<item>
				<title>What Width or Size Should I Design the Web Site For?</title>
				<link>http://www.stephenwithington.com/blog/index.cfm/2008/5/14/What-Width-or-Size-Should-I-Design-the-Web-Site-For</link>
				<description>
				
				&lt;p&gt;It&apos;s a question that comes up time and time again: &amp;quot;What width or size should I design the web site for?&amp;quot; Unfortunately, the answer is always the same, &amp;quot;it depends.&amp;quot;&lt;/p&gt;
&lt;p&gt;It depends on what? Well, it depends primarily on two major considerations:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Your target audience&apos;s  screen resolutions&lt;/li&gt;
	&lt;li&gt;The amount of  space needed to display the information in a readable format&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you don&apos;t know the screen resolutions of your target audience, then take a look at &lt;a href=&quot;http://www.w3schools.com/browsers/browsers_stats.asp&quot; target=&quot;_blank&quot;&gt;W3Schools Browser Statistics&lt;/a&gt; and specifically the &lt;a href=&quot;http://www.w3schools.com/browsers/browsers_display.asp&quot; target=&quot;_blank&quot;&gt;Browser Display Statistics&lt;/a&gt; page. There, you&apos;ll find some fairly good information based on their log-files. Of course, if you have access to your client&apos;s web stats, check there first.&lt;/p&gt;
&lt;p&gt;Keep in mind that if you intend to use the entire display width, be sure to leave room for the scroll bars and such. For the most part, simply subtract 20 pixels from the width to determine your maximum design width. For example, if your intended audience is using 800x600, then your maximum width should be 780 pixels.&lt;/p&gt;
&lt;p&gt;I&apos;m all for web site usability and would rather not have to force a visitor to scroll to the right to see important information simply because their monitor&apos;s screen resolution was set lower than the width of my intended layout. However, if your target audience utilizes for example 1024x768, then by all means, feel free to use the extra real estate ... but only if you need to. This might make sense in a corporate environment where you are designing an intranet and you know for sure what dimensions the employees are/would be using.&lt;/p&gt;
&lt;p&gt;People are also visiting the web with their cell phones, PDA&apos;s and other handheld web-enabled devices at an increasing rate. By using Cascading Style Sheets (CSS), you can create an entirely different display to accomodate these visitors. So keep this in mind when planning your design.&lt;/p&gt;
&lt;p&gt;One thing I try to bring up to my design collegues, is to think about how you personally use your web browser(s). Do you expand it to the entire width and height of your available display? I don&apos;t. I usually have several windows open at the same time and rarely do I expand the application to my entire available display. Why do I bring this up? Well, if my display is 1024x768 and the web site is using a full 1004 (or more!) pixels, then I&apos;m probably having to scroll right to see any content.&lt;/p&gt;
&lt;p&gt;So, whilst I&apos;m standing on this soap box, I&apos;ll try to throw in one last thought here. If you are designing a web site for the general public, I would recommend keeping the width within 780 pixels. Why? Because as of January 2008, according to &lt;a href=&quot;http://www.w3schools.com/browsers/browsers_display.asp&quot; target=&quot;_blank&quot;&gt;W3Schools Browser Display Statistics&lt;/a&gt;, approximately 8% of visitors are using 800x600 displays. I know, you&apos;re saying, &amp;quot;but that means 92% are using 1024x768 or higher!&amp;quot; You would be correct. However, I believe 10% is a significant number. Would you be willing to simply ignore or turn away 10% of your paying customers?&lt;/p&gt;
				
				</description>
						
				
				<category>Web Usability</category>				
				
				<pubDate>Wed, 14 May 2008 12:15:00 -0700</pubDate>
				<guid>http://www.stephenwithington.com/blog/index.cfm/2008/5/14/What-Width-or-Size-Should-I-Design-the-Web-Site-For</guid>
				
			</item>
			
		 	
			</channel></rss>