<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US">
  <title>Intridea - Company Blog</title>
  <id>tag:www.intridea.com,2009:company</id>
  
  <link href="http://www.intridea.com/blog/company" rel="alternate" type="text/html" />
  <updated>2009-07-09T08:52:36-04:00</updated>
  <link rel="self" href="http://feeds.feedburner.com/intridea" type="application/atom+xml" /><entry xml:base="http://www.intridea.com">
    <author>
      <name>Doug Ramsay</name>
    </author>
    <id>tag:www.intridea.com,2009-07-08:194</id>
    <published>2009-07-08T18:25:00-04:00</published>
    <updated>2009-07-08T18:25:00-04:00</updated>
    <category term="built_for_speed" />
    <category term="performance. amazon" />
    <category term="cloudfront" />
    <category term="s3" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/-S19sBg7O_Q/amazon-cloudfront-preventing-stale-assets" rel="alternate" type="text/html" />
    <title>Built For Speed: Prevent Amazon CloudFront From Serving Stale Assets</title>
    <content type="html">&lt;p&gt;In the &lt;a href="http://intridea.com/2009/7/6/using-amazon-cloudfront-to-serve-assets"&gt;last Built For Speed post&lt;/a&gt;, I demonstrated how you can use the Amazon CloudFront Content Delivery Network (CDN) for images on your site. However, ideally we should be using CloudFront for &lt;em&gt;all&lt;/em&gt; static assets, not just images.&lt;/p&gt;


	&lt;p&gt;Before we jump into that, though, let&amp;#8217;s do a quick review of how CloudFront works. Like all CDNs, CloudFront consists of a number of edge servers all around the world, each of which has a connection back to a central asset server. When CloudFront receives a request for an asset, it calculates which edge server is geographically closest to the request location. For example, a user in England may request the asset &amp;#8216;dog.jpg&amp;#8217;. CloudFront will route that request to the London server, which will check if it has a cached version of &amp;#8216;dog.jpg&amp;#8217;. If it does, the edge server will return that cached version. If not, it will retrieve the image from the central asset, cache it locally and return it to the user. All subsequent requests in England for &amp;#8216;dog.jpg&amp;#8217; will get the cached version on the London edge server. This approach minimizes network latency.&lt;/p&gt;


	&lt;p&gt;There is one big gotcha with this approach: If the &amp;#8216;dog.jpg&amp;#8217; image changes from a poodle to a beagle, but keeps the same name, the edge server will keep serving the poodle image (assuming the expires headers are set far in the future as they should be). The edge server will not pick up the latest asset unless the name of the asset changes.&lt;/p&gt;


	&lt;p&gt;Okay, with that background out of the way, let&amp;#8217;s take a look at how we can get our &lt;span class="caps"&gt;CSS&lt;/span&gt; and JavaScripts served through CloudFront. The approach I&amp;#8217;ve taken is to create an initializer file that sets a &lt;span class="caps"&gt;REVISION&lt;/span&gt; constant. This could easily be created as part of a deployment process, copying the latest Git or Subversion revision into the initializer file, but for now I just created it manually. We&amp;#8217;ll append the &lt;span class="caps"&gt;REVISION&lt;/span&gt; constant to the names of your packaged &lt;span class="caps"&gt;CSS&lt;/span&gt; and JavaScripts, so that on each deploy, the files have a different name, thereby preventing CloudFront from serving stale assets.&lt;/p&gt;


	&lt;p&gt;I have also moved the S3 configuration parsing out of the Post model and into another initializer, which sets the S3_CONFIG hash constant. In addition, I added the bucket name to my amazon_s3.yml config file. (Remember, if you have any questions, you can always refer to the &lt;a href="http://github.com/dramsay/built_for_speed/tree/master"&gt;source code&lt;/a&gt;.)&lt;/p&gt;


&lt;pre name="code" class="ruby"&gt;
# /config/initializers/s3_config.rb
S3_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/amazon_s3.yml")[RAILS_ENV]
&lt;/pre&gt;

	&lt;p&gt;See below for the Rake task I wrote to copy the packaged files to S3. Note that this should be run after you run the &amp;#8216;rake assets:packager:build_all&amp;#8217; task from AssetPackager (see the &lt;a href="http://intridea.com/2009/6/26/using-the-assetpackager-plugin?blog=company"&gt;first Built For Speed post&lt;/a&gt;).&lt;/p&gt;


&lt;pre name="code" class="ruby"&gt;
require 'right_aws'

