<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Brennan's Blog</title>
	<atom:link href="http://brennan.offwhite.net/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://brennan.offwhite.net/blog</link>
	<description>My Experiences with Software Development</description>
	<lastBuildDate>Thu, 29 Oct 2009 03:56:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>PHP Needs a Foundation</title>
		<link>http://brennan.offwhite.net/blog/2009/10/28/php-needs-a-foundation/</link>
		<comments>http://brennan.offwhite.net/blog/2009/10/28/php-needs-a-foundation/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 00:48:23 +0000</pubDate>
		<dc:creator>Brennan Stehling</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[oss]]></category>

		<guid isPermaLink="false">http://brennan.offwhite.net/blog/?p=570</guid>
		<description><![CDATA[Over the years I have moved from technology to technology based on the popularity of a new language or platform because that how you keep finding work. In high school and college I was taught Basic, Turbo Pascal, COBOL and a little C. In college I taught myself Perl and Java which is what I [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://brennan.offwhite.net/blog/wp-content/uploads/2009/10/PHP-Zend.png" alt="PHP-Zend" title="PHP-Zend" width="306" height="242" class="alignright size-full wp-image-573" style="border: 1px solid #000; padding: 0;" />Over the years I have moved from technology to technology based on the popularity of a new language or platform because that how you keep finding work. In high school and college I was taught Basic, Turbo Pascal, COBOL and a little C. In college I taught myself Perl and Java which is what I actually used when I got my first internship and my first couple of jobs after college. For a short time I got into Java and I really liked JSP, servlets and the maturing <a href="http://java.sun.com/products/jsp/tutorial/TagLibrariesTOC.html">taglib</a> system. Unfortunately Sun started to propose <a href="http://java.sun.com/javaee/javaserverfaces/">JSF</a> but did not really put much energy behind it and it still has yet to make an impact. Other web frameworks for Java like Struts, Tapestry and so many others dominated over JSF because people were using them and they worked. As a consultant at that time I found it very difficult to know all of the available frameworks to any reasonable depth to confidently call myself an expert on the Java platform as web developer. It did not help that Sun did not really put much energy behind Netbeans, their IDE which was being developed by a team of developers who built it using Emacs. So IBM and their contribution to the Java landscape, <a href="http://www.eclipse.org/">Eclipse</a>, took an leadership role in the community where Sun left a massive vacuum.</p>
<p>Why am I recalling this history about Java when the post is supposed to be about PHP? Well, I really liked Java and thought I was going to build my career on it, but it turned out that there was not a sufficient force behind it to keep it moving forward. And while I see PHP as a dominant player among web site development, I do not see the sorts of efforts underway to advance the platform.</p>
<p><span id="more-570"></span></p>
<p>In contrast, I have been working with the .NET Framework which has teams of developers working to make my work easier. One solid example is the release of ASP.NET 2.0 which was in beta when I was building an e-commerce from the ground up. I need a way for users to log in and also manage a database of users. During the ASP.NET 1.0 lifetime Microsoft learned that developers often had to build all these pieces themselves so they created the <a href="http://msdn.microsoft.com/en-us/library/yh26yfzy.aspx">Membership Provider</a> and the <a href="http://msdn.microsoft.com/en-us/library/ms178329.aspx">Login Controls</a> so that you could be up and running within minutes. I was past these requirements quickly and was on to the specifics of the site and leveraged many other features that came with ASP.NET 2.0, such as <a href="http://msdn.microsoft.com/en-us/library/wtxbf3hh.aspx">Master Pages</a> and the new caching features. I was able to create a site with rich features that was really quite fast and my client was very happy.</p>
<p>You might describe these improvements as framework updates because they added some libraries but they also added some tools as well as rich support in the IDE, Visual Studio, so that I could get up and running quickly. The release of Visual Studio 2005 was coordinated with the .NET 2.0 release so taking advantage of all of these features was simplified. Meanwhile IIS, the web server, was also updated to leverage .NET 2.0 features. It was an end-to-end update.</p>
<p>Now you could contrast the benefits of a well coordinated release which truly did make my job a lot easier with how new features trickled out from the Java community. If Sun were to release JSF with a whole series of useful controls along with supporting features in Netbeans and the Tomcat web server it could have energized a lot of developers to get on board and get them all moving in the same direction. It just did not happen. Now I find it hard to find a Java developer who is still doing a lot of work with Java. Many have moved on to Ruby, Python or PHP.</p>
<p>So what about PHP? Sure Yahoo! and others employ some of the core PHP developers and allow them to continue working on the language, but what about developer's needs beyond the language? What about a rich IDE which is synced to support new language features? What about releasing rich libraries which solve the most common developer concerns?</p>
<p>What I see is large projects like Wordpress and Drupal growing up on top of PHP, with their own communities as a structure onto itself. People build on Wordpress or Drupal as the platform, using tools in the web application itself to make changes to the platform through extensions or plugins and custom modules which just happen to be written in PHP. There is no IDE and there is no need for the PHP community to have role in this space. But there is an opportunity here for the core PHP team to provide support to platforms like Wordpress and Drupal.</p>
<p>Over the last year I have asked PHP developers a lot of questions. I often ask them what they use to edit PHP code and they all have a different answer. I personally edit it with VIM with color support because I often have it on my FreeBSD server. Others use Coda, DreamWeaver, Eclipse or Aptana Studio. It seems there is no clear IDE of choice. </p>
<p>I also find that people do not describe themselves as PHP developers. Instead they say they are Wordpress or Drupal developers and they work largely within the web application to "develop" the web site. I am not sure if many of them touch actual PHP code that often. There is nothing wrong with that, but it is very interesting.</p>
<p>Back when Netscape open sourced their web browser they created a new organization to watch over it. It became Mozilla which is now largely known for Firefox which has become a very popular web browser which innovates with new features from HTML5 as well as a rich extension model. This organization makes money through a search engine deal with Google, which allows them to focus on making a great web browser. I like that model. The goal of the company is to make a great web browser. They are not a small group of developers working for a big web-based company that simply allows them work on their little open source project. There is some urgency that they compete with others like Internet Explorer, Safari and Chrome. This competition drives them.</p>
<p>So back to PHP, I know that some PHP developers work for Yahoo! and they can focus on the language, but maybe they should form a foundation that is similar to the <a href="http://apache.org/">Apache Foundation</a> which receives sponsorship money and support from several companies while continuing to produce software which is widely used and respected. I believe the Apache Foundation is the most respectable and most important open source organization there has ever been. It has essentially ensured that no company has been able to take over the web as their own proprietary platform and kept it open and honest. This group has also played a big role in moving the web forward. What could something called the PHP Foundation do?</p>
<p>For starters, I think they could work to refactor out the best features of the most used PHP applications so they can leverage a common code base which continues to improve over time, possibly with rich support from a common IDE. New features could be planned, announced, beta tested and released at a major PHP conference which includes Wordpress and Drupal which have been holding their own separate conferences. The entire community should be unified, not fragmented.</p>
<p>I realize that choice is important for some, but do you really need 37+ MVC frameworks for PHP? What if you had a mature MVC framework that was planned through the PHP Foundation after gathering community feedback, beta tested and then released after providing time for IDE developers for Eclipse and Aptana Studio to support these features? I think you would start to see some real energy behind the platform and innovation that you just are not getting right now from PHP as a language.</p>
<p>As a part of this PHP Foundation they could take on other open source projects and bring them into platform. After MySQL was bought by Sun and then pulled into Oracle and subsequently forked to get it away from Oracle the PHP Foundation could be a good new home for what is the newly forked MySQL. And what about continued integration and the Apache Foundation and the Apache web server which works well with PHP now, but there is so much more it could do.</p>
<p>What I would also like to see is a Just-In-Time Compiler for PHP which we have been seeing with JavaScript in Firefox, Chrome and Safari lately. Does a JIT for PHP exist already? It is under development? Could a PHP Foundation fund this development? And how much would a dramatically more efficient PHP runtime be? Yahoo! and other major providers using PHP would not need as much processing power that they have now if PHP was JIT'd.</p>
<p>But why does this matter to me if I am happy working with .NET/Mono? Well, I prefer to work with HTML, CSS and JavaScript which are web standards but there is no official server-side programming language. Back in the late 90's the de facto standard was Perl and these days it seems PHP has grown to become modern de facto standard. If that is the case, there is a good chance I will be making a move to work in PHP in the future. But I do not want to move to just a language. I want an entire platform that has vision, energy and a plan.</p>
<p>I also see an opportunity for the PHP Foundation to release reference applications of good PHP architecture that shows how the best PHP developers do it and how you should do it as well. Along these sample web sites I would want tutorials which train everyone to write good code in PHP. Over the past 2 years Microsoft realized that the ASP.NET community wanted MVC, so they developed it as open source and released it. On the first day it was able to run on Linux with Mono and you can learn how to use it with the <a href="http://www.microsoft.com/Downloads/details.aspx?familyid=1E0BE0B2-910A-4676-9F3A-41E4D9C0FC08&#038;displaylang=en">ASP.NET MVC Training Kit</a>. Beyond the training kit there are <a href="http://www.asp.net/Learn/mvc/">written and video tutorials available</a>.</p>
<p>This is what I see is missing from the PHP community. Sure the developers have jobs which allow them to work full time on the language, but do they have teams producing sample projects, writing papers, preparing video tutorials and organizing workshops and conferences to train the community about all of the latest features of the platform? If I saw this happen, I would find it to be a very appealing community and platform.</p>
<p>I am interested in what you think. I realize I do not know everything about what is going on with PHP, so please fill me in. What is going with PHP that you think is going right? And what do you agree could be done to improve on the PHP ecosystem?</p>
<p>[ Image courtesy of Creative Commons and <a href="http://www.flickr.com/photos/calevans/2265072893/in/photostream/">calevans</a>. ]</p>
]]></content:encoded>
			<wfw:commentRss>http://brennan.offwhite.net/blog/2009/10/28/php-needs-a-foundation/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>iMade &#8211; Mobile Application Development Event &#8211; iPhone</title>
		<link>http://brennan.offwhite.net/blog/2009/10/06/imade/</link>
		<comments>http://brennan.offwhite.net/blog/2009/10/06/imade/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 03:21:50 +0000</pubDate>
		<dc:creator>Brennan Stehling</dc:creator>
				<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://brennan.offwhite.net/blog/?p=556</guid>
		<description><![CDATA[
 On October 24 you will want to attend iMade if you are interested in learning about designing or developing for the iPhone. Prior to the event developers can work with each other on various coding tasks and discuss any issues that come up during development. As all the tasks are completed the pieces to [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; padding: 5px;"><a href="http://www.theresgonnabesnacks.com/iMade/"><img src="http://brennan.offwhite.net/blog/wp-content/uploads/2009/10/iMade.png" alt="iMade" title="iMade" width="330" height="119" class="alignnone size-full wp-image-557" /></a></div>
<p> On October 24 you will want to attend <a href="http://www.theresgonnabesnacks.com/iMade/">iMade</a> if you are interested in learning about designing or developing for the iPhone. Prior to the event developers can work with each other on <a href="http://groups.google.com/group/mwiphonesdk/browse_thread/thread/de1cf2b8e89e59b4">various coding tasks</a> and discuss any issues that come up during development. As all the tasks are completed the pieces to build the final application on the day of the iMade event will be ready. </p>
<p>On the day of the event we will cover three areas: User Experience Design, Graphic Design and Objective-C Coding for the iPhone. The rules of User Experience Design (UXD) for the desktop is not the same for a mobile device or even across different mobile devices, so we will cover the guidelines provided by Apple for the iPhone and developer the UXD and workflow for the demo application.</p>
<p><span id="more-556"></span></p>
<p>Once we have the UXD workflow ready we will work on the graphics to make the application look as good as we can make it. We can use PNG images for backgrounds, iconography as well as styling the UI controls available for the iPhone via Interface Builder. We will go over several examples and put together an attractive design for this applications.</p>
<p>Finally we will assemble all of the pieces, including <a href="http://code.google.com/p/mwiphonesdk/issues/list">code snippets which are under development</a> already, and produce the final application which will allow you to find a list of area groups and subscribe to them, their RSS and calendar feeds and keep track of up coming events and stay current with their latest news.</p>
<p>Check out the <a href="http://www.theresgonnabesnacks.com/iMade/">iMade web site</a> for more details and to register. Space is limited.</p>
]]></content:encoded>
			<wfw:commentRss>http://brennan.offwhite.net/blog/2009/10/06/imade/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Parsing CSV Data, the Easy Way</title>
		<link>http://brennan.offwhite.net/blog/2009/09/17/parsing-csv-data-the-easy-way/</link>
		<comments>http://brennan.offwhite.net/blog/2009/09/17/parsing-csv-data-the-easy-way/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 21:50:45 +0000</pubDate>
		<dc:creator>Brennan Stehling</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[dotnet]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://brennan.offwhite.net/blog/?p=554</guid>
		<description><![CDATA[Download: SmallSharpTools.Extensions.zip
I am always surprised how there is no direct support for parsing CSV data in .NET even though Microsoft Excel can export data to CSV and it is infinitely easier to parse a CSV file than an Excel document. (correct me if I am wrong) I rarely deal with files anymore and when I [...]]]></description>
			<content:encoded><![CDATA[<div style="width: 285px; text-align: center; float: right; margin: 5px; padding: 5px; border: 1px solid #999;"><strong>Download:</strong> <a href="http://www.smallsharptools.com/Downloads/SmallSharpTools.Extensions.zip">SmallSharpTools.Extensions.zip</a></div>
<p>I am always surprised how there is no direct support for parsing CSV data in .NET even though Microsoft Excel can export data to CSV and it is infinitely easier to parse a CSV file than an Excel document. (correct me if I am wrong) I rarely deal with files anymore and when I do they are typically XML formatted, so when it came time to parse some CSV files I browsed <a href="http://www.codeplex.com/">CodePlex</a> for a project which would handle this task for me. There are several options there but nothing looked right for me so I searched <a href="http://www.codeproject.com/">Code Project</a> and found <a href="http://www.codeproject.com/KB/database/CsvReader.aspx">CsvReader</a> which is designed for reading large CSV documents quickly. Great, it had unit tests and all but 1 of the many tests passed so I got to using right away.</p>
<p>I finished my work on this particular project and today my client sends me an updated input file which does not include header lines and actually starts out with a few blank lines. I also found that the last field in some rows were blank and these differences were enough to break all of my code which was using CsvReader. I tried to dig through the code and recompile an updated version that would safely handle my new requirements but it was too much work. This particular document has 3 types of rows: batch, header, and detail. Each of these line types has a different number of fields and CsvReader seems to assume all lines with have the same number of fields and throws exceptions if it does not like what it reads. It is very inflexible and unforgiving. And if the last column has no value it also throws an exception. It was not helpful in the slightest. </p>
<p><span id="more-554"></span></p>
<p>Now the only reason to use a complex CSV parser is the condition that a field contains a comma and is then wrapped with quotes. I created a spreadsheet with Microsoft Excel 2007 with values with commas and exported the document to CSV format. It was simple enough with double quotes around the fields which had commas in the value. With a little coding I could do this. And with a little .NET 3.5 I could do it as a set of extension methods with the proper amount of unit tests and safely start using it in this project, so that is what I did. In about a half hour I had it all working with unit tests and was able to quickly integrate it with the client application and get it to pass all of the unit tests for business logic.</p>
<p>Below you can see the extension class which is just a little over 100 lines of code. I hope that you find it easy to read and understand in case you need to extend it to account for more complexities in your CSV files. You can download the project and see how to make use of it with the unit tests. It only accounts for double quoted fields, so if you do have single quoted fields you will need to make an update to this class. If I find this parser is not sufficient I will probably create more unit tests and add more functionality as needed. For now it is doing the job and I am happy to share it with anyone who would like to use freely.</p>
<pre class="code">
<form><textarea name="code" class="c#">
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace SmallSharpTools.Extensions
{

    public static class StringExtensions
    {

        public const char Comma = ',';
        public const char DoubleQuote = '"';

        public static string[] SplitCsvLine(this String line)
        {
            if (line.Contains(DoubleQuote))
            {
                return SplitComplexLine(line);
            }
            else
            {
                return SplitSimpleLine(line);
            }
        }

        private static string[] SplitSimpleLine(string line)
        {
            var fields = new List<String>();
            var parts = line.Split(Comma.ToString().ToCharArray(), StringSplitOptions.None);
            foreach (var field in parts)
            {
                fields.Add(field.Trim());
            }
            return fields.ToArray();
        }

        private static string[] SplitComplexLine(string line)
        {
            var fields = new List<String>();
            var chars = line.ToCharArray();
            var sb = new StringBuilder();

            for (var i = 0; i < chars.Length; i++)
            {
                var currentChar = chars[i];
                if (currentChar == Comma)
                {
                    fields.Add(sb.ToString().Trim());
                    sb = new StringBuilder();
                }
                else if (currentChar == DoubleQuote)
                {
                    // read to the next double quote
                    i++; // advance one character
                    currentChar = chars[i];
                    // read until the next double quote is found
                    while (currentChar != DoubleQuote)
                    {
                        sb.Append(currentChar.ToString());
                        i++;
                        // throw an exception if it exceeds chars.Length
                        if (i >= chars.Length)
                        {
                            throw new ApplicationException("CSV line is invalid.");
                        }
                        currentChar = chars[i];
                    }
                }
                else
                {
                    sb.Append(currentChar.ToString());
                }
            }

            // add the last column
            fields.Add(sb.ToString().Trim());

            return fields.ToArray();
        }

        public static IEnumerable<string[]> ParseCsvData(this String csvData)
        {
            return csvData.ParseCsvData(true);
        }

        public static IEnumerable<string[]> ParseCsvData(this String csvData, bool skipBlankLines)
        {
            var result = new List<string[]>();

            using (var sr = new StringReader(csvData))
            {
                String line = String.Empty;
                while ((line = sr.ReadLine()) != null)
                {
                    if (skipBlankLines &#038;& !String.IsNullOrEmpty(line))
                    {
                        var csv = line.SplitCsvLine();
                        result.Add(csv);
                    }
                    else if (!skipBlankLines)
                    {
                        var csv = line.SplitCsvLine();
                        result.Add(csv);
                    }
                }
            }

            return result;
        }

    }

}
</textarea></form>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://brennan.offwhite.net/blog/2009/09/17/parsing-csv-data-the-easy-way/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Twitter Bookmarklet: I Just Read (IJR)</title>
		<link>http://brennan.offwhite.net/blog/2009/04/29/twitter-bookmarklet-i-just-read-ijr/</link>
		<comments>http://brennan.offwhite.net/blog/2009/04/29/twitter-bookmarklet-i-just-read-ijr/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 16:00:11 +0000</pubDate>
		<dc:creator>Brennan Stehling</dc:creator>
				<category><![CDATA[twitter]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://brennan.offwhite.net/blog/?p=553</guid>
		<description><![CDATA[There are lots of social networking sites like Digg that let you tell others about what is a good read. But you can bypass these sites and directly tell everyone about good reads using Twitter. So I created a simple bookmarklet that you can click to send set the title and link to the page [...]]]></description>
			<content:encoded><![CDATA[<p>There are lots of social networking sites like Digg that let you tell others about what is a good read. But you can bypass these sites and directly tell everyone about good reads using Twitter. So I created a simple bookmarklet that you can click to send set the title and link to the page you are currently on to Twitter where you can submit your new post.</p>
<p>Bookmarklet: <a href="javascript:document.location.href='http://twitter.com/home?status='+encodeURIComponent('IJR: ')+encodeURIComponent(document.title)+' - '+encodeURIComponent(location.href)">IJR</a></p>
<p><img src="http://brennan.offwhite.net/images/blog/IJR-Bookmarklet.png" alt="IJR Bookmarklet" style="margin-left: 20px;" /></p>
<p>I have this bookmarklet on my links toolbar in Firefox and Chrome along with other bookmarklets I have created. Feel free to drag this bookmarklet to your bookmarks bar and start sharing your IJR posts on Twitter.</p>
]]></content:encoded>
			<wfw:commentRss>http://brennan.offwhite.net/blog/2009/04/29/twitter-bookmarklet-i-just-read-ijr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modern JavaScript Techniques</title>
		<link>http://brennan.offwhite.net/blog/2009/04/21/modern-javascript-techniques/</link>
		<comments>http://brennan.offwhite.net/blog/2009/04/21/modern-javascript-techniques/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 19:52:37 +0000</pubDate>
		<dc:creator>Brennan Stehling</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://brennan.offwhite.net/blog/?p=552</guid>
		<description><![CDATA[In my interview with The Thirsty Developer podcast I mentioned some modern JavaScript techniques. It is hard to explain these techniques in a podcast so I wanted to post them here.

Learn more about JavaScript and jQuery at BootWorks, Wednesday, April 22. [ Details ]

The biggest problem area I work to avoid when working with JavaScript [...]]]></description>
			<content:encoded><![CDATA[<p>In my interview with <a href="http://thirstydeveloper.com/2009/04/20/TheThirstyDeveloper59JQuery.aspx">The Thirsty Developer podcast</a> I mentioned some modern JavaScript techniques. It is hard to explain these techniques in a podcast so I wanted to post them here.</p>
<div style="border: 1px solid #ccc; background-color: #ddf; padding: 3px; font-size: 0.9em; text-align: center;">
Learn more about JavaScript and jQuery at BootWorks, Wednesday, April 22. [ <a href="http://www.bootworks.org/Training/Track-001-Building-Web-2.0/Session-2/">Details</a> ]
</div>
<p>The biggest problem area I work to avoid when working with JavaScript is the scoping issue. It has been very common to simply create a series of functions and call them however you see fit from event handlers in your HTML. This was all fine when you had 300 lines of JavaScript for your entire site because it was just used for a slight site enhancement. Now if you are building a much more complex site with lots of interaction, you will have several thousand lines of code. Every one of these functions and variables that you define are all placed in the global scope, which is the window object. Consider the following code.</p>
<pre class="code">
<form><textarea name="code" class="js">
var AnyVariableName = 1;
alert(AnyVariableName);
</textarea></form>
</pre>
<p>This code is equivalent to the following code, assuming this code is in the global scope and not within a function block.</p>
<pre class="code">
<form><textarea name="code" class="js">

window['AnyVariableName'] = 1;
alert(AnyVariableName);

</textarea></form>
</pre>
<p>Why is this useful? Well, if you are within a function block and declare a variable the scope of that variable is limited to that function block. If you want to declare a variable and put it into the global scope you can use the window object in this way to do so. (Hint: window is the container for the global scope.)</p>
<p><span id="more-552"></span></p>
<p>But you do not want to dirty up the global scope which will lead to naming conflicts and code that is very difficult to maintain. What you may want is namespacing so that you can isolate blocks of code in an organized structure. There is no language feature in JavaScript for namespaces like you find in C# or VB.NET but you can put references into objects. The following code declares a variable which is an object that holds onto properties.</p>
<pre class="code">
<form><textarea name="code" class="js">
var MyStuff = { };
MyStuff.CurrentIndex = 0;
MyStuff.Increment = function() { return ++MyStuff.CurrentIndex; };
</textarea></form>
</pre>
<p>This is one way that you can manage scope, but when you start to have a fuller hierarchy you can imagine that this would become difficult to manage. So you can leverage the Module Pattern where you declare everything without regard for scope and then wrap it in what is now being called a module.</p>
<pre class="code">
<form><textarea name="code" class="js">
(function(){
var $currentIndex = 0;
var $increment = function() { return ++MyStuff.CurrentIndex; };
}());
</textarea></form>
</pre>
<p>The first and last lines are a little hard to understand when you see it for the first time. Think of it like algebra. When you want to manage scope in an expression you use parentheses. This way you can make an expression like <code>(4 + 2) * 3</code> to ensure that the 4 and 2 are added before the result is multiplied by 3. The same premise works here with the Module Pattern. What happens outside the parentheses does not affect what is inside. Then the first thing in the container is an anonymous function, but notice when the function block is closed there is a set of parentheses which causes the function to be executed immediately. The code in the function block is executed immediately and then contained with the scope of that function block. In the case of this code snippet nothing is happening because the code is not doing anything. How is this useful?</p>
<p>In the code below we will reference a little jQuery code to attach an event handler function. This code will find all anchor tags on the page which have <code>Close</code> as a class value and attach a click event. This click event will hide the parent container of the anchor element.</p>
<pre class="code">
<form><textarea name="code" class="js">
(function(){
  $('a.Close').click(function(e) {
    e.preventDefault();
    $(this).parent().hide();
  });
}());
</textarea></form>
</pre>
<p>This code is isolated and executed, leaving nothing in the global scope while the function that is attached to any matching anchor tags is still accessible because the element is now bound to the function as a click event handler.</p>
<p>Now you may want to start organizing this nicely scoped code into namespaces and you can do so by declaring your variables and functions within the module and export them to through a global variable, as shown in the code below.</p>
<pre class="code">
<form><textarea name="code" class="js">
(function(){
var $closeAllModals = function() {
  $('div.Modal').hide();
};
window['SST'] = {};
SST.CloseAllModals = $closeAllModals;
}());
</textarea></form>
</pre>
<p>Now you can do whatever you like within your module and export the public portions you choose. In this case I added the reference for the function to a container named SST. I can now access it anywhere in my code. The key difference here is that now all my code for this site will be held within the SST container and I will not have to be concerned with using third party libraries which may place variables into the global scope. Most libraries, like jQuery, will declare the minimal amount of variables in the global scope. The jQuery library uses <code>$</code> and <code>jQuery</code> for the global scope and then functions, variables and plugins used by jQuery are held under that scope. The same is true for libraries like the Yahoo UI library which uses <code>YUI</code> in the global scope. </p>
<p>As you write more code and need to organize it further you will want to have multiple levels in your namespace hierarchy. You can easily chain containers together, such as the following code.</p>
<pre class="code">
<form><textarea name="code" class="js">
(function(){
window['SST'] = {};
SST.Data = {};
SST.Services = {};
SST.Methods = {};
}());
</textarea></form>
</pre>
<p>When you have a lot of code you will want to split it across multiple files, so declaring your namespace hierarchy from a central point may not be ideal, so you will want to use a function that will build your structure in a simple way.</p>
<pre class="code">
<form><textarea name="code" class="js">
(function(){
SST.CreateNamespace('SST.Data.Products');
SST.CreateNamespace('SST.Data.Customers');
SST.CreateNamespace('SST.Services.Validation');
SST.CreateNamespace('SST.Services.Checkout');
}());
</textarea></form>
</pre>
<p>Not every page will use every script and if you have 500kb of script you want to use the minimal amount of code on each page, so I find it best to ensure the namespace that I am defining in this module is defined within the module.</p>
<pre class="code">
<form><textarea name="code" class="js">
(function(){
var basketItems = [];
var shippingZip = 55555;
var $getShippingTotal = function() {
  // do stuff
};

var $submitOrder = function() {
  // do stuff
};

SST.CreateNamespace('SST.Services.Checkout');
SST.Services.Checkout.GetShippingTotal = $getShippingTotal;
SST.Services.Checkout.SubmitOrder = $submitOrder;
}());
</textarea></form>
</pre>
<p>Now I have my functions and variables defined in an isolated scope where the functions can access these variables, which are now effectively private variables, and the public functions are exposed through the namespace structure.</p>
<p>Since I use these techniques often I have created a core library that I have been using for many projects this past year. I call it <a href="http://www.smallsharptools.com/downloads/JavaScript/core.js">core.js</a> and it includes the <code>CreateNamespace</code> function that I referenced in the code snippets above. And if you are using Visual Studio, you can use <a href="http://www.smallsharptools.com/downloads/JavaScript/core-vsdoc.js">core-vsdoc.js</a> to get Intellisense support in any of your code that is using core.js.</p>
<p>In addition to namespace support, you will also find a lightweight StringBuilder object in core.js which is useful if you are assembling HTML with your code so you can avoid the overhead that comes with string concatenation.</p>
<p>There is a lot more that I will be covering going forward, such as common jQuery techniques, currying and callbacks. Please check back for that content.</p>
<p>Find me on Twitter: <a href="http://twitter.com/smallsharptools">@smallsharptools</a>.</p>
<h3>Recommended Reading</h3>
<ul>
<li><a href="http://brennan.offwhite.net/blog/2009/04/13/embracing-jquery-and-learning-javascript-all-over-again/">Embracing jQuery and Learning JavaScript All Over Again</a></li>
<li><a href="http://brennan.offwhite.net/blog/2008/05/12/recommended-books-on-javascript/">Recommended Books on JavaScript</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://brennan.offwhite.net/blog/2009/04/21/modern-javascript-techniques/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Embracing jQuery and Learning JavaScript All Over Again</title>
		<link>http://brennan.offwhite.net/blog/2009/04/13/embracing-jquery-and-learning-javascript-all-over-again/</link>
		<comments>http://brennan.offwhite.net/blog/2009/04/13/embracing-jquery-and-learning-javascript-all-over-again/#comments</comments>
		<pubDate>Mon, 13 Apr 2009 19:00:00 +0000</pubDate>
		<dc:creator>Brennan Stehling</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://brennan.offwhite.net/blog/?p=551</guid>
		<description><![CDATA[Now that ASP.NET MVC has been released and jQuery is included it is time for every ASP.NET developer to start embracing jQuery. I personally have been using jQuery and other JavaScript libraries for the past few years. Ever since JavaScript became popular again thanks to the likes of the Google Mail interface in 2004 and [...]]]></description>
			<content:encoded><![CDATA[<p>Now that ASP.NET MVC has been released and jQuery is included it is time for every ASP.NET developer to start embracing <a href="http://jquery.com/">jQuery</a>. I personally have been using jQuery and other JavaScript libraries for the past few years. Ever since JavaScript became popular again thanks to the likes of <a href="http://brennan.offwhite.net/blog/2004/06/17/gmail-and-yahoo-mail/">the Google Mail interface</a> in 2004 and the naming of <a href="http://www.adaptivepath.com/publications/essays/archives/000385.php">AJAX by  Jesse James Garrett</a> in 2005.</p>
<p>With JavaScript becoming a central piece of a modern web application, I decided that I had to start taking it seriously. For years I only used JavaScript to enhance a page and ensured that if the user had JavaScript disabled the page would still work as required. It was time consuming to add a lot of JavaScript and it was often not worthwhile. Starting in 2004 I started seeing more and more sites start building sites which simply would not work without JavaScript. I decided that since I plan to do web development for many more years to come that I had to learn how this was all done, and I found that these modern sites were leveraging JavaScript libraries that would abstract away browser differences and reduce the effort necessary to implement a rich experience.</p>
<p><span id="more-551"></span></p>
<p>I tried out several libraries and after working with libraries like <a href="http://www.prototypejs.org/">Prototype</a> and <a href="http://mootools.net/">MooTools</a> I settled on jQuery. The compelling features of jQuery were the small download size along with the powerful plugin model with a rich collection of available plugins. The other libraries are still useful, but jQuery is what I reach for first and it typically does not let me down.</p>
<p>An important point that I have to get across to developers and designers who are getting into jQuery is that it is not a replacement for JavaScript. It is simply a compatibility layer that has an elegant interface which is far easier to use than the standard <a href="http://www.w3.org/DOM/">DOM API</a>. It is still necessary to understand JavaScript to build modern web applications well. I also stress the fact that you must have a strong grasp on HTML and CSS because jQuery manipulates HTML and CSS to achieve the interactive features that you are building with jQuery.</p>
<p>Web page layout is known as the <a href="http://www.w3.org/TR/CSS2/box.html">Box Model</a>. It is a simple concept but working with it can be difficult with many browsers which do not behave in the same way. CSS alone can be intimidating, but if you break it down and keep it simple for a while you can pick it all up gradually. I have found books by <a href="http://meyerweb.com/eric/css/">Eric Meyer</a> and <a href="http://www.zeldman.com/">Jeffrey Zeldman</a> to be the best resources to master the Box Model.</p>
<p>I have been doing web development for a very long time and back in 1999 the JavaScript that I wrote then is very different than what I am writing now. I have had to unlearn a lot of bad coding practices. The most difficult lesson that I have learned is that every book back then had it all wrong. When I read <a href="http://jspro.org/">Pro JavaScript Techniques</a> by <a href="http://ejohn.org/blog/">John Resig</a> I finally started to see the language as it was meant to be. A year later I found <a href="http://oreilly.com/catalog/9780596517748/">JavaScript: The Good Parts</a> by <a href="http://www.crockford.com/">Douglas Crockford</a> which is a book that you must read. It is packed full of important details you wish you had known before, and it is a very short book which makes it much easier to finish reading. <img src='http://brennan.offwhite.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Both of these books are the foundation for all of the modern techniques I am using every day. And a new book coming soon by John Resig called <a href="http://jsninja.com/">Secrets of the JavaScript Ninja</a> will cover additional topics that he did not get deep into in with his first book.</p>
<p>Once you have started to come up to speed with HTML, CSS and JavaScript you will want to make sure you are making use of the best tools that are now available. I compiled a list of <a href="http://brennan.offwhite.net/blog/2007/04/02/web-development-tools-for-the-power-developer-revised/">Web Developer Tools for the Power Developer</a>. If you are not familiar with these tools yet you will discover the work you have been doing can be much easier. Since I created this list there have been updates to these tools and new browsers like Google Chrome and Internet Explorer 8 have started to implement useful tools in the browser which are similar to the extremely popular <a href="http://www.getfirebug.com/">Firebug extension to Firefox</a>.</p>
<p>I have built some tools to assist with web development. <a href="http://www.smallsharptools.com/Projects/Packer/">Packer for .NET</a> is one which I have started using on every web site I build lately. This utility can compact your JavaScript and CSS by stripping whitespace and comments which are not necessary in your production environment but are very useful in making your work maintainable. Recently I have implemented functionality making it easier to combine multiple files into one. I find that instead of one large file that is over 1000 lines long it is better to break that file into pieces which are used during development and then when it is moved to production, where the debug attribute in the Web.config is set to false, the files are combined, compacted and sent in the response. The Packer project also includes an MSBuild task to update your Web.config during deployment. I use this feature often to automate my deployments with a single click. You may find this utility will save you a great deal of time.</p>
<p>Going forward with jQuery and ASP.NET MVC is going to be a very different experience from the PostBack model. I will have greater control over the HTML which will allow me to define the semantic structure and style it the way I see fit with CSS. Adding behavior with JavaScript is going to be a lot easier. It won't all be rainbows and I am sure new problems will come up, but it does feel like a fresh start.</p>
<p>If you would like to read more on jQuery and Javascript, please subscribe to this blog and also browse my past blog entries. In the next few months I will continue writing about jQuery and ASP.NET MVC, so more content is coming. And be sure to post comments. I always like to know what others are doing.</p>
]]></content:encoded>
			<wfw:commentRss>http://brennan.offwhite.net/blog/2009/04/13/embracing-jquery-and-learning-javascript-all-over-again/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Packer for .NET 4.1 Released</title>
		<link>http://brennan.offwhite.net/blog/2009/03/01/packer-for-net-41-released/</link>
		<comments>http://brennan.offwhite.net/blog/2009/03/01/packer-for-net-41-released/#comments</comments>
		<pubDate>Mon, 02 Mar 2009 04:00:23 +0000</pubDate>
		<dc:creator>Brennan Stehling</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[msbuild]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://brennan.offwhite.net/blog/?p=550</guid>
		<description><![CDATA[Packer for .NET has been updated to version 4.1. A major new addition is a new MSBuild task called UpdateWebConfig which makes it easier to prepared your web.config file during deployment. There is also the new Combine mode.

Packer for .NET
Download

Note: Version 4.1.1 has been released with a fix to the targets file.
Breaking Change
With this release [...]]]></description>
			<content:encoded><![CDATA[<p>Packer for .NET has been updated to version 4.1. A major new addition is a new MSBuild task called UpdateWebConfig which makes it easier to prepared your web.config file during deployment. There is also the new Combine mode.</p>
<ul>
<li><a href="http://www.smallsharptools.com/Projects/Packer/">Packer for .NET</a></li>
<li><a href="http://www.smallsharptools.com/Downloads/SmallSharpTools.Packer/">Download</a></li>
</ul>
<p><b>Note: Version 4.1.1 has been released with a fix to the targets file.</b></p>
<h3>Breaking Change</h3>
<p>With this release the Utility class has been renamed FileProcessor. If you are coding against the assembly you will need to change Utility to FileProcessor.</p>
<h3>Combine Mode</h3>
<p>Sometimes you may want to simply combine multiple files together without running the JSMin or CSSMin modes. You may like to spread our CSS across multiple files so they are easier to organize and allow multiple developers to access concurrently. The Combine mode will allow you to combine these files into one either during the build and deployment process or even at runtime if you choose. In <a href="http://brennan.offwhite.net/blog/2009/02/08/packer-for-net-403-released/">the 4.0.3 release</a> I added features to make it possible to push out your files in this way.</p>
<h3>UpdateWebConfig</h3>
<p>I automate as much as I can on a project. One of the most critical changes during deployment is updating the configuration file. To do this I make use of web site projects along with the <a href="http://www.microsoft.com/DOWNLOADS/details.aspx?FamilyID=0aa30ae8-c73b-4bdd-bb1b-fe697256c459&#038;displaylang=en">web deployment project</a>. This process creates a pre-compiled web site which is ready for deployment and while it does have a feature to replace sections of the configuration file, it needs to be more targeted.</p>
<p><span id="more-550"></span></p>
<p>A setting that we all have to change is the debug mode which is true during development but should always be false in production. To change this setting with the web deployment projects you must replace the compilation element for that one attribute which means replacing the list of assemblies which are often updated without notice by Visual Studio during development. I find it is dangerous to blindly replace this whole section, so I have been using the XmlUpdate task included with the <a href="http://msbuildtasks.tigris.org/">MSBuild Community Tasks</a>. That task allows you to use an XPath value to target updates to attributes or any node an XPath can reference.</p>
<p>The problem with using XmlUpdate is that it adds a lot to your MSBuild script which is hard to read and maintain. The UpdateWebConfig task allows you to set the values that you would commonly change like the appSettings, debug mode, compilation errors mode, mail host and the configSource value on the connectionStrings element. With a very easy to read MSBuild script I can now set the right values so that when the files are copied to the staging server I can simply <a href="http://brennan.offwhite.net/blog/2007/05/31/running-msbuild-from-visual-studio/">click a button in Visual Studio</a> and within minutes (or seconds) the site will be built, configured and copied to the staging server, ready for testing. With the latest site that I am developing this happens in under 20 seconds.</p>
<p>Below is a sample of the new UpdateWebConfig task.</p>
<pre class="code">
<form><textarea name="code" class="xml">
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <Import Project="$(MSBuildExtensionsPath)\SmallSharpTools.Packer\MSBuild.Packer.Targets" />

  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Environment Condition=" '$(Environment)' == '' ">Production</Environment>

    <WebConfigPath>Website_deploy\Web.config</WebConfigPath>

    <!-- Development -->
    <AppSettings Condition=" '$(Environment)' == 'Development' ">
      Environment = Development;
    </AppSettings>

    <!-- Staging -->
    <AppSettings Condition=" '$(Environment)' == 'Staging' ">
      Environment = Staging;
      SSL.Enabled = false;
    </AppSettings>

    <!-- Production -->
    <AppSettings Condition=" '$(Environment)' == 'Production' ">
      Environment = Production;
      SSL.Enabled = true;
      SSL.Host = https://www.acme.com
    </AppSettings>

  </PropertyGroup>
  <ItemGroup>
  </ItemGroup>
  <Target Name="Build">

    <!-- Development -->
    <UpdateWebConfig Condition=" '$(Environment)' == 'Development' "
        WebConfigPath="$(WebConfigPath)"
        ConnectionStringConfigSource="Configurations\\connectionStrings-dev.config"
        AppSettings="$(AppSettings)"
        Debug="true"
        CustomErrorsMode="Off"
        MailHost="localhost"/>

    <!-- Staging -->
    <UpdateWebConfig Condition=" '$(Environment)' == 'Staging' "
        WebConfigPath="$(WebConfigPath)"
        ConnectionStringConfigSource="Configurations\\connectionStrings-staging.config"
        AppSettings="$(AppSettings)"
        Debug="false"
        CustomErrorsMode="Remote"
        MailHost="staging.acme.com"/>

    <!-- Production -->
    <UpdateWebConfig Condition=" '$(Environment)' == 'Production' "
        WebConfigPath="$(WebConfigPath)"
        ConnectionStringConfigSource="Configurations\\connectionStrings-production.config"
        AppSettings="$(AppSettings)"
        Debug="false"
        CustomErrorsMode="On"
        MailHost="mail.acme.com"/>

  </Target>
</Project>
</textarea></form>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://brennan.offwhite.net/blog/2009/03/01/packer-for-net-41-released/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Browser Upgrades, IE6 and ESPN</title>
		<link>http://brennan.offwhite.net/blog/2009/02/25/browser-upgrades-ie6-and-espn/</link>
		<comments>http://brennan.offwhite.net/blog/2009/02/25/browser-upgrades-ie6-and-espn/#comments</comments>
		<pubDate>Wed, 25 Feb 2009 14:58:19 +0000</pubDate>
		<dc:creator>Brennan Stehling</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[ie6]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://brennan.offwhite.net/blog/?p=549</guid>
		<description><![CDATA[Back in 2004 I wrote A Great Example of CSS and Javascript in Action which explained how to use CSS and JavaScript carefully due to the varying browser experiences at the time. The situation has changed quite a bit since then. We no longer have to support Netscape 4 or Internet Explorer 5. Now there [...]]]></description>
			<content:encoded><![CDATA[<p>Back in 2004 I wrote <a href="http://brennan.offwhite.net/blog/2004/10/15/a-great-example-of-css-and-javascript-in-action/">A Great Example of CSS and Javascript in Action</a> which explained how to use CSS and JavaScript carefully due to the varying browser experiences at the time. The situation has changed quite a bit since then. We no longer have to support Netscape 4 or Internet Explorer 5. Now there is a push spreading widely to end support for IE6. (Read <a href="http://brennan.offwhite.net/blog/2009/02/20/the-end-of-ie6/">The End of IE6</a>) And this time there is a significant amount of resistance. IE6 seems entrenched and there has been push back on not supporting this old browser.</p>
<p>Consider if I were to loan you my laptop that I bought in 2001. It is very slow and cannot run many of the applications that you use today and has a 10GB hard drive. Most iPods have more storage space. You would not want to use that laptop. You may refuse to use it because it is just not worth your time to deal with the headaches of finding old ways to do what takes so much less effort with a computer purchased in the last 3 years.</p>
<p><span id="more-549"></span></p>
<p>Back in 2004 ESPN implemented some new features on their web site that they wanted to get to their users. In order to do so they were going to have to require users to use a current browser. To do this they did a check in JavaScript to see if their browser supported certain functions and if they did not they would send them to the <a href="http://espn.go.com/browserupgrade.html">Browser Upgrade Page</a> which is still there. The browser check did not look for a certain version of a browser, but browser capabilities. Fortunately that was easy enough to do and they were successful in rolling out new features that their users appreciated. ESPN is one of the most innovative sites around.</p>
<p>Still there are a significant number of IE6 users roaming the public Internet. What can we do?</p>
<p>I think the attitude has to change. It is not acceptable that IE6 has not supported PNG images properly since it was released in 2001. Microsoft could have released an update to fully implement proper support, but they did not for several years. Now we have IE7 which fixed the PNG problem along with several other major bugs in IE6, but still problems remain. The expectation is that the browser should properly support modern HTML, CSS and JavaScript standards within a reasonable time frame. And in Internet terms a reasonable lag time to support new standards has been 2 to 3 years roughly. Lately with modern browsers, which completely excludes the Internet Explorer family of browsers, the lag time has been 6 months to a year. <a href="http://www.apple.com/safari/">Safari 4</a> is now out as a beta with support for HTML 5 and CSS 3 and the new JavaScript engine is 30 times faster than IE7.</p>
<p>In contrast IE7 barely supports CSS 2.1 and has significant shortcomings with CSS. And support for HTML 5 is not even on the horizon much less a faster JavaScript engine. Apparently the architecture for this browser is extremely costly to maintain and upgrade so much that even Microsoft cannot maintain a reasonable upgrade time line.</p>
<p>Browsers like Firefox, Safari and Chrome all have an upgrade feature that makes it easy to stay current and updates are published regularly for big and small changes which move the browser towards improved standards compliance as well as greater stability and performance. You do not have to wait years for these updates, instead they come out every few weeks. If a bug is found it is corrected as soon as a fix can be pushed out in the next update. Users of version 3.0.5 are quickly updated to version 3.0.6 through the automatic update program that transparently downloads the update for you and installs it for you the next time you start the browser. Critical bugs do not last long with such an update system in place. The same does not exist for IE7 beyond Windows updates which are not nearly as effective as the Firefox update system. Users are unwilling and sometimes afraid to run Windows updates. Perhaps some users have a pirated version of Windows and cannot run the updates. Sometimes an improperly configured anti-virus program will also prevent Windows updates from running properly. Whatever the reason, they would be better off with using a browser that has an update system that keeps them current.</p>
<p>After my last post a friend sent me a link to this site, <a href="http://www.stoplivinginthepast.com/">Stop Living in the Past</a>. It is yet another site that is pushing for the end of IE6.</p>
]]></content:encoded>
			<wfw:commentRss>http://brennan.offwhite.net/blog/2009/02/25/browser-upgrades-ie6-and-espn/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The End of IE6</title>
		<link>http://brennan.offwhite.net/blog/2009/02/20/the-end-of-ie6/</link>
		<comments>http://brennan.offwhite.net/blog/2009/02/20/the-end-of-ie6/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 19:18:59 +0000</pubDate>
		<dc:creator>Brennan Stehling</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[ie6]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://brennan.offwhite.net/blog/?p=548</guid>
		<description><![CDATA[
Internet Explorer 6 was released in August of 2001. Since then Microsoft delayed any new releases after achieving dominance in the browser market which effectively ended the browser wars of the late 90's. In a previous post I suggested the dominance of IE6 and lack of releases over several years was bad, but also good [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.pushuptheweb.com/" style="text-decoration: none;" target="_blank"><img src="http://brennan.offwhite.net/images/blog/pushup.png" alt="Pushup" style="float: right; margin: 5px; padding: 4px; border: 0;" /></a><br />
Internet Explorer 6 was <a href="http://en.wikipedia.org/wiki/Internet_Explorer_6#Release_history">released</a> in August of 2001. Since then Microsoft delayed any new releases after achieving dominance in the browser market which effectively ended the browser wars of the late 90's. In a <a href="http://brennan.offwhite.net/blog/2006/09/05/the-wait-for-ie7-good-or-bad/">previous post</a> I suggested the dominance of IE6 and lack of releases over several years was bad, but also good because it offered a "stable" base that we could build on. In the late 90's there were frequent releases of Netscape and Internet Explorer with amazing new features and it was hard to keep up. At least with no releases for the browser with 90% of the market share you could stick with what you had. But now it is time to move forward.</p>
<p>Starting with Google Mail everything changed. Suddenly you could build rich applications than run on web sites. And thanks to the rising popularity of <a href="http://www.adaptivepath.com/publications/essays/archives/000385.php">AJAX</a> many more sites jumped forward into what became known at <a href="http://en.wikipedia.org/wiki/Web_2.0">Web 2.0</a>. Now it is common for a site like Facebook to act more like an application than a collection of pages. You have a task bar at the bottom to show notifications and keep active chats going with friends even as you browse to different areas to look at photos and post comments on your friend's walls. In order to run as an application a web site requires more resources, and Internet Explorer 6 is just not capable of providing the experience that people want.</p>
<p><span id="more-548"></span></p>
<p>The Mozilla organization has made gradual strides in coming back as a viable competitor to Internet Explorer and Apple's Safari has had a different impact. The Firefox browser is popular, especially among more technically savvy users, because of the rich <a href="https://addons.mozilla.org/">add-on library</a>. It is easy to make the argument that without the <a href="https://addons.mozilla.org/en-US/firefox/addon/1843">Firebug</a> add-on the refined modern interfaces that are more common today would not be as common.</p>
<p>Safari has taken a different route. Instead of eating into Internet Explorer market share it has mostly taken away Firefox users. Safari is based on Apple's WebKit engine which is easily re-purposed for other uses like the mobile web interfaces on the iPhone and Google's phone. The WebKit engine is also what runs <a href="http://www.adobe.com/products/air/">Adobe AIR</a>, a rich internet application platform. Apple's impact on web technologies, due to the wide use of the WebKit engine, has helped increase the value of web standards and move the web forward as a platform.</p>
<p>Another major browser, which happens to be based on WebKit, is <a href="http://www.google.com/chrome">Google Chrome</a>. While this browser makes use of the WebKit engine, it is quite different than Safari. A major difference is the JavaScript runtime engine which is capable of much faster performance than conventional JavaScript runtime engines. The coming Firefox and Safari releases promise to outpace the initial release of Chrome, which brings us back to Internet Explorer. There is no projected release of a modern JavaScript engine for Internet Explorer that will provide the experience that user's want and web site developers really, really want to deliver.</p>
<p>A major effort is currently underway to get users off of Internet Explorer 6. <a href="http://en.wikipedia.org/wiki/Internet_Explorer_7#Release_history">Version 7</a> has been available since October of 2006 yet by some statistics up to 20% of Internet users are still using version 6. In Norway there is currently <a href="http://blog.wired.com/business/2009/02/norwegian-websi.html">a war on IE6</a> which is spreading well beyond Norway <a href="http://search.twitter.com/search?q=%23ie6">via Twitter</a> and other social networks like a group on Facebook called <a href="http://www.facebook.com/group.php?gid=52657958554">IE6 Warning Campaign</a>.</p>
<p>The largest group of users that are dragging their feet, even though IE7 has been out so long, is corporate users where applications were built for IE6. Since IE6 has so many nuances and bugs the applications built specifically for it years ago for it just do not work on Firefox or Chrome, much less IE7. To make matters worse, you cannot install IE7 alongside IE6 which would at least give these corporate users the option to use their internal applications (like time entry and accounting) with IE6 while they can use IE7 for the public Internet.</p>
<p>For over a year the <a href="http://iedeathmarch.org/">IE6 Death March</a> web site has highlighted products which are younger than IE6. The first iPod was released AFTER IE6. It is hard to believe that users are still using a pre-iPod browser. What kind of world is this? <img src='http://brennan.offwhite.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The IE6 Death March site also promotes the March 2009 deadline for IE6 where web site designers and developers will simply stop testing their work in IE6 from that point forward and put all of that effort instead into getting their clients and users to use modern browsers.</p>
<p>I built <a href="http://www.smallsharptools.com/downloads/JavaScript/ie6upgrade.html">my own warning mechanism</a> for IE6 users. Another warning mechanism called <a href="http://www.pushuptheweb.com/">Pushup</a> covers several older browsers, not just IE6, and provides a much nicer design than what I put together. I strongly suggest putting one of these warning mechanisms on your public sites starting in March to help users stay current.</p>
<p>And staying current could not be easier in the modern browsers. Firefox, Safari and Chrome all have a feature that helps users stay current by automatically checking for new versions and upgrading with little effort. I have seen that Firefox users are often upgraded to the very last minor release within weeks, not months or years like we have typically seen with browsers. Annoying problems, like incomplete support for PNG graphics in IE6, could be fixed within weeks if IE8 introduces an update system similar to Firefox, Safari and Chrome. Instead we have to comprise the user experience for 80% of the users because 20% are lingering behind with IE6.</p>
<p>The problem with legacy internet web applications is very real. When you have 3 months to build an internal web application and then your budget is gone you cannot simply go back and update it each time a new browser comes out, so corporations decided that IE6 was all they ever needed. And upgrading the browser is not just a matter of a 5 minute installation, it requires budgeting work to upgrade all of those internal applications. And those budgets can be prohibitive.</p>
<p>But it is possible to build web applications that are what I like to call "future proof." Last year I wrote <a href="http://brennan.offwhite.net/blog/2008/03/03/internet-explorer-8-and-future-proofing-your-website/">Internet Explorer 8 and Future Proofing your Website</a>. I explain how you can write standards compliant HTML and CSS that you can validate with W3C tools so that you are protected from unknowns problems that creep into your work. You may have some syntax errors in your HTML or CSS which are not causing trouble today but will cause strange behavior in a future version of your favorite browser.</p>
<p>You can also future proof your work by leveraging one of the popular JavaScript libraries available today. The DOM API which is a part of JavaScript is used to manipulate the web page, which gives us all of those great Web 2.0 features that we love. But the DOM API is pretty hard to use and it does not work consistently across all of the browsers. I have been using <a href="http://jquery.com/">jQuery</a> which does all of the page manipulation that the DOM API does, but it has a much more intuitive interface and the library is heavily tested across all of the major browsers, including IE6. And once IE8 comes out, and Firefox 4, and Chrome 2 we can try out our applications to see if anything is broken in these new browsers. If they are, we may just have to get the latest versions of our chosen JavaScript library which adapts to these new browsers for us and leaves us to go back to our normal daily routine without having to redo all of our work to get that application to work in the newest browsers.</p>
<p>Starting in March I will be joining the March. Every one of my personal web sites will be making use of either my IE6 warning mechanism or Pushup. I will try to get my clients on board with Pushup as well. Once these IE6 users are warned enough they may finally decide to upgrade. I am confident the majority of them will. And then once IE6 usage drops below 5% you will start to see sites with features you never thought were possible. I am sure the next Google Mail is just around the corner, and it will be possible because the web took a huge step forward.</p>
]]></content:encoded>
			<wfw:commentRss>http://brennan.offwhite.net/blog/2009/02/20/the-end-of-ie6/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Packer for .NET 4.0.3 Released</title>
		<link>http://brennan.offwhite.net/blog/2009/02/08/packer-for-net-403-released/</link>
		<comments>http://brennan.offwhite.net/blog/2009/02/08/packer-for-net-403-released/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 03:54:07 +0000</pubDate>
		<dc:creator>Brennan Stehling</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[msbuild]]></category>

		<guid isPermaLink="false">http://brennan.offwhite.net/blog/?p=547</guid>
		<description><![CDATA[Packer for .NET has been updated to provide an easy way to return the minified content directly for a web request. Until now the process of "minifying" content was done either on the command-line or with with MSBuild.

Packer for .NET
Download

The task of creating the compacted content can easily be forgotten during a deployment. And when [...]]]></description>
			<content:encoded><![CDATA[<p>Packer for .NET has been updated to provide an easy way to return the minified content directly for a web request. Until now the process of "minifying" content was done either on the command-line or with with MSBuild.</p>
<ul>
<li><a href="http://www.smallsharptools.com/Projects/Packer/">Packer for .NET</a></li>
<li><a href="http://www.smallsharptools.com/Downloads/SmallSharpTools.Packer/">Download</a></li>
</ul>
<p>The task of creating the compacted content can easily be forgotten during a deployment. And when the source control system locks the output files which are updated with the build script there can be trouble in both writing out the files as well as keeping the files current in source control. So instead of referencing the generate file it would be useful to reference the source files dynamically. Read on for an example.</p>
<p><span id="more-547"></span></p>
<p>First <code>SiteUtility.cs</code> defines a property that is a collection of the all of the scripts that a web page would reference. The <code>RegisterJavaScript</code> method will register script references with a <code>ScriptManager</code> control. Then <code>ScriptsHandler.ashx</code> uses the same list of scripts to dynamically generate the compacted content. Anytime the list of scripts is updated the change will take affect for both the <code>RegisterJavaScript</code> method as well as the handler.</p>
<p>Another feature of the <code>SiteUtility</code> class is the debug mode switching. If you are working in debug mode the scripts will be referenced directly. When the web site is deployed the debug mode can be disabled which will use the <code>ScriptHandler.ashx</code> to output the scripts as a single compacted reference.</p>
<p><b>App_Code/SiteUtility.cs</b></p>
<pre class="code">
<form><textarea name="code" class="c#">
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Caching;
using System.Web.UI;
using SmallSharpTools.Packer.Utilities;

/// <summary>
/// </summary>
public static class SiteUtility
{

    private static List<string> _scripts;

    public static List<string> Scripts
    {
        get
        {
            if (_scripts == null)
            {
                _scripts = new List<string>();
                _scripts.Add("~/core.js");
                _scripts.Add("~/script1.js");
                _scripts.Add("~/script2.js");
                _scripts.Add("~/script3.js");
            }
            return _scripts;
        }
    }

    public static void RegisterJavaScript(Page page)
    {
        ScriptManager scriptManager = ScriptManager.GetCurrent(page);

        if (HttpContext.Current.IsDebuggingEnabled)
        {
            // reference each script without shrinking
            foreach (string script in Scripts)
            {
                scriptManager.Scripts.Add(new ScriptReference(script));
            }
        }
        else
        {
            // reference the scripts handler which shrinks all scripts into one
            scriptManager.Scripts.Add(new ScriptReference("~/ScriptsHandler.ashx"));
        }
    }

    public static string GetCompactedJavaScript()
    {
        Cache cache = HttpRuntime.Cache;
        string cacheKey = "JavaScript";
        if (cache[cacheKey] != null)
        {
            return cache[cacheKey] as string;
        }

        List<string> scripts = new List<string>();
        foreach (string script in SiteUtility.Scripts)
        {
            scripts.Add(HttpContext.Current.Request.MapPath(script));
        }

        StringBuilder sb = new StringBuilder();
        sb.AppendLine("/*  Generated " + DateTime.Now.ToString() + "  */\n");
        sb.AppendLine(Utility.Run(PackMode.JSMin, scripts.ToArray(), true));

        string output = sb.ToString();

        // set to expire cache when any of the source files changes
        CacheDependency dep = new CacheDependency(scripts.ToArray());

        // hold for 30 minutes
        cache.Insert(cacheKey, output, dep, DateTime.Now.AddMinutes(30),
            Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);

        return output;
    }

}
</textarea></form>
</pre>
<p><b>ScriptsHandler.ashx</b></p>
<pre class="code">
<form><textarea name="code" class="c#">
<%@ WebHandler Language="C#" Class="ScriptsHandler" %>

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Caching;
using SmallSharpTools.Packer.Utilities;

public class ScriptsHandler : IHttpHandler {

    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/javascript";
        context.Response.Write(SiteUtility.GetCompactedJavaScript());
    }

    public bool IsReusable {
        get {
            return false;
        }
    }

}
</textarea></form>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://brennan.offwhite.net/blog/2009/02/08/packer-for-net-403-released/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