namespace :s3 do
  namespace :assets do
    desc "Upload static assets to S3" 
    task :upload =&amp;gt; :environment do
      s3 = RightAws::S3.new(
        S3_CONFIG['access_key_id'], 
        S3_CONFIG['secret_access_key']
      )
      bucket = s3.bucket(S3_CONFIG['bucket'], true, 'public-read')

      files = Dir.glob(File.join(RAILS_ROOT, "public/**/*_packaged.{css,js}"))

      files.each do |file|
        filekey = file.gsub(/.*public\//, "").gsub(/_packaged/, "_packaged_#{REVISION}")
        key = bucket.key(filekey)
        begin
          File.open(file) do |f|
            key.data = f
            key.put(nil, 'public-read', {'Expires' =&amp;gt; 1.year.from_now})
          end
        rescue RightAws::AwsError =&amp;gt; e
          puts "Couldn't save #{key}" 
          puts e.message
          puts e.backtrace.join("\n")
        end
      end
    end
  end
end
&lt;/pre&gt;

	&lt;p&gt;Again, ideally this should be part of the deployment process &amp;#8211; first, run the AssetPackager task to create the packaged asssets, then run the S3 upload task to store them on S3. Notice that I&amp;#8217;m appending the &lt;span class="caps"&gt;REVISION&lt;/span&gt; string to the end of file names for each of the packaged &lt;span class="caps"&gt;CSS&lt;/span&gt; and JavaScript files before uploading to S3. Also notice that I&amp;#8217;m setting the Expires header to one year from now.&lt;/p&gt;


	&lt;p&gt;Hmm, we may have a couple problems here. First, by default, Rails expects &lt;span class="caps"&gt;CSS&lt;/span&gt; and JavaScript files to be in their proper places in the /public directory at the root of the application. That&amp;#8217;s easily fixed by adding the following line to the bottom of /config/environments/production.rb:&lt;/p&gt;


&lt;pre name="code" class="ruby"&gt;
ActionController::Base.asset_host = Proc.new { CLOUDFRONT_DISTRIBUTION }
&lt;/pre&gt;

	&lt;p&gt;The second problem is that the helpers provided by the AssetPackager plugin (&amp;#8216;stylesheet_link_merged&amp;#8217; and &amp;#8216;javascript_include_merged&amp;#8217;) don&amp;#8217;t know that you&amp;#8217;ve added a revision number to the end of the filenames. Not to worry &amp;#8211; we just need to update a couple lines in /vendor/plugins/asset_packager/lib/synthesis/asset_package.rb. Update the &amp;#8216;current_file&amp;#8217; method to look like this:&lt;/p&gt;


&lt;pre name="code" class="ruby"&gt;
def current_file
  build unless package_exists?

  path = @target_dir.gsub(/^(.+)$/, '\1/')
  name = "#{path}#{@target}_packaged" 
  name += "_#{REVISION}" if defined? REVISION
end
&lt;/pre&gt;

	&lt;p&gt;Try making those updates, then running &amp;#8216;rake s3:assets:upload &lt;span class="caps"&gt;RAILS&lt;/span&gt;_ENV=production&amp;#8221; (remember we&amp;#8217;re running in production mode for all the Built For Speed examples). After restarting your application, inspect the source and you should see that your stylesheets and scripts are being served by CloudFront, with the revision number at the end of the file names.&lt;/p&gt;


	&lt;p&gt;Now let&amp;#8217;s return to our images. After the last post, we already have them delivered by CloudFront. The problem is, if you decide to update your image, Paperclip will give it the same style names as before (&amp;#8216;original&amp;#8217;, &amp;#8216;large&amp;#8217;, &amp;#8216;medium&amp;#8217;, &amp;#8216;thumb&amp;#8217;). Uh-oh. Because the files have the same names, the CloudFront edge servers won&amp;#8217;t update from the central asset server to use the latest image, and your users will continue to see the stale, old image.&lt;/p&gt;


	&lt;p&gt;Go ahead and give it a try by updating an image for an existing post. Whoops! The old image is still displayed.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s how we solve that problem. First of all, let&amp;#8217;s update the Post model to use the new S3_CONFIG constant. While we&amp;#8217;re at it, let&amp;#8217;s add a timestamp to our image path so that each time you update the image, it will have a different name.&lt;/p&gt;


&lt;pre name="code" class="ruby"&gt;
# in /app/models/post.rb
has_attached_file :image, 
                :styles =&amp;gt; {:large =&amp;gt; "500x500", :medium =&amp;gt; "250x250", :thumb =&amp;gt; "100x100"}, 
                :storage =&amp;gt; 's3', 
                :s3_credentials =&amp;gt; S3_CONFIG, 
                :bucket =&amp;gt; S3_CONFIG['bucket'], 
                :path =&amp;gt; ":class/:id/:style_:timestamp.:extension" 
&lt;/pre&gt; 

	&lt;p&gt;One small issue: For some reason the Paperclip plugin uses a string representation for its &amp;#8216;timestamp&amp;#8217; method, so you end up with values like &amp;#8220;2009-06-26 15:25:44 &lt;span class="caps"&gt;UTC&lt;/span&gt;&amp;#8221;. This isn&amp;#8217;t very practical for timestamping file names, so I&amp;#8217;ve changed it:&lt;/p&gt;


&lt;pre name="code" class="ruby"&gt;
# /vendor/plugins/paperclip/lib/paperclip/interpolations.rb
def timestamp attachment, style
  attachment.instance_read(:updated_at).to_i
end
&lt;/pre&gt;

	&lt;p&gt;With that change, now each time we store an attached image, it will have a timestamp affixed to the end of the filename. Thus, the CloudFront edge server will go back to the central asset server and retrieve the new image rather than serving up the old image. Don&amp;#8217;t worry &amp;#8211; for each subsequent request, you&amp;#8217;ll get the benefit of having the new image on the edge server.&lt;/p&gt;


	&lt;p&gt;Restart your application, and try updating an image again. This time around, you&amp;#8217;ll see the image is updated correctly.&lt;/p&gt;


	&lt;p&gt;That wraps it up for our CloudFront review.  Now go forth and speed up your sites!&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;I realized I promised in my last post to show you how to make YSlow recognize that you were now using a &lt;span class="caps"&gt;CDN&lt;/span&gt;. Here&amp;#8217;s what you do:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Go to &amp;#8220;about:config&amp;#8221; in Firefox&lt;/li&gt;
		&lt;li&gt;Right-click on the page, and select &amp;#8220;New&amp;#8221; &amp;gt; &amp;#8220;String&amp;#8221; &lt;/li&gt;
		&lt;li&gt;Enter &amp;#8220;extensions.yslow.cdnHostnames&amp;#8221; as the preference name&lt;/li&gt;
		&lt;li&gt;Enter &amp;#8220;cloudfront.net&amp;#8221; as your &lt;span class="caps"&gt;CDN&lt;/span&gt; host name&lt;/li&gt;
		&lt;li&gt;Restart Firefox and run YSlow on your application again &amp;#8211; you should now see that you get an &amp;#8220;A&amp;#8221; for using a &lt;span class="caps"&gt;CDN&lt;/span&gt;&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;RESOURCES&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://github.com/dramsay/built_for_speed/tree/master"&gt;Built For Speed source code&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/-S19sBg7O_Q" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/amazon-cloudfront-preventing-stale-assets</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Doug Ramsay</name>
    </author>
    <id>tag:www.intridea.com,2009-07-06:193</id>
    <published>2009-07-06T18:00:00-04:00</published>
    <updated>2009-07-06T18:00:00-04:00</updated>
    <category term="performance" />
    <category term="yslow" />
    <category term="built_for_speed" />
    <category term="amazon" />
    <category term="s3" />
    <category term="cloudfront" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/NHXxMUkJ5ts/using-amazon-cloudfront-to-serve-assets" rel="alternate" type="text/html" />
    <title>Built For Speed: Using Amazon CloudFront To Serve Assets</title>
    <content type="html">&lt;p&gt;This is the second in a series of posts on improving your site&amp;#8217;s performance with the help of the YSlow Firefox plugin. In the &lt;a href="http://intridea.com/posts/using-the-assetpackager-plugin"&gt;last Built for Speed post&lt;/a&gt;, we took a look at YSlow&amp;#8217;s most important factor in page speed &amp;#8211; the number of &lt;span class="caps"&gt;HTTP&lt;/span&gt; requests. We demonstrated using the AssetPackager plugin to help reduce both the number of &lt;span class="caps"&gt;HTTP&lt;/span&gt; requests and the size of your &lt;span class="caps"&gt;CSS&lt;/span&gt; and JavaScript files. The &lt;a href="http://github.com/dramsay/built_for_speed/tree/master"&gt;source for the Built for Speed application&lt;/a&gt; is available on Github.&lt;/p&gt;


	&lt;p&gt;This week, we&amp;#8217;ll learn how to use a Content Delivery Network (CDN) to help users see our static content faster. Granted, this may be overkill for a lot of sites, but I think it&amp;#8217;s worth the time to see how it&amp;#8217;s done. There are a lot of CDNs out there, but I&amp;#8217;ve decided to use &lt;a href="http://aws.amazon.com/cloudfront/"&gt;Amazon&amp;#8217;s CloudFront&lt;/a&gt; because it&amp;#8217;s relatively cheap and easy to set up (not to mention it integrates seamlessly with S3). Before you get much further, you&amp;#8217;ll want to set up an account with &lt;a href="http://aws.amazon.com/s3/"&gt;S3&lt;/a&gt; and &lt;a href="http://aws.amazon.com/cloudfront/"&gt;CloudFront&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;First, let&amp;#8217;s install the Paperclip plugin so we can upload an image to go with our post.&lt;/p&gt;


&lt;pre name="code"&gt;
  script/plugin install git://github.com/thoughtbot/paperclip.git
&lt;/pre&gt;

	&lt;p&gt;Next, we need to add the Paperclip fields to the Post model:&lt;/p&gt;


&lt;pre name="code"&gt;
  script/generate migration AddPaperclipColumnsToPost 
&lt;/pre&gt;

&lt;pre name="code" class="ruby"&gt;
  # in the newly-created migration
  def self.up
    add_column(:posts, :image_file_name, :string)
    add_column(:posts, :image_content_type, :string)
    add_column(:posts, :image_file_size, :integer)
    add_column(:posts, :image_updated_at, :datetime)
  end

  def self.down
    remove_column(:posts, :image_file_name)
    remove_column(:posts, :image_content_type)
    remove_column(:posts, :image_file_size)
    remove_column(:posts, :image_updated_at)
  end
&lt;/pre&gt;

	&lt;p&gt;We also need to make the Paperclip declaration in the Post model:&lt;/p&gt;


&lt;pre name="code" class="ruby"&gt;
  class Post &amp;lt; ActiveRecord::Base
    has_attached_file :image, :styles =&amp;gt; {:large =&amp;gt; "500x500", :medium =&amp;gt; "250x250", :thumb =&amp;gt; "100x100"}
  end
&lt;/pre&gt;

	&lt;p&gt;And finally we make the updates to the views. First change the new and edit views, adding the file_field for the attachment and making sure the form is set to accept multipart data (see the &lt;a href="http://github.com/dramsay/built_for_speed/tree/master"&gt;source on Github&lt;/a&gt; if you have questions). Then update your show view to display the image:&lt;/p&gt;


&lt;pre name="code" class="rhtml"&gt;
  &amp;lt;%= image_tag @post.image.url(:large) %&amp;gt;
&lt;/pre&gt; 

	&lt;p&gt;Now let&amp;#8217;s take a look at our application in Firefox. Remember, we&amp;#8217;re running it in production mode to see the benefits of the AssetPackager plugin among other things. Create a new post with the image attachment of your choice.&lt;/p&gt;


	&lt;p&gt;One gotcha &amp;#8211; if you are running your application using Passenger, you may see an error something like this when you try to create a Paperclip attachment:&lt;/p&gt;


&lt;pre name="code"&gt;
  Image /tmp/passenger.621/var/stream.818.0 is not recognized by the 'identify' command.
&lt;/pre&gt;

	&lt;p&gt;In order to avoid this, create a file in /config/initializers to tell Paperclip where to find ImageMagick. I installed ImageMagick using MacPorts, so my file looks like:&lt;/p&gt;


&lt;pre name="code" class="ruby"&gt;
  Paperclip.options[:command_path] = "/opt/local/bin" 
&lt;/pre&gt;

	&lt;p&gt;Okay, now that we have a new post with an image, browse to the post detail page, open up the YSlow interface, click &amp;#8220;Run Test&amp;#8221; and take a look at the second grade, &amp;#8220;Use a Content Delivery Network (CDN)&amp;#8221;.&lt;/p&gt;


&lt;div class="thumbnail"&gt;&lt;a href="http://skitch.com/dramsay/bssxs/posts-show"&gt;&lt;img src="http://img.skitch.com/20090706-tyck79park6nb4yg3gpw3q2ddq.preview.jpg" alt="Posts: show" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080"&gt;Uploaded with &lt;a href="http://plasq.com/"&gt;plasq&lt;/a&gt;&amp;#8217;s &lt;a href="http://skitch.com"&gt;Skitch&lt;/a&gt;!&lt;/span&gt;&lt;/div&gt;

	&lt;p&gt;Ugh, we got a &amp;#8220;D&amp;#8221;. Okay, let&amp;#8217;s see how we can implement Amazon CloudFront to make that grade an &amp;#8220;A&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;Let&amp;#8217;s start by telling Paperclip to use S3 for our image storage. Go ahead and create a configuration file called amazon_s3.yml. Obviously, you&amp;#8217;ll need to replace the values here with your own keys:&lt;/p&gt;


&lt;pre name="code"&gt;
  # config/amazon_s3.yml
  development:
    access_key_id: 123...
    secret_access_key: 123...
  test:
    access_key_id: abc...
    secret_access_key: abc...
  production:
    access_key_id: 456...
    secret_access_key: 456...
&lt;/pre&gt;

	&lt;p&gt;Paperclip depends on the &amp;#8216;right_aws&amp;#8217; gem for its S3 storage, so make sure you add that to your config.gem list in /config/environment.rb and install it with:&lt;/p&gt;


&lt;pre name="code"&gt;
  rake gems:install
&lt;/pre&gt;

	&lt;p&gt;Next, update the Post model so it will use the new S3 configuration:&lt;/p&gt;


&lt;pre name="code" class="ruby"&gt;
  class Post &amp;lt; ActiveRecord::Base
    has_attached_file :image, 
                    :styles =&amp;gt; {:large =&amp;gt; "500x500", :medium =&amp;gt; "250x250", :thumb =&amp;gt; "100x100"}, 
                    :storage =&amp;gt; 's3', 
                    :s3_credentials =&amp;gt; YAML.load_file("#{RAILS_ROOT}/config/amazon_s3.yml")[RAILS_ENV], 
                    :bucket =&amp;gt; "built-for-speed", 
                    :path =&amp;gt; ":class/:id/:style.:extension" 
  end
&lt;/pre&gt;

	&lt;p&gt;Now restart your application and create a new post with an image. When you get to the post detail page, check out the source and you should see that your image is being served from your S3 bucket. That&amp;#8217;s great, but what we really want to do is serve the image from the CloudFront &lt;span class="caps"&gt;CDN&lt;/span&gt;. The easiest way to do this is to install the &lt;a href="http://www.s3fox.net/"&gt;S3 Firefox Organizer plugin&lt;/a&gt;). Once you enter your credentials, you should see your newly-created &amp;#8216;built-for-speed&amp;#8217; bucket. Right-click on the bucket name and click &amp;#8220;Manage Distributions&amp;#8221;, then optionally add a comment and click &amp;#8220;Create Distribution&amp;#8221; (we&amp;#8217;ll skip the &lt;span class="caps"&gt;CNAME&lt;/span&gt; option for now).&lt;/p&gt;


&lt;div class="thumbnail"&gt;&lt;a href="http://skitch.com/dramsay/bsaqy/s3-firefox-organizer"&gt;&lt;img src="http://img.skitch.com/20090706-b9fwuqr7cs6q4xxt55g7k6puyt.preview.jpg" alt="S3 Firefox Organizer" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080"&gt;Uploaded with &lt;a href="http://plasq.com/"&gt;plasq&lt;/a&gt;&amp;#8217;s &lt;a href="http://skitch.com"&gt;Skitch&lt;/a&gt;!&lt;/span&gt;&lt;/div&gt;

	&lt;p&gt;This will generate a new resource &lt;span class="caps"&gt;URL&lt;/span&gt; for you to use in your application so you can take advantage of CloudFront. Now we have to go back and tell our application to use this resource &lt;span class="caps"&gt;URL&lt;/span&gt;:&lt;/p&gt;


&lt;pre name="code" class="ruby"&gt;
  # /config/initializers/cloudfront.rb
  # 
  # Note that your CloudFront resource URL will be different
  CLOUDFRONT_DISTRIBUTION = "http://d2qd39qqjqb9uw.cloudfront.net" 
&lt;/pre&gt;

&lt;pre name="code" class="ruby"&gt;
  # in /app/models/post.rb
  def cloudfront_url( variant = nil )
    image.url(variant).gsub( "http://s3.amazonaws.com/built-for-speed", CLOUDFRONT_DISTRIBUTION )
  end
&lt;/pre&gt;

&lt;pre name="code" class="rhtml"&gt;
  # in /app/views/posts/show.html.erb
  &amp;lt;%= image_tag @post.cloudfront_url(:large) %&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;Restart the application and go back to the post detail page. Inspect the source and you&amp;#8217;ll see that your image is now being served from CloudFront.&lt;/p&gt;


	&lt;p&gt;Okay, I think that&amp;#8217;s enough for today. In the next post, I&amp;#8217;ll show you how to avoid CloudFront serving stale assets and how to make YSlow recognize that you are now using a &lt;span class="caps"&gt;CDN&lt;/span&gt;. Please leave any questions or comments below.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;CREDITS&lt;/span&gt;/RESOURCES:&lt;/strong&gt;&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://sdruby.com/podcast/63"&gt;Nick Zadrozny&amp;#8217;s YSlow presentation from SD Ruby&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=2331"&gt;Managing Assets on Amazon CloudFront&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/NHXxMUkJ5ts" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/using-amazon-cloudfront-to-serve-assets</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Dave Potsiadlo</name>
    </author>
    <id>tag:www.intridea.com,2009-07-01:192</id>
    <published>2009-07-01T09:20:00-04:00</published>
    <updated>2009-07-01T09:20:00-04:00</updated>
    <category term="sketchnotes" />
    <category term="user experience" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/OSgUdpmhqfM/sketchnotes-uie-roadshow" rel="alternate" type="text/html" />
    <title>Sketchnotes from the UIE Roadshow</title>
    <content type="html">&lt;p&gt;I recently had the pleasure of attending the &lt;a href="http://www.uie.com/events/roadshow/"&gt;User Interface Engineering Roadshow&lt;/a&gt; in Washington, DC.  The day was chock-full of insight and wisdom from usability guru Jared Spool, founder of &lt;a href="http://www.uie.com/"&gt;UIE.com&lt;/a&gt;.  In taking notes during the workshop, I decided to take my first official shot at sketchnoting.  The results are as follows:&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;a style="border: none;" href="http://www.skipvision.com/blog/wp-content/uploads/2009/07/20090630-uie-sketchnotes.gif"&gt;&lt;img class="size-full wp-image-97" style="border: none; padding: 0;" title="Sketchnotes from the UIE Roadshow" src="http://www.skipvision.com/blog/wp-content/uploads/2009/07/20090630-uie-sketchnotes-500.gif" alt="Sketchnotes from the UIE Roadshow" width="500" height="1075" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Overall, I found this experience to be wholly satisfying.  Putting key ideas into sketches required an interesting use of my attention span: in addition to listening intently to the ideas being communicated, I was simultaneously forced to employ creative sketching solutions that would properly embody the most important parts of the talks.&lt;/p&gt;
&lt;p&gt;Upon returning home from the Roadshow, I was quite surprised to find these sketches spanning 5 full pages of my notebook.  Upon scanning the notes and adding a bit of chronological organization, I&amp;#8217;m left with a sort of visual map of the workshop (as I experienced it).  I hope these notes might be of interest to others who attended.&lt;/p&gt;
&lt;p&gt;As for adventures in sketchnoting?  I look forward to continued exploration when the proper circumstances arise in the future.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/OSgUdpmhqfM" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/sketchnotes-uie-roadshow</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Doug Ramsay</name>
    </author>
    <id>tag:www.intridea.com,2009-06-26:191</id>
    <published>2009-06-26T14:42:00-04:00</published>
    <updated>2009-06-26T14:42:00-04:00</updated>
    <category term="performance" />
    <category term="assetpackager" />
    <category term="yslow" />
    <category term="built_for_speed" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/3eClZCy_VVY/using-the-assetpackager-plugin" rel="alternate" type="text/html" />
    <title>Built For Speed: Using the AssetPackager Plugin</title>
    <content type="html">&lt;p&gt;Inspired by the recent launch of &lt;a href="http://code.google.com/speed"&gt;code.google.com/speed&lt;/a&gt;, I decided to sit down and see how I could apply their guidelines. This is the first in a series of posts on improving front-end performance for your Rails applications.&lt;/p&gt;


	&lt;p&gt;First of all, we need to create our sample application. Recently, I&amp;#8217;ve been using &lt;a href="http://jackdempsey.github.com/beet"&gt;Beet&lt;/a&gt;, a gem for generating Ruby projects, but you can create your local version however works for you.  Using Beet, the following command tells the Rails generator to use MySQL, remove unused files (public/index.html, etc.) and initialize a Git repository:&lt;/p&gt;


&lt;pre name="code"&gt;
  beet -g built_for_speed -r="rails/db/mysql, rails/clean_files, rails/git" 
&lt;/pre&gt;

	&lt;p&gt;Next, let&amp;#8217;s create a Post resource:&lt;/p&gt;


&lt;pre name="code"&gt;
  script/generate scaffold Post title:string body:text
&lt;/pre&gt;

	&lt;p&gt;Make sure your databases are created, and run the migrations. Note that for the purposes of this tutorial, I&amp;#8217;m running the application in production mode (to better see the speed benefits), using Passenger on my MacBook Pro. By the way, I highly recommend the &lt;a href="http://www.fngtps.com/passenger-preference-pane"&gt;Fingertips Passenger preference pane&lt;/a&gt; for managing your sites locally.&lt;/p&gt;


&lt;pre name="code"&gt;
  RAILS_ENV=production rake db:migrate
&lt;/pre&gt;

	&lt;p&gt;Now let&amp;#8217;s add the Blueprint &lt;span class="caps"&gt;CSS&lt;/span&gt; framework. Download the latest version from &lt;a href="http://blueprintcss.org"&gt;blueprintcss.org&lt;/a&gt; and unpack it somewhere. Blueprint provides you with compressed versions of the &lt;span class="caps"&gt;CSS&lt;/span&gt; files, but humor me and add the uncompressed versions. From the unpacked directory, copy all the &lt;span class="caps"&gt;CSS&lt;/span&gt; files from /blueprint/src/ into /public/stylesheets/blueprint/ in your application.&lt;/p&gt;


	&lt;p&gt;Before we start up the application, let&amp;#8217;s add the &lt;span class="caps"&gt;CSS&lt;/span&gt; files as well as the default JavaScript files to the head of our posts layout (/app/views/layout/posts.html.erb). The head of your layout file should look something like this (note that I added my own base.css file):&lt;/p&gt;


&lt;pre class="rhtml" name="code"&gt;
  &amp;lt;head&amp;gt;
    ...
    &amp;lt;%= stylesheet_link_tag 'blueprint/reset', :media =&amp;gt; 'projection, screen' %&amp;gt;
    &amp;lt;%= stylesheet_link_tag 'blueprint/typography', :media =&amp;gt; 'projection, screen' %&amp;gt;
    &amp;lt;%= stylesheet_link_tag 'blueprint/forms', :media =&amp;gt; 'projection, screen' %&amp;gt;
    &amp;lt;%= stylesheet_link_tag 'blueprint/grid', :media =&amp;gt; 'projection, screen' %&amp;gt;
    &amp;lt;%= stylesheet_link_tag 'blueprint/print', :media =&amp;gt; 'print' %&amp;gt;
    &amp;lt;!--[if lt IE 8]&amp;gt;
        &amp;lt;%= stylesheet_link_tag 'blueprint/ie', :media =&amp;gt; "screen, projection" %&amp;gt;
    &amp;lt;![endif]--&amp;gt;
    &amp;lt;%= stylesheet_link_tag 'base', :media =&amp;gt; 'projection, screen' %&amp;gt;
    &amp;lt;%= javascript_include_tag :defaults %&amp;gt;
  &amp;lt;/head&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;Okay, now let&amp;#8217;s fire up the application. I&amp;#8217;ll be using Firefox so we can profile the application using &lt;a href="http://developer.yahoo.com/yslow/"&gt;YSlow&lt;/a&gt;. Go ahead and create your first post. Once you&amp;#8217;re looking at the &amp;#8216;show&amp;#8217; page, let&amp;#8217;s open up Firebug and click on the &amp;#8220;YSlow&amp;#8221; tab. On the YSlow screen, click the &amp;#8220;Run Test&amp;#8221; button to get your page grade.&lt;/p&gt;


&lt;div class="thumbnail"&gt;&lt;a href="http://skitch.com/dramsay/biwa7/posts-show"&gt;&lt;img src="http://img.skitch.com/20090626-tmxf8kxp2m5a2nxbxxhwqeutu7.preview.jpg" alt="Posts: show" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080"&gt;Uploaded with &lt;a href="http://plasq.com/"&gt;plasq&lt;/a&gt;&amp;#8217;s &lt;a href="http://skitch.com"&gt;Skitch&lt;/a&gt;!&lt;/span&gt;&lt;/div&gt;

	&lt;p&gt;Bummer, we got an overall D &amp;#8211; not so good. Let&amp;#8217;s take a look at what&amp;#8217;s going on. YSlow grades are listed in order of importance, so let&amp;#8217;s check out the first section: &amp;#8220;Make fewer &lt;span class="caps"&gt;HTTP&lt;/span&gt; requests&amp;#8221;. Looks like we got a C in that area. What can we do to improve our grade? YSlow gives us some tips: &amp;#8220;combine multiple scripts into one script, combine multiple &lt;span class="caps"&gt;CSS&lt;/span&gt; files into one style sheet&amp;#8221;. Before we get back to the application, take a look at the &amp;#8220;Components&amp;#8221; tab in the YSlow dialog.&lt;/p&gt;


&lt;div class="thumbnail"&gt;&lt;a href="http://skitch.com/dramsay/biw5p/posts-show"&gt;&lt;img src="http://img.skitch.com/20090626-kq6mqmw9g9g2kkxeh8j5u28924.preview.jpg" alt="Posts: show" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080"&gt;Uploaded with &lt;a href="http://plasq.com/"&gt;plasq&lt;/a&gt;&amp;#8217;s &lt;a href="http://skitch.com"&gt;Skitch&lt;/a&gt;!&lt;/span&gt;&lt;/div&gt;

	&lt;p&gt;Hmm, five JavaScript files for a total of 234.3K and six &lt;span class="caps"&gt;CSS&lt;/span&gt; files for a total of 18K. We definitely need to work on that.&lt;/p&gt;


	&lt;p&gt;In order to compress JavaScript and &lt;span class="caps"&gt;CSS&lt;/span&gt; files in my applications, I use Scott Becker&amp;#8217;s &lt;a href="http://github.com/sbecker/asset_packager/tree/master"&gt;AssetPackager plugin&lt;/a&gt;. Go ahead and install it:&lt;/p&gt;


&lt;pre name="code"&gt;
  script/plugin install git://github.com/sbecker/asset_packager.git
&lt;/pre&gt;

	&lt;p&gt;The first step after installation is to create the configuration file for AssetPackager:&lt;/p&gt;


&lt;pre name="code"&gt;
  $ rake asset:packager:create_yml
&lt;/pre&gt;

	&lt;p&gt;You should see a message to reorder the files under &amp;#8216;base&amp;#8217;, so let&amp;#8217;s go ahead and do that. Open up the newly-created /config/asset_packages.yml file. You&amp;#8217;ll notice that there are two top-level entries &amp;#8211; one for &amp;#8216;javascripts&amp;#8217; and one for &amp;#8216;stylesheets&amp;#8217;. AssetPackager should have correctly generated the required files for the &amp;#8216;javascripts&amp;#8217; section, but we&amp;#8217;ll need to add the Blueprint files. Your completed asset_packages.yml file should look something like this (again, I added a base.css file):&lt;/p&gt;


&lt;pre class="yaml" name="code"&gt;
    --- 
    javascripts: 
    - base: 
      - prototype
      - effects
      - dragdrop
      - controls
      - application
    stylesheets: 
    - base:
      - blueprint/reset
      - blueprint/typography
      - blueprint/forms
      - blueprint/grid 
      - base
    - print:
      - blueprint/print
    - ie:
      - blueprint/ie
&lt;/pre&gt;

	&lt;p&gt;Now that the config file is set up, you can go ahead and generate the combined, minified JavaScript and &lt;span class="caps"&gt;CSS&lt;/span&gt; files:&lt;/p&gt;


&lt;pre name="code"&gt;
  rake asset:packager:build_all
&lt;/pre&gt;

	&lt;p&gt;This command will output a &amp;#8220;[name]_packaged&amp;#8221; file for each entry under both &amp;#8216;javascripts&amp;#8217; and &amp;#8216;stylesheets&amp;#8217;. Now we have to tell our application to use those compressed files. Go back to your posts.html.erb layout and change the head to look like this:&lt;/p&gt;


&lt;pre class="rhtml" name="code"&gt;
  &amp;lt;head&amp;gt;
    ...
    &amp;lt;%= stylesheet_link_merged :base, :media =&amp;gt; "screen, projection" %&amp;gt;
    &amp;lt;%= stylesheet_link_merged :print, :media =&amp;gt; "print" %&amp;gt;
    &amp;lt;!--[if lt IE 8]&amp;gt;
    &amp;lt;%= stylesheet_link_merged :ie, :media =&amp;gt; "screen, projection" %&amp;gt;
    &amp;lt;![endif]--&amp;gt;
    &amp;lt;%= javascript_include_merged :defaults %&amp;gt;
  &amp;lt;/head&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;Okay, now it&amp;#8217;s time to see the fruits of our labors. Restart the application in the Passenger preference pane, and reload the post page in Firefox. Now let&amp;#8217;s run YSlow again. This time, you should see output like this:&lt;/p&gt;


&lt;div class="thumbnail"&gt;&lt;a href="http://skitch.com/dramsay/biw5w/posts-show"&gt;&lt;img src="http://img.skitch.com/20090626-n1uc7n7u51srj4m61rr48gbeen.preview.jpg" alt="Posts: show" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080"&gt;Uploaded with &lt;a href="http://plasq.com/"&gt;plasq&lt;/a&gt;&amp;#8217;s &lt;a href="http://skitch.com"&gt;Skitch&lt;/a&gt;!&lt;/span&gt;&lt;/div&gt;

	&lt;p&gt;Alright! We&amp;#8217;ve improved our grade up to an overall B, with an A for &amp;#8220;Make fewer &lt;span class="caps"&gt;HTTP&lt;/span&gt; requests&amp;#8221;. Let&amp;#8217;s take a look at the &amp;#8216;Components&amp;#8217; tab.&lt;/p&gt;


&lt;div class="thumbnail"&gt;&lt;a href="http://skitch.com/dramsay/biw5d/posts-show"&gt;&lt;img src="http://img.skitch.com/20090626-bwa4a17p4mtsxkkc8t1i58us5d.preview.jpg" alt="Posts: show" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080"&gt;Uploaded with &lt;a href="http://plasq.com/"&gt;plasq&lt;/a&gt;&amp;#8217;s &lt;a href="http://skitch.com"&gt;Skitch&lt;/a&gt;!&lt;/span&gt;&lt;/div&gt;

	&lt;p&gt;Thanks to AssetPackager, we&amp;#8217;re down to one JavaScript file for a total of 171.7K and two &lt;span class="caps"&gt;CSS&lt;/span&gt; files for a total of 12.6K. Now there&amp;#8217;s eight fewer components, and we&amp;#8217;re saving 68K of bandwidth on each request. Nice work!&lt;/p&gt;


	&lt;p&gt;The source code for this sample application can be found at: &lt;a href="http://github.com/dramsay/built_for_speed"&gt;github.com/dramsay/built_for_speed&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Check back for more performance tips in the future.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/3eClZCy_VVY" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/using-the-assetpackager-plugin</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Michael Bleigh</name>
    </author>
    <id>tag:www.intridea.com,2009-06-19:190</id>
    <published>2009-06-19T21:11:00-04:00</published>
    <updated>2009-06-19T21:11:00-04:00</updated>
    <category term="jquery" />
    <category term="quick tip" />
    <category term="array" />
    <category term="convenience" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/m-KID82SXFI/quick-tip-railsy-array-checks-in-jquery" rel="alternate" type="text/html" />
    <title>Quick Tip: Railsy Array Checks in jQuery</title>
    <content type="html">&lt;p&gt;I love the &lt;code&gt;any?&lt;/code&gt; and &lt;code&gt;empty?&lt;/code&gt; convenience methods that Rails and Ruby provide, they make conditional statements much easier to read. I also really dislike the default method of checking this behavior in jQuery:&lt;/p&gt;


&lt;pre name='code' class='js'&gt;if ($('some.element').length &amp;gt; 0) {
  // ...do something
}&lt;/pre&gt;

	&lt;p&gt;Well, luckily jQuery is ridiculously easy to extend, so why not just mix that functionality in with a couple of quick shot plugin methods? Just add this javascript sometime after you include jQuery:&lt;/p&gt;


&lt;pre name='code' class='js'&gt;jQuery.fn.any = function() {
  return (this.length &amp;gt; 0);
}

jQuery.fn.none = function() {
  return (this.length == 0);
}&lt;/pre&gt;

	&lt;p&gt;That&amp;#8217;s all you have to do! Now we can make the same call as before, but it looks a little cleaner:&lt;/p&gt;


&lt;pre name='code' class='js'&gt;if ($('some.element').any()) {
  // do something more readably...
}&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;:&lt;/strong&gt; Apologies, I added in the &lt;code&gt;empty&lt;/code&gt; bit as a last-second update to the post and forgot to check and realize that &lt;code&gt;empty()&lt;/code&gt; is part of jQuery core. Updated the name to &lt;code&gt;none&lt;/code&gt; instead.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/m-KID82SXFI" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/quick-tip-railsy-array-checks-in-jquery</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Adam Bair</name>
    </author>
    <id>tag:www.intridea.com,2009-06-12:189</id>
    <published>2009-06-12T13:01:00-04:00</published>
    <updated>2009-06-12T13:01:00-04:00</updated>
    <category term="unconference" />
    <category term="hack" />
    <category term="hacking" />
    <category term="hackon" />
    <category term="craftsman" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/vZI5tBMAfeg/hackon" rel="alternate" type="text/html" />
    <title>Intridea's Hackon in Portland, Maine</title>
    <content type="html">&lt;p&gt;I’m pleased to announce &lt;a href="http://www.intridea.com/hackon"&gt;Intridea’s Hackon&lt;/a&gt;, a 3-day co-working and unconference event we’ve organized at the Portland Harbor Hotel in Portland, Maine June 18-20th.&lt;/p&gt;


	&lt;p&gt;Thursday and Friday (17/18th) will be for informal hacking, coworking, and discussion and as we attempt to backfill interesting talks for Saturday (20th).&lt;/p&gt;


	&lt;p&gt;The &lt;a href="http://www.intridea.com/hackon"&gt;Hackon&lt;/a&gt; is intended to bring local software craftsman together to work on projects, exchange ideas, hack on open source, or just get some work done. There will be wifi, projection, food, and valet parking at the hotel.&lt;/p&gt;


	&lt;p&gt;And because we love developers and the community so much, we are hosting this event for &lt;span class="caps"&gt;FREE&lt;/span&gt;! Yes. Free. If you want to attend we only ask that you &lt;span class="caps"&gt;RSVP&lt;/span&gt; ahead of time so we can ensure that enough food, space, and power available.&lt;/p&gt;


	&lt;p&gt;Thank you to &lt;a href="http://meruby.org"&gt;&lt;span class="caps"&gt;MERUG&lt;/span&gt;&lt;/a&gt;, &lt;a href="http://nhruby.org"&gt;&lt;span class="caps"&gt;NHRUG&lt;/span&gt;&lt;/a&gt;, and &lt;a href="http://www.progmatica.com"&gt;#Progmatica&lt;/a&gt; for their support and their assistance in spreading the word!&lt;/p&gt;


	&lt;p&gt;Please head over to &lt;a href="http://www.intridea.com/hackon"&gt;intridea.com/hackon&lt;/a&gt; for details, rsvp, and talk submission.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.intridea.com/hackon"&gt;&lt;img src="http://img.skitch.com/20090612-fqcjw5uxj3n7tmqg9jr6q5e4e8.gif" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/vZI5tBMAfeg" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/hackon</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Brendan Lim</name>
    </author>
    <id>tag:www.intridea.com,2009-06-10:188</id>
    <published>2009-06-10T10:12:00-04:00</published>
    <updated>2009-06-10T10:12:00-04:00</updated>
    <category term="presently" />
    <category term="collaboration" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/Sk96OY5mrYE/presently-mentioned-as-best-bet-collaboration-tool-by-inc-magazine" rel="alternate" type="text/html" />
    <title>Present.ly Mentioned as a Best-Bet Collaboration Tool by Inc. Magazine</title>
    <content type="html">&lt;center&gt;&lt;img src='http://img197.imageshack.us/img197/1158/incmagazinelogo.gif'/&gt;&lt;/center&gt;
&lt;br/&gt;
In the June 2009 issue of &lt;a href='http://www.inc.com' target='_new'&gt;Inc. Magazine&lt;/a&gt;, &lt;a href="http://presentlyapp.com" target='_new'&gt;Present.ly&lt;/a&gt; was mentioned as one of the best-bet collaboration tools for mobile users.   It's becoming more apparent that companies need online collaboration tools that help alleviate the hassle of back-and-forth e-mail conversations and allow users to share information and documents. The article states that 22 percent of companies use real-time collaboration software and around 24 percent use document-sharing software, which &lt;a href="http://presentlyapp.com" target='_new'&gt;Present.ly&lt;/a&gt; supports out of the box.  It goes into detail on how to choose the right collaboration software for your company and provides real-life examples from different companies.
&lt;br/&gt;
&lt;br/&gt;
We are more than honored to be mentioned in a magazine that we all frequently read.  If you get a chance, pick up the June 2009 issue of &lt;a href='http://www.inc.com' target='_new'&gt;Inc. Magazine&lt;/a&gt;.
&lt;br/&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/Sk96OY5mrYE" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/presently-mentioned-as-best-bet-collaboration-tool-by-inc-magazine</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Dave Potsiadlo</name>
    </author>
    <id>tag:www.intridea.com,2009-06-08:179</id>
    <published>2009-06-08T12:29:00-04:00</published>
    <updated>2009-06-08T12:29:00-04:00</updated>
    <category term="design" />
    <category term="tutorials" />
    <category term="data visualization" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/KyzARZZpGt4/data-visualization-sampras-federer-title-race" rel="alternate" type="text/html" />
    <title>Visualizing Data: the Sampras &amp; Federer Title Race</title>
    <content type="html">&lt;p&gt;With Roger Federer&amp;#8217;s recent win of the 2009 French Open, he is now tied with Pete Sampras for holding the most Grand Slam titles &amp;#8212; fourteen.  Although the two athletes have arrived at the same destination, how do their respective journeys compare with one another?  With this question fueling my curiosity, I set out to create a rich visualization of the data to add some depth to this story.&lt;/p&gt;
&lt;p&gt;The final product is available as follows.  For additional notes about the techniques used to create these graphs, keep on reading.&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;a style="border: none;" href="http://www.skipvision.com/images/blog/sampras-federer/Sampras-Federer-Comparison-Full-Size.png" target="_blank"&gt;&lt;img class="aligncenter" src="http://www.skipvision.com/images/blog/sampras-federer/Sampras-Federer-Comparison-520.png" alt="Graph of Sampras vs. Federer race for Grand Slam title record" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here are some tips &amp;amp; techniques I employed to put this together.&lt;/p&gt;
&lt;h3&gt;Have Your Data Ready&lt;/h3&gt;
&lt;p&gt;Before diving into Illustrator (or whatever your tool of choice may be), spend the necessary time finding all of the data you will need for your graph.  Go the extra mile to arrange and label everything properly &amp;#8212; you may return to the data at a much later time and will be glad you did yourself the favor.  Aside from reaping the benefits of good organization, this step is additionally helpful in keeping the grunt work of data-fetching separate from the creative requirements of the task.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;img class="aligncenter" src="http://www.skipvision.com/images/blog/sampras-federer/google-docs.png" alt="How I used Google Docs to organize the data" /&gt;&lt;/p&gt;
&lt;h3&gt;Start with the Simplest Graphs Possible&lt;/h3&gt;
&lt;p&gt;An elegant, attractive graph is seldom created from scratch.  There are usually a number of tried &amp;amp; tested variations that must be wrestled with before arriving at the final product.  With this in mind, a good first step is creating some bare-bones, stripped down graphs to get bird&amp;#8217;s eye view of the data.  This phase is all about finding the approach that will best server your original vision.  Sketches work great in this stage.&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img class="aligncenter" src="http://www.skipvision.com/images/blog/sampras-federer/simple-graph.png" alt="Simple graphs to get things started" /&gt;&lt;/p&gt;
&lt;p&gt;What is the story you want to tell with your data?  This is an important question to keep in mind, as different visualization approaches will yield different results.  Play around with things.  See what looks good as well as which data comparisons are intuitive and interesting.  Seek feedback from friends or colleagues who might offer a valuable opinion.&lt;/p&gt;
&lt;h3&gt;Using the Grid&lt;/h3&gt;
&lt;p&gt;Before long, it will be time to create your final, finished product.  At this stage, the very most important thing you can do to keep things looking straight and orderly is use Illustrator&amp;#8217;s grid feature.  You&amp;#8217;ll want to make grids visible (CTRL/CMD + &amp;#8220;), as well as enable &amp;#8220;Snap to Grid&amp;#8221; (CTRL/CMD + SHIFT + &amp;#8220;).  Additionally, you may want to go into Illustrator&amp;#8217;s preferences to customize the grid spacing and subdivision width (which you can modify at any point).&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;img class="aligncenter" src="http://www.skipvision.com/images/blog/sampras-federer/grid-examples.png" alt="Using the grids to make things easier" /&gt;&lt;/p&gt;
&lt;p&gt;Another useful tip to keep in mind when using grids extensively is enabling Overprint Preview (CTRL/CMD + ALT + SHIFT + Y).  This will have the gridlines appear on top of all objects &amp;amp; paths, allowing you to eliminate any guessing that might otherwise be required in keeping things properly arranged.&lt;/p&gt;

&lt;h3&gt;Using Layers Wisely&lt;/h3&gt;
&lt;p&gt;Keeping your objects arranged in layers is a huge time-saver when dealing with moderately complex projects in Illustrator.  This was especially true in my case of creating four separate graphs, each of which contained separate groups of objects.  For example: if I wanted to modify the color of the Roger Federer graph plots, I&amp;#8217;d only need to target the layer &amp;#8220;Federer&amp;#8221; and all plots (on each graph) would become active.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;img class="aligncenter" src="http://www.skipvision.com/images/blog/sampras-federer/layer-screenshot.png" alt="Using layers to make things easier" /&gt;&lt;/p&gt;
&lt;p&gt;Layers can also be locked, combined, or temporarily hidden to make document management easier.&lt;/p&gt;
&lt;h3&gt;Go Forth and Visualize&lt;/h3&gt;
&lt;p&gt;And that&amp;#8217;s it!  Combined with a simple bit of color and typography, you can transform any crude visualization into an attractive graph.  Keep in mind that data in itself can be rather inert; though when arranged in a conscientious manner it can tell an interesting story.  Hopefully the techniques above can be of use in recreating your own graphs of a similar nature.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;a style="border: none;" href="http://www.skipvision.com/images/blog/sampras-federer/Sampras-Federer-Comparison-Full-Size.png" target="_blank"&gt;&lt;img class="aligncenter" src="http://www.skipvision.com/images/blog/sampras-federer/Sampras-Federer-Comparison-520.png" alt="Graph of Sampras vs. Federer race for Grand Slam title record" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/KyzARZZpGt4" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/data-visualization-sampras-federer-title-race</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Maggie Lubberts</name>
    </author>
    <id>tag:www.intridea.com,2009-06-05:176</id>
    <published>2009-06-05T10:55:00-04:00</published>
    <updated>2009-06-05T10:55:00-04:00</updated>
    <link href="http://feedproxy.google.com/~r/intridea/~3/5PQvFLRcjl0/alwayson-and-kpmg-global-250-competition" rel="alternate" type="text/html" />
    <title>AlwaysOn and KPMG Global 250 Competition</title>
    <content type="html">&lt;p style="align:center;"&gt;&lt;a href="http://alwayson.goingon.com/permalink/post/32074"&gt;&lt;img src="http://alwayson.goingon.com/sites/default/files/images/thumbnail_AO%5B1%5DGlobal250.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;We are very pleased to announce that Present.ly has been nominated for the seventh annual &lt;a href="http://alwayson.goingon.com/permalink/post/32074"&gt;AlwaysOn and &lt;span class="caps"&gt;KPMG&lt;/span&gt; Global 250 Competition!&lt;/a&gt; This truly is an honor as the AO Global 250 Competition nominates only the best and brightest emerging companies in the global marketplace in several categories. Our selection for the competition means that AlwaysOn and &lt;span class="caps"&gt;KPMG&lt;/span&gt; think that we are &amp;#8220;demonstrating significant market traction and pursuing game-changing technology.&amp;#8221; The winners are announced in July, and our fingers are crossed, but simply being nominated is an honor. Thanks AlwaysOn and &lt;span class="caps"&gt;KPMG&lt;/span&gt;!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/5PQvFLRcjl0" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/alwayson-and-kpmg-global-250-competition</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Maggie Lubberts</name>
    </author>
    <id>tag:www.intridea.com,2009-06-05:175</id>
    <published>2009-06-05T10:53:00-04:00</published>
    <updated>2009-06-05T10:53:00-04:00</updated>
    <link href="http://feedproxy.google.com/~r/intridea/~3/NVBGXi_OXXA/nvtc-hot-ticket-awards-nomination" rel="alternate" type="text/html" />
    <title>NVTC Hot Ticket Awards Nomination</title>
    <content type="html">&lt;p style="align:center;"&gt;&lt;a href="http://www.nvtc.org/events/geteventinfo.php?event=HOTTICKET7"&gt;&lt;img src="http://www.nvtc.org/images/header_logo.gif" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;We are honored to announce that we have been nominated for the &lt;a href="http://www.nvtc.org/events/geteventinfo.php?event=HOTTICKET7"&gt;Northern Virginia Technology Council Hot Ticket Awards!&lt;/a&gt; These awards recognize the hottest companies in a number of categories, and this year we are competing in the Hottest Bootstrap category. The announcement of winners will be held on June 24th, and all of us are truly appreciative of this nomination.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/NVBGXi_OXXA" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/nvtc-hot-ticket-awards-nomination</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Michael Bleigh</name>
    </author>
    <id>tag:www.intridea.com,2009-05-19:174</id>
    <published>2009-05-19T15:28:00-04:00</published>
    <updated>2009-05-19T15:28:00-04:00</updated>
    <category term="presently" />
    <category term="webware100" />
    <category term="announcements" />
    <category term="awards" />
    <category term="winner" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/m59p8dRyz3E/presently-wins-webware-100-editors-choice" rel="alternate" type="text/html" />
    <title>Present.ly Wins WebWare 100 Editors' Choice Award!</title>
    <content type="html">&lt;div style='float: right; margin: 0 0 10px 10px;'&gt;&lt;img src="http://www.cnet.com/html/ww/100/2009/images/winner.jpg" alt="" /&gt;&lt;/div&gt;

	&lt;p&gt;We are extremely excited to announce that Present.ly has been selected as a &lt;a href="http://news.cnet.com/8301-13546_109-10240181-29.html"&gt;CNet WebWare 100 Winner&lt;/a&gt; in the &lt;strong&gt;Editors&amp;#8217; Choice&lt;/strong&gt; category. The WebWare 100 is a list of the top 100 web applications of the year, and to be included as an editor&amp;#8217;s choice is a great honor. Thanks to everyone who supported us in the voting and to all of our users for helping us get to this prestigious accolade.&lt;/p&gt;


	&lt;p&gt;This award shows the recognition that Present.ly is gaining as a tool for enterprise collaboration and a new way to collaborate with co-workers. This is going to be a great year for Present.ly and we have lots of big things planned, so stay tuned to this blog for some new announcements in the coming weeks.&lt;/p&gt;


	&lt;p&gt;As we celebrate our success, we would love to hear feedback from those who use our product to enhance their business communications. If you have suggestions or comments, feel free to send an e-mail to &lt;a href="mailto:info@presentlyapp.com"&gt;info@presentlyapp.com&lt;/a&gt; or just leave a comment on the blog!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/m59p8dRyz3E" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/presently-wins-webware-100-editors-choice</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Michael Bleigh</name>
    </author>
    <id>tag:www.intridea.com,2009-05-15:173</id>
    <published>2009-05-15T10:03:00-04:00</published>
    <updated>2009-05-15T10:03:00-04:00</updated>
    <category term="rspec" />
    <category term="macros" />
    <category term="rails" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/giZElcx-aNY/make-it-so-with-rspec-macros" rel="alternate" type="text/html" />
    <title>Make it so with RSpec Macros</title>
    <content type="html">&lt;p&gt;RSpec macros (like those in the fantastic &lt;a href="http://github.com/carlosbrando/remarkable"&gt;Remarkable&lt;/a&gt; library) ease spec writing for repetitive tasks, but is that process more effort than it&amp;#8217;s worth? No&amp;#8212;it&amp;#8217;s actually quite easy to write and include macros for your specs to do some of the standard heavy lifting.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.benmabey.com/2008/06/08/writing-macros-in-rspec/"&gt;This is a great resource&lt;/a&gt; to get started with how to write the actual macros (or custom matchers) themselves.&lt;/p&gt;


	&lt;p&gt;What tripped me up was how to actually include them in my examples. Monkeypatching is rarely a clean process. And, while the comments on that post mentioned a public &lt;span class="caps"&gt;API&lt;/span&gt;, how to use that &lt;span class="caps"&gt;API&lt;/span&gt; wasn&amp;#8217;t immediately obvious (as with many things about RSpec).&lt;/p&gt;


	&lt;p&gt;In my case, I was looking to define a quick &lt;code&gt;login!&lt;/code&gt; macro that would allow me to easily create a before block to log in as a specified user or just as a FactoryGirl generated one in a &lt;a href="http://github.com/mbleigh/twitter-auth"&gt;TwitterAuth&lt;/a&gt; based app. Here&amp;#8217;s the module I wrote and stuck in my &lt;code&gt;spec_helper.rb&lt;/code&gt;:&lt;/p&gt;


&lt;pre name='code' class='ruby'&gt;module LoginMacro
  def login!(user=Factory(:user))
    before do
      @current_user = user
      controller.stub!(:current_user).and_return(@current_user)
      session[:user_id] = @current_user.id
    end
  end
end&lt;/pre&gt;

	&lt;p&gt;So that was relatively straightforward and now what I wanted to be able to do was call it in my controller specs like this:&lt;/p&gt;


&lt;pre name='code' class='ruby'&gt;describe UsersController do
  describe "#create" do
    login!

    it 'should etc. etc.'
  end
end&lt;/pre&gt;

	&lt;p&gt;As it turns out, RSpec offers the ability to add macros and matchers via the &lt;code&gt;config.extend&lt;/code&gt; and &lt;code&gt;config.include&lt;/code&gt; methods on the RSpec &lt;a href="http://gitrdoc.com/rdoc/dchelimsky/rspec/cdbdeef23f3496d81799bebfd2091f0d73084138/classes/Spec/Runner/Configuration.html"&gt;configuration object&lt;/a&gt; (extend is for class-level macros like the one I wrote here, include is for instance-level matchers). You just have to add this to your spec helper&amp;#8217;s configuration portion:&lt;/p&gt;


&lt;pre name='code' class='ruby'&gt;config.extend(LoginMacro)&lt;/pre&gt;

	&lt;p&gt;Voila! Now your specs will be able to use the &lt;code&gt;login!&lt;/code&gt; macro to set up a user in no time.&lt;/p&gt;


	&lt;p&gt;Experienced RSpec users are already familiar with this, but I find that certain things can be hard to come across if you don&amp;#8217;t already know how to use them. So I thought I&amp;#8217;d blog for the benefit of others like me: this is an easy way to use RSpec macros.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/giZElcx-aNY" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/make-it-so-with-rspec-macros</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Dave Potsiadlo</name>
    </author>
    <id>tag:www.intridea.com,2009-05-13:172</id>
    <published>2009-05-13T12:00:00-04:00</published>
    <updated>2009-05-13T12:00:00-04:00</updated>
    <category term="design" />
    <category term="vector" />
    <category term="logos" />
    <category term="tutorials" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/iIYnx1gnMk8/hacking-the-washington-capitals-logo-with-illustrator" rel="alternate" type="text/html" />
    <title>Hacking the Washington Capitals Logo with Illustrator</title>
    <content type="html">&lt;p&gt;While on a recent plane ride, I embarked on a self-imposed quickfire challenge to use Adobe Illustrator to design the text &amp;#8220;@davidpots&amp;#8221; (my &lt;a href="http://www.twitter.com/davidpots"&gt;Twitter username&lt;/a&gt;) in the style of the Washington Capitals logo.  I was armed with only 45 minutes and a vector version of the Capitals logo; no internet connection would be at hand for additional assets (such as fonts, etc).&lt;/p&gt;
&lt;p&gt;By the end of the plane ride, things worked out great:&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/01-washington-capitals-davidpots.png" alt="turning Washington Capitals logo into David Potsiadlo twitter icon" /&gt;&lt;/p&gt;
&lt;p&gt;Throughout the remainder of the post, I&amp;#8217;d like to share an overview of the approach I took and the Illustrator techniques used to make this happen.  The result is not merely a tutorial, but rather a broad look at some Illustrator skills any user might find helpful in such a situation.&lt;span id="more-57"&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;Start With What You&amp;#8217;ve Got&lt;/h3&gt;
&lt;p&gt;First step when resources are short?  Make the most of what you&amp;#8217;ve already got.  While in a perfect world I&amp;#8217;d have access to the font on which the Capitals logo is based, in this case I&amp;#8217;d have to make due with the letters (or rather, shapes) that make up the source logo I was starting with.&lt;/p&gt;
&lt;p&gt;Fortunately, &amp;#8220;Capitals&amp;#8221; and &amp;#8220;@davidpots&amp;#8221; have quite a few letters in common.  My first move was to ungroup the shapes in the &amp;#8220;Capitals&amp;#8221; logo and move all letters that matched into their proper placement in their &amp;#8220;@davidpots&amp;#8221; counterpart.&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/02-see-what-youve-got.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;After this first step alone, about half of the letters are already in place.  What’s left?  Creating the “@”, “d”, “v”, and “o”.  Onward we go.&lt;/p&gt;

&lt;h3&gt;This Shape + That Shape&lt;/h3&gt;
&lt;p&gt;To create the remaining letters, I would have to create custom shapes based on the contours of existing elements. This would ensure the overall look &amp;amp; feel of the logo remained consistent.&lt;/p&gt;
&lt;p&gt;Starting with the “d”, I saw that the base contours I’d need already existed in the “c” and the “l”.  Through combining these two objects, the resulting “d” would retain the general shape of these other letters.&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/03-making-the-d.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;So far so good.  While the remaining letters wouldn’t necesarily be as simple to create, the basic premise &amp;amp; approach would be the same.&lt;/p&gt;

&lt;h3&gt;Take This, Tweak That, and Drop the Rest&lt;/h3&gt;
&lt;p&gt;Next up is the letter “v”.  After a moment’s investigation, it seemed the best way to recreate the bottom point of the “v” (with existing elements of “Capitals”) is through the upper-right corner of the letter “p”.&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/04-spotting-the-v-corner.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Unlike the creation of the “d”, this would require a bit more work.  Instead of simply combining two separate letters to create a third, I would instead be transforming &amp;amp; tweaking part of a letter and then getting rid of the rest.  I did it like this:&lt;/p&gt;
&lt;p&gt;First, rotate the “p” 180 degrees&amp;#8230;&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/05-p_step_1.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Second, use the direct select tool to increase the height of the left “arm”&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/06-p_step_2.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Third, use the Pathfinder’s divide function to get rid of excess shape at the top&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/07-p_step_3.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;And that’s it! The “v” is ready to be inserted into its namesake.&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/08-p_step_4.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;The exact same approach was used to create the “o”.  Starting with the already-existant “p”, (1) the shape is divided, as to get rid of the unnecessary bottom stem.  (2) Next, the remaining “corner” is duplicated &amp;amp; rotated 180 degrees.  (3) Finally, the two remaining pieces are moved into place to form the “o”.  Voila!&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/09-making-the-o.png" alt="" /&gt;&lt;/p&gt;

&lt;h3&gt;Round the Corner(s) &amp;amp; Tie Up Loose Ends&lt;/h3&gt;
&lt;p&gt;The final and most challenging letter to create was the “@”, which would require the most alchemy of the bunch.  In summary, my plan would be to first (1) create the interior shape of the symbol, and second (2) use an external stroke to create the “wrap around” shape of the symbol &amp;#8212; this would ensure the curves were 100% right-on. Here’s how I made it happen:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Creating the inner shape&lt;/strong&gt;&lt;br /&gt;
The first step was creating the inner shape of the “@”.  Locating all I would need in the base of the “d” contour, I simply created a dividing line and used the Pathfinder’s divide tool to make a clean cut:&lt;/p&gt;

&lt;p style="text-align:center;"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/10-at_pt_1.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rounding the Corners, Part 1&lt;/strong&gt;&lt;br /&gt;
So far so good &amp;#8212; but I realized that I would need to round out the corners on the right-hand side of the shape I created (lest the sharp/jagged run wild and free).  To make this happen, I first (1) spotted an existing corner “curve” in the “p”, (2) used the Pathfinder’s divide tool to isolate this corner, (3) and finally shifted this over into the contour of my original shape.&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/11-at_pt_2.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rounding the Corners, Part 2&lt;/strong&gt;&lt;br /&gt;
The previous “round the corner” approach was used one more time for the upper-right corner of the shape.  This time I used an existing corner from the “a” to make it happen.  Same basic steps:&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/12-at_pt_3.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Creating the Outer Wrapper&lt;/strong&gt;&lt;br /&gt;
In order to create an outter wrapper for the “@”, I decided to use the object’s stroke.  This would ensure the curves remained consistent in both contour and width.  To make this happen, I first (1) gave an exterior stroke to my original object. Next, (2) an additional stroke of then wrapped around the shape again.  Finally, (3) after expanding the strokes into proper shapes (Object &amp;gt; Expand), I used the Pathfinder’s divide tool to get rid of the undesired middle “red” section.&lt;/p&gt;

&lt;p style="text-align:center;"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/13-at_pt_4.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Finishing Touches&lt;/strong&gt;&lt;br /&gt;
The very last step involves tweaking the lower-right section of the shape to complete the “@” transition.  This involved (1) using the Pathfinder’s divide tool to once again get rid of the undesired portion of the outer wrapper.  (2) Next, I created a small curved shape to join the two shapes, which was (3) moved into place and combined with both shapes to complete the task.&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/14-at_pt_5.png" alt="" /&gt;&lt;/p&gt;
&lt;h3&gt;And We’re All Done!&lt;/h3&gt;
&lt;p&gt;And there you have it!  All shapes have now been created.  I needed only to align the items as desired and save my final product (which I now proudly wear as my Twitter profile pic in support of the team).&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;a style="border: none" href="http://www.twitter.com/davidpots"&gt;&lt;img style="border: 0; padding: 15px 0; background: #fff;" src="http://www.skipvision.com/images/blog/caps-davidpots-logo/15-david-potsiadlo-washington-capitals-logo-twitter.png" alt="Washington Capitals + David Potsiadlo (davidpots) twitter logo" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Could this have been arrived at quicker if I had the original “Capitals” font to work with?  Of course!  But that is removed from the point: this was instead about the challenge of a self-imposed quickfire task which forced me to think quickly &amp;amp; make the most of the resources at hand.&lt;/p&gt;
&lt;p&gt;In closing, I must of course bestow the Caps with all the good luck I can muster for game 7 against Pittsburgh.  It has been a truly epic series so far, and I trust Washington is going to bring it home to DC with their best performance of the series.  Let’s go Caps!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/iIYnx1gnMk8" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/hacking-the-washington-capitals-logo-with-illustrator</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Michael Bleigh</name>
    </author>
    <id>tag:www.intridea.com,2009-05-08:170</id>
    <published>2009-05-08T18:15:00-04:00</published>
    <updated>2009-05-08T18:15:00-04:00</updated>
    <category term="railsconf" />
    <category term="rails" />
    <category term="twitter" />
    <category term="talk" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/Pch3D_euebw/railsconf-2009-twitter-on-rails" rel="alternate" type="text/html" />
    <title>RailsConf 2009: Twitter on Rails</title>
    <content type="html">&lt;p&gt;And I&amp;#8217;m back from RailsConf 2009! I had a great time and enjoyed meeting and speaking with a number of Rubyists who had previously only been @-names on Twitter. I also had a great time giving my talk, Twitter on Rails. Thanks to everyone who had a chance to make the session and especially everyone who made it to the Twitter BoF on Wednesday night. I got some great feedback and interesting ideas for future work.&lt;/p&gt;


	&lt;p&gt;I recorded my entire session as a screencast (a last-minute idea that I&amp;#8217;m very glad to have had; with 30+ minutes of livecode the slides are only so useful), and I have also posted the &lt;a href="http://www.slideshare.net/mbleigh/twitter-on-rails-1396030"&gt;slides&lt;/a&gt; (also embedded below) and &lt;a href="http://github.com/mbleigh/twisteners"&gt;the completed livecode&lt;/a&gt;. I&amp;#8217;m happy to answer any questions about Twitter app development, TwitterAuth, or anything else since I didn&amp;#8217;t have a chance to take questions during the session.&lt;/p&gt;


&lt;p align='center'&gt;&lt;embed src="http://blip.tv/play/AYGAjWQA" type="application/x-shockwave-flash" width="600" height="480" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/p&gt;

&lt;p align='center'&gt;&lt;object style="margin:0px" width="600" height="480"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=twitteronrails-090506141804-phpapp01&amp;#38;stripped_title=twitter-on-rails-1396030" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=twitteronrails-090506141804-phpapp01&amp;#38;stripped_title=twitter-on-rails-1396030" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="600" height="480"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

	&lt;p&gt;Thanks to everyone at RailsConf for making it a great conference, and hopefully I&amp;#8217;ll see many of you at another Ruby event soon!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/Pch3D_euebw" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/railsconf-2009-twitter-on-rails</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Chris Selmer</name>
    </author>
    <id>tag:www.intridea.com,2009-04-22:169</id>
    <published>2009-04-22T17:00:00-04:00</published>
    <updated>2009-04-22T17:00:00-04:00</updated>
    <category term="Earth Day" />
    <category term="Earth Aid" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/TzlYf2wh8WY/earth-aid-on-earth-day" rel="alternate" type="text/html" />
    <title>Earth Aid on Earth Day</title>
    <content type="html">&lt;p&gt;On this Earth Day, we are happy to highlight our most Earth-friendly client, &lt;a href="http://www.earthaid.net/r/3"&gt;Earth Aid&lt;/a&gt;.  We've been working with Earth Aid to build an innovative new service designed to help consumers reduce energy consumption and then reward them for their savings.  This is the first service to bring carbon offset trading down to the individual level &amp;mdash; previously carbon offsets had only been tracked and traded at the big business level.&lt;/p&gt;

&lt;p&gt;Hear it first-hand from Earth Aid CEO, Ben Bixby:&lt;p&gt;

&lt;blockquote&gt;"Households have a big role to play in the fight against global warming, but they’ve been left out of the $100 billion carbon market system that allows big business to earn rewards when they save. Earth Aid's service is the first tool that can measure and verify your energy savings, 'bundle' them with savings from other households, and then sell them on carbon markets, in the same way as big business."&lt;/blockquote&gt;

&lt;p&gt;From the day we started, we knew there would be significant technology hurdles to overcome, along with a tightly compressed development schedule.  Earth Aid chose Intridea as their technology and design partner because of our reputation as an innovative company that excels under pressure.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.earthaid.net/r/3"&gt;&lt;img src="http://img.skitch.com/20090422-r7nxhbuxrwew361ggk54esse61.png"/ width="350" align="right" hspace="5" vspace="5"&gt;&lt;/a&gt;Our team loves a challenge, and were able to get through even the thorniest problems that came up throughout development.  Using our proven agile methodologies, we worked closely with Earth Aid to deliver feature-rich iterations that brought them closer to their launch point every week.  Working in tandem, our design and development teams built a great looking user interface that was full of function and easy to understand.&lt;/p&gt;

&lt;p&gt;Ben and the crew at Earth Aid are a pleasure to work with.  Their enthusiasm for making the world a greener place is contagious, and our team voluntarily put in extra hours to help ensure a successful beta launch.  We're looking forward to expanding the Earth Aid feature set and providing additional ways for individuals to reduce their footprint and earn money at the same time.&lt;/p&gt;

&lt;p&gt;Please check &lt;a href="http://www.earthaid.net/r/3"&gt;EarthAid.net&lt;/a&gt; out and sign up today - not only will you do the planet some good, but you'll get paid for it, too!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/TzlYf2wh8WY" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/earth-aid-on-earth-day</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Michael Bleigh</name>
    </author>
    <id>tag:www.intridea.com,2009-04-17:168</id>
    <published>2009-04-17T22:32:00-04:00</published>
    <updated>2009-04-17T22:32:00-04:00</updated>
    <category term="twitter" />
    <category term="twitterauth" />
    <category term="rails" />
    <category term="sso" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/8HEC9pQXIEU/twitter-auth-supports-sign-in-with-twitter" rel="alternate" type="text/html" />
    <title>TwitterAuth Supports 'Sign in with Twitter'</title>
    <content type="html">&lt;p&gt;Twitter recently implemented &lt;a href="http://apiwiki.twitter.com/Sign-in-with-Twitter"&gt;Sign in with Twitter&lt;/a&gt;, a convenience layer on top of their OAuth solution that provides a better user experience for those making use of OAuth as a sign-in strategy for their applications. I have just added support for this new feature to &lt;a href="http://mbleigh.com/twitter-auth"&gt;TwitterAuth&lt;/a&gt;. This is available immediately to new applications made with TwitterAuth as the default implementation.&lt;/p&gt;


&lt;p align='center'&gt;&lt;img src="http://apiwiki.twitter.com/f/1239839565/sign_in_with_twitter.gif" alt="" /&gt;&lt;/p&gt;

	&lt;p&gt;If you already have a TwitterAuth application that you would like to utilize the new sign in method all you need to do is add one line to each of your &lt;code&gt;twitter_auth.yml&lt;/code&gt; environments:&lt;/p&gt;


&lt;pre name='code' class='yaml'&gt;authorize_path: "/oauth/authenticate"&lt;/pre&gt;

	&lt;p&gt;You don&amp;#8217;t need to reset any user data or make any other changes, and when you restart your server people should be able to take advantage of the new experience. Enjoy!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/8HEC9pQXIEU" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/twitter-auth-supports-sign-in-with-twitter</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Michael Bleigh</name>
    </author>
    <id>tag:www.intridea.com,2009-04-09:167</id>
    <published>2009-04-09T15:06:00-04:00</published>
    <updated>2009-04-09T15:06:00-04:00</updated>
    <category term="presently" />
    <category term="announcements" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/aNWB6HRxk3M/presently-adds-ldap-support" rel="alternate" type="text/html" />
    <title>Present.ly Adds LDAP Authentication</title>
    <content type="html">&lt;p&gt;We want to make Present.ly a seamless part of your organization&amp;#8217;s workflow. To that end we are excited to announce a new feature that is finally ready to enter beta: &lt;strong&gt;&lt;span class="caps"&gt;LDAP&lt;/span&gt; Integration&lt;/strong&gt;! With &lt;span class="caps"&gt;LDAP&lt;/span&gt;, you can allow your employees to use the same credentials to log in to Present.ly that they use to log in to your other business services, making it easier and more secure by utilizing your existing processes. This is especially useful for large organizations with hundreds of employees, as replicated logins create a great deal of stress and extra work.&lt;/p&gt;


	&lt;p&gt;To utilize the &lt;span class="caps"&gt;LDAP&lt;/span&gt; integration in Present.ly an administrator of your network needs to go to the Admin page and click on &lt;strong&gt;&lt;span class="caps"&gt;LDAP&lt;/span&gt; Settings&lt;/strong&gt;. The administrator should then fill out the form that appears:&lt;/p&gt;


&lt;p align='center'&gt;&lt;img src="http://img.skitch.com/20090407-1b56yw3ax6b1xsascmmrjd8nme.jpg" alt="test [Present.ly]"/&gt;&lt;/p&gt;

	&lt;p&gt;For more detailed information about &lt;span class="caps"&gt;LDAP&lt;/span&gt; usage, visit the &lt;a href="http://support.presentlyapp.com/faqs/using-presently/ldap-integration"&gt;&lt;span class="caps"&gt;LDAP&lt;/span&gt; Knowledge Base Article&lt;/a&gt; on the Present.ly support pages. This feature is available immediately for all claimed networks. It is still considered a beta feature at this point, so if you have any questions, concerns, or problems don&amp;#8217;t hesitate to &lt;a href="mailto:support@presentlyapp.com"&gt;contact support&lt;/a&gt; and we&amp;#8217;ll work with you to improve the system.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/aNWB6HRxk3M" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/presently-adds-ldap-support</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Brendan Lim</name>
    </author>
    <id>tag:www.intridea.com,2009-04-06:165</id>
    <published>2009-04-06T20:26:00-04:00</published>
    <updated>2009-04-06T20:26:00-04:00</updated>
    <category term="larubyconf" />
    <category term="conference" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/JBCNaQxODNc/la-ruby-conference-2009-recap" rel="alternate" type="text/html" />
    <title>LA Ruby Conference 2009 Recap</title>
    <content type="html">&lt;p&gt;Pradeep Elankumaran and I just came back from the very first &lt;a href="http://larubyconf.com"&gt;LA Ruby Conference&lt;/a&gt; (&lt;a href="http://twitter.com/larubyconf"&gt;Twitter&lt;/a&gt;), which was held in Tustin, CA.  We didn&amp;#8217;t know what Tustin had to offer or what to expect, since it was the first time either of us has visited Tustin.  When we arrived  at the venue, we were in awe of the few million dollars worth of automobiles surrounding the stage.  The conference was held in the &lt;a href="www.marconimuseum.org"&gt;Marconi Automotive Museum&lt;/a&gt;, which is filled with Ferrari&amp;#8217;s, Lamborghini&amp;#8217;s, F1 cars&amp;#8212;you name it.  The event ended up being a huge success due to the great venue and the amazing set of talks, with a final count of 115 attendees.&lt;/p&gt;


&lt;center&gt;&lt;a href='http://farm4.static.flickr.com/3640/3413028057_1acdb14d97_b.jpg'&gt;&lt;img src='http://farm4.static.flickr.com/3640/3413028057_1acdb14d97_m.jpg'&gt;&lt;/a&gt; &lt;a href='http://farm4.static.flickr.com/3352/3413027351_68b2d74457_b.jpg'&gt;&lt;img src='http://farm4.static.flickr.com/3352/3413027351_68b2d74457_m.jpg'&gt;&lt;/a&gt;
&lt;/center&gt;

&lt;center&gt;&lt;a href="http://farm4.static.flickr.com/3652/3413057971_08bf89d418_b.jpg"&gt;&lt;img src="http://farm4.static.flickr.com/3652/3413057971_08bf89d418_m.jpg" alt="" /&gt;&lt;/a&gt;  &lt;a href="http://farm4.static.flickr.com/3366/3413017651_ab18d72447_b.jpg"&gt;&lt;img src="http://farm4.static.flickr.com/3366/3413017651_ab18d72447_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/center&gt;

	&lt;p&gt;&lt;br/&gt;
There were many great talks that ended up covering a wide variety of topics.  You can view the whole schedule &lt;a href="http://larubyconf.com/schedule"&gt;here&lt;/a&gt;.  One very unique talk was by Ron &amp;#38; Damen Evans with their unveiling of &lt;a href="http://github.com/deadprogrammer/flying_robot"&gt;Flying Robot&lt;/a&gt;, a platform for &lt;a href="http://rad.rubyforge.org/"&gt;Ruby Arduino Development&lt;/a&gt;.  The Ruby powered blimp, flew around the museum, while being controlled by a Wii-mote.&lt;/p&gt;


&lt;center&gt;&lt;a href="http://farm4.static.flickr.com/3400/3413047953_a16ba128c9_b.jpg"&gt;&lt;img src="http://farm4.static.flickr.com/3400/3413047953_a16ba128c9_m.jpg" alt="" /&gt;&lt;/a&gt; &lt;a href="http://farm4.static.flickr.com/3639/3413850414_dd78e3963d_b.jpg"&gt;&lt;img src="http://farm4.static.flickr.com/3639/3413850414_dd78e3963d_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/center&gt;
&lt;center&gt;&lt;a href="http://farm4.static.flickr.com/3335/3413858388_a45aa6b43e_b.jpg"&gt;&lt;img src="http://farm4.static.flickr.com/3335/3413858388_a45aa6b43e_m.jpg" alt="" /&gt;&lt;/a&gt; &lt;a href="http://farm4.static.flickr.com/3338/3413050697_d5841e979e_b.jpg"&gt;&lt;img src="http://farm4.static.flickr.com/3338/3413050697_d5841e979e_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/center&gt;

	&lt;p&gt;&lt;br/&gt;
Pradeep gave his talk on &lt;i&gt;Fast and Scalable Front/Back-end Services using Ruby, Rails and &lt;span class="caps"&gt;XMPP&lt;/span&gt;&lt;/i&gt; and I gave my talk on &lt;i&gt;Mobilizing Your Rails Application&lt;/i&gt;.  The kind fellas from &lt;a href="http://confreaks.com"&gt;Confreaks&lt;/a&gt; were there recording each talk as well, so be sure to look out for those when they become available.&lt;/p&gt;


	&lt;p&gt;From flying robots to creating cross-platform native mobile applications, it&amp;#8217;s  quite clear that there are some very exciting things going on in the world of Ruby development.  Our thanks and congratulations goes out to &lt;a href="http://www2.confreaks.com/"&gt;Coby Renquist&lt;/a&gt;, &lt;a href="http://www.jrfent.com/blog/"&gt;JR Fent&lt;/a&gt;, all of the great speakers and everybody else who helped to put on such a great conference.  We are both looking forward to going back to Tustin in 2010.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/JBCNaQxODNc" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/la-ruby-conference-2009-recap</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Michael Bleigh</name>
    </author>
    <id>tag:www.intridea.com,2009-04-03:164</id>
    <published>2009-04-03T08:13:00-04:00</published>
    <updated>2009-04-03T08:13:00-04:00</updated>
    <category term="twitter" />
    <category term="twitterauth" />
    <category term="rails" />
    <category term="template" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/yZjClmn2yX0/rails-template-create-a-twitter-application-in-seconds" rel="alternate" type="text/html" />
    <title>Rails Template: Create a Twitter Application in Seconds</title>
    <content type="html">&lt;p&gt;&lt;a href="http://mbleigh.com/twitter-auth"&gt;TwitterAuth&lt;/a&gt; has been out for a little while and has received some great feedback. &lt;a href="http://drnicwilliams.com/2009/03/30/closing-in-on-the-dream-one-click-to-deploy-rails-apps/"&gt;Dr. Nic released a great template&lt;/a&gt; that lets you quickly build a TwitterAuth app for deployment to SliceHost and since I have some plans for a number of Twitter applications I wanted to try my own hand at writing one up.&lt;/p&gt;


	&lt;p&gt;If you have Rails 2.3, all you need to do is run this:&lt;/p&gt;


&lt;pre&gt;rails -m http://github.com/mbleigh/rails-templates/raw/master/twitterapp.rb yourappname&lt;/pre&gt;

	&lt;p&gt;Changing &lt;code&gt;yourappname&lt;/code&gt; to the directory in which you want to generate your application. The template will then prompt you for three things:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;What is your application called?&lt;/strong&gt; Just give it a title for the pretty template generators.&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;OAuth Consumer Key:&lt;/strong&gt; The consumer key that you register at &lt;a href="http://twitter.com/oauth_clients"&gt;http://twitter.com/oauth_clients&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;OAuth Consumer Secret&lt;/strong&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;It will also ask you if you want to install missing gems and go ahead and generate your databases and run migrations. Once you&amp;#8217;ve responded through the prompts though, you&amp;#8217;re good to go! Just switch to your application&amp;#8217;s directory and &lt;code&gt;script/server&lt;/code&gt;. Your &lt;code&gt;http://localhost:3000&lt;/code&gt; should look like this:&lt;/p&gt;


&lt;p align='center'&gt;&lt;img src="http://img.skitch.com/20090402-xgbi1p5wjggqksnbu8r3tsa4sc.jpg" alt="" /&gt;&lt;/p&gt;

	&lt;p&gt;When you click on &lt;strong&gt;Login via Twitter&lt;/strong&gt; you will be taken to the Twitter OAuth approval page.&lt;/p&gt;


&lt;p align='center'&gt;&lt;img src="http://img.skitch.com/20090402-k5gufygc3cj7taef4uy6f38st.jpg" alt="" /&gt;&lt;/p&gt;

	&lt;p&gt;Twitter will then send you back to your application, and guess what? You&amp;#8217;re logged in!&lt;/p&gt;


&lt;p align='center'&gt;&lt;img src="http://img.skitch.com/20090402-jijjh2ducfgpnr7uy9hbnsuatf.jpg" alt="" /&gt;&lt;/p&gt;

	&lt;p&gt;You can now build on top of this without having to worry about the basic authentication stack. If you aren&amp;#8217;t familiar with TwitterAuth, it works a lot like RESTful Authentication, so it should be easy to pick up.&lt;/p&gt;


	&lt;p&gt;Enjoy, and I hope you find it useful!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/yZjClmn2yX0" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/rails-template-create-a-twitter-application-in-seconds</feedburner:origLink></entry>
  <entry xml:base="http://www.intridea.com">
    <author>
      <name>Michael Bleigh</name>
    </author>
    <id>tag:www.intridea.com,2009-03-31:163</id>
    <published>2009-03-31T15:00:00-04:00</published>
    <updated>2009-03-31T15:00:00-04:00</updated>
    <category term="presently" />
    <category term="webware100" />
    <category term="announcement" />
    <link href="http://feedproxy.google.com/~r/intridea/~3/n3BUDuGiXgw/presently-is-a-webware-100-finalist" rel="alternate" type="text/html" />
    <title>Present.ly is a WebWare 100 Finalist!</title>
    <content type="html">&lt;div style='float: right;'&gt;&lt;a href="http://www.cnet.com/html/ww/100/2009/poll/communication.html"&gt;&lt;img src="http://www.cnet.com/html/ww/100/2009/images/voteforus/webware100-09_vote_l.jpg" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;

	&lt;p&gt;Intridea&amp;#8217;s &lt;a href="http://www.presentlyapp.com"&gt;Present.ly&lt;/a&gt; has been nominated as a finalist in the &lt;a href="http://www.cnet.com/html/ww/100/2009/poll/communication.html"&gt;WebWare 100 Communication Category&lt;/a&gt;. We&amp;#8217;re honored to be chosen from a pool of more than 5,000 applicants to be one of the 300 finalists to compete for the title.&lt;/p&gt;


	&lt;p&gt;The WebWare 100 is a yearly contest held by &lt;span class="caps"&gt;CNET&lt;/span&gt; that allows the public to pick what the 100 best web applications of the year are. Past winners included such products as GMail and Amazon &lt;span class="caps"&gt;MP3&lt;/span&gt;, so we&amp;#8217;re very excited to be included as a finalist for this year&amp;#8217;s selection.&lt;/p&gt;


	&lt;p&gt;Voting is open right now, so please &lt;a href="http://www.cnet.com/html/ww/100/2009/poll/communication.html"&gt;vote for us&lt;/a&gt;! We think that business micro-communication is an important next step in the future of communication, and your votes will help validate that and move it even further into the mainstream. Thanks for your support.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/intridea/~4/n3BUDuGiXgw" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://www.intridea.com/posts/presently-is-a-webware-100-finalist</feedburner:origLink></entry>
</feed>
