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

<channel>
	<title>Blog &#124; The Working Group</title>
	<atom:link href="http://blog.twg.ca/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.twg.ca</link>
	<description></description>
	<lastBuildDate>Tue, 23 Feb 2010 04:17:11 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>TWG Kicks Off 2010 with Scrum!</title>
		<link>http://blog.twg.ca/2010/02/twg-kicks-off-2010-with-scrum/</link>
		<comments>http://blog.twg.ca/2010/02/twg-kicks-off-2010-with-scrum/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 15:47:17 +0000</pubDate>
		<dc:creator>todd</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[TWG News]]></category>
		<category><![CDATA[Team]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[sales]]></category>
		<category><![CDATA[scrum]]></category>

		<guid isPermaLink="false">http://blog.twg.ca/?p=444</guid>
		<description><![CDATA[TWG would like to formally welcome you to 2010 and talk a little bit about something we&#8217;ve decided to kick off the new year with: Scrum!
Scrum is an agile framework that allows teams to become self organizing and focus on delivering high business value.
In 2010, TWG is committed to delivering working, high business value, high [...]]]></description>
			<content:encoded><![CDATA[<p>TWG would like to formally welcome you to 2010 and talk a little bit about something we&#8217;ve decided to kick off the new year with: Scrum!</p>
<p>Scrum is an agile framework that allows teams to become self organizing and focus on delivering high business value.</p>
<p>In 2010, TWG is committed to delivering working, high business value, high quality software, faster.  This is something Scrum enables us to do.</p>
<h2>Why Change?</h2>
<p>While TWG has previously used plenty of agile practices, the time has come to formalize the process so that we can get all the benefits of being an agile organization.</p>
<h2>How Is Agile Different?</h2>
<p>Many agencies and web development companies typically insist on gathering every single requirement up front, locking them down, forcing the client to sign off, swearing that these requirements will never change.  We now know better.  Requirements will change, we learn as we go, and we will inevitably discover new and more valuable features as the project comes together.  TWG is using Scrum to build partnering relationships with our clients, so that we can see and adapt to requirements as they emerge, and deliver better and more usefule websites and software.</p>
<h2>Build Less Software&#8230;</h2>
<p>So how do you build high value, high quality software, quickly?  Build less, but build it better!</p>
<p>This may seem unusual, but remember, when you start a project, application or a web site, you don&#8217;t really know what you or your users want until you get your hands on it and start playing with it.  This is normal.  So instead of trying to plan it all up front, we&#8217;re going to be working on building the things you know right now, and get them done, Done, DONE!</p>
<p>Nothing gets feedback better than working software, so why wait until the end of your project to see it?  Once you&#8217;ve seen it and learned from it, you can add to it, change it or even scrap it!</p>
<p>At TWG, we&#8217;re starting Scrum with 1 week sprints.  These are time boxed working periods where at the end, our goal is to deliver working software, as opposed to things like documents, mock-ups or in-progress features.  This is a tough, aggressive process that we&#8217;re working on, but we feel in the end it will enable us to deliver better, more valuable software, faster.</p>
<h2>&#8230;Get more value (rather than a laundry list).</h2>
<p>Many web development companies will work with you to look around at all the sites that are out there, collect a large laundry lists of  possible features that you might want your system to do, and then give a quote on building that.  You sign off, and the work gets started.  You wait potentially months until all the features are built, the schedule might slip two or three times, and when you finally get it, you discover you really didn&#8217;t end up with the software you really hoped for or needed.</p>
<p>Not only that, but while the software was being built, the market changed and some features became irrelevant or new features became more critical.  Too late to change now.  I guess you&#8217;re stuck.</p>
<p>What if you had your list of features prioritized in order of importance/ROI and what if you got the most important features first each iteration &#8211; say every week?  Maybe you&#8217;d find out you didn&#8217;t need to build those last few features since they weren&#8217;t all that valuable anyway, or maybe you&#8217;d find you could swap some of those less valuable ones out for new ones.  Who wouldn&#8217;t want that kind of flexibility?</p>
<h2>What Comes Next?</h2>
<p>This transition is a work in progress and we&#8217;re going to give you regular updates and insights into our experiences with Scrum.  You&#8217;ll get to see some of the nitty-gritty details like our task board, and burn up charts, as well as some of the struggles and discoveries we make as we go down this road.  We hope you&#8217;ll keep your eye on our blog and provide us with any feedback or experiences you&#8217;ve had.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.twg.ca/2010/02/twg-kicks-off-2010-with-scrum/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hump-Day: Whose website sucks less?</title>
		<link>http://blog.twg.ca/2010/02/hump-day-whose-website-sucks-less/</link>
		<comments>http://blog.twg.ca/2010/02/hump-day-whose-website-sucks-less/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 16:15:25 +0000</pubDate>
		<dc:creator>Andrés</dc:creator>
				<category><![CDATA[Hump-Day]]></category>

		<guid isPermaLink="false">http://blog.twg.ca/?p=500</guid>
		<description><![CDATA[North 44 &#8211; One of Toronto&#8217;s best fine dining restaurants,

or
Taquerias El Farolito &#8211; Serves excellent Mexican food and has 9 locations in California.
Note: their website is a giant .gif of their menu, and the site says it&#8217;s still under construction.

Survey says&#8230; North44 sucks more!

Dear North44,
Your restaurant is divine, but your website sucks. Skip the intro, [...]]]></description>
			<content:encoded><![CDATA[<p><a title="North 44" href="http://north44restaurant.com" target="_blank">North 44</a> &#8211; One of Toronto&#8217;s best fine dining restaurants,</p>
<p><a href="http://north44restaurant.com" target="_blank"><img class="size-large wp-image-536 alignnone" title="North44" src="http://blog.twg.ca/wp-content/uploads/2010/02/North44-1024x767.png" alt="North44" width="614" height="460" /></a><br />
or<br />
<a title="Taquerias El Farolito" href="http://elfarolitoinc.com/" target="_blank">Taquerias El Farolito</a> &#8211; Serves excellent Mexican food and has 9 locations in California.<br />
Note: their website is a giant .gif of their menu, and the site says it&#8217;s still <em>under construction</em>.</p>
<p><a href="http://elfarolitoinc.com/" target="_blank"><img class="alignnone size-large wp-image-537" title="El_Farolito" src="http://blog.twg.ca/wp-content/uploads/2010/02/El_Farolito-1024x955.png" alt="El_Farolito" width="614" height="573" /></a></p>
<p>Survey says&#8230; North44 sucks more!</p>
<div style="float:left;padding:0 10px 10px 0;"><img class="alignleft size-full wp-image-505" title="North44_fail" src="http://blog.twg.ca/wp-content/uploads/2010/02/North44_fail.jpg" alt="North44_fail" width="192" height="288" /></div>
<p>Dear North44,<br />
Your restaurant is divine, but your website sucks. Skip the intro, lose the flash, and show me your phone number/address within 0.25secs of my arrival on your web page.</p>
<p>Look what your site did to my iPhone!</p>
<p>Thank you,<br />
The Internet Police</p>
<p>P.S. If you want a better website, call me (416.850.2500)</p>
<p>P.S.S. If you don&#8217;t understand what I&#8217;m talking about read this gem from <a title="VenomousPorridge" href="http://venomousporridge.com/post/389785000/a-conversation-i-have-every-month-or-so#disqus_thread" target="_blank">venomousporridge.com</a></p>
<p><strong>Me:</strong> <em>(tries to visit a local restaurant’s website via iPhone)</em><br />
<strong>Restaurant website:</strong> I require Flash. Fuck off.<br />
<strong>Me:</strong> I just want to know how late you’re open.<br />
<strong>Website:</strong> Nope.<br />
<strong>Me:</strong> But I’m on my phone. Don’t you have a little “HTML Version” link up in the corner or something?<br />
<strong>Website:</strong> I’m ignoring you.<br />
<strong>Me:</strong> What if I’m on my phone because I’m <em>out, looking for a place to eat? </em>Didn’t that ever occur to you?<br />
<strong>Website:</strong> Fuck entirely off.<br />
<strong>Me:</strong> <em>(gives up, switches to computer)</em><br />
<strong>Website:</strong> Oh! Hi! What can I help you with today?<br />
<strong>Me:</strong> What are your —<br />
<strong>Website:</strong> Hang on, I’m loading the music. <a title="VenomousPorridge.com" href="http://venomousporridge.com/post/389785000/a-conversation-i-have-every-month-or-so#disqus_thread" target="_blank">Read more&#8230;</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.twg.ca/2010/02/hump-day-whose-website-sucks-less/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Good clients make good design</title>
		<link>http://blog.twg.ca/2010/02/good-clients-make-good-design/</link>
		<comments>http://blog.twg.ca/2010/02/good-clients-make-good-design/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 15:24:33 +0000</pubDate>
		<dc:creator>Vivian</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[design process]]></category>
		<category><![CDATA[designer vs. client]]></category>

		<guid isPermaLink="false">http://blog.twg.ca/?p=479</guid>
		<description><![CDATA[I recently finished Chip Kidd&#8217;s The Learners, a beautiful novel set in a 1960&#8217;s ad agency. Kidd – the Brad Pitt of book designers – provides tons of graphic design gems in this book, inspiring nuggets like:
Kiddies, what makes good design is good clients. It&#8217;s as simple as that. Look at CBS–the eye. Genuis. But [...]]]></description>
			<content:encoded><![CDATA[<p>I recently finished Chip Kidd&#8217;s <a href="http://www.goodisdead.com/index.php?/the_learners/" target="new"><em>The Learners</em></a>, a beautiful novel set in a 1960&#8217;s ad agency. Kidd – the Brad Pitt of book designers – provides tons of graphic design gems in this book, inspiring nuggets like:</p>
<blockquote><p>Kiddies, what makes good design is good clients. It&#8217;s as simple as that. Look at CBS–the eye. Genuis. But Frank Stanton, the head of the network, deserves as much credit as Bill Golden, who actually designed it. If the sumvabitch paying the bills isn&#8217;t on your bus, you ain&#8217;t going anywhere. But if he really lets you drive, you can gun it to the moon.</p></blockquote>
<p>We definitely agree with the sentiment that credit for a great design can be mutually shared between the designer and the client (who has provided the designer with enough license to craft genius.) Unfortunately, unsuccessful designs are also created by both the designer and client. Articles dealing with <a href="http://articles.sitepoint.com/article/design-designers-clients" target="new">designers vs. clients</a> and the <a href="http://jjeffryes.blogspot.com/2007/10/process-message-is-design.html" target="new">design</a> <a href="http://www.webdesignerdepot.com/2009/03/5-things-your-clients-should-know/" target="new">process</a> with clients place the success of a project in the hands of a healthy client-designer relationship.</p>
<h2>Make the logo bigger? There are other possibilities.</h2>
<p>Because the relationship between client and designer is so critical to the success of a project, we&#8217;re continually trying to come up with better ways for these key players to interact. We need to be mindful of the time, investment and even prior experience that a client is putting into the project, while at the same time pushing that client to try and step back and let us do our thing.</p>
<p>It&#8217;s important for us to hear the business objectives and business problems directly from clients so we can understand the reason why they are seeking something new. At the same time, we can also look to read between the lines, and dig to find solutions that the client might not realize exist.</p>
<p>It is far more useful for us to hear a client&#8217;s perspective such as <em>&#8220;most of the customers who arrive on our home page don&#8217;t yet know us, and our brand is being lost on a page that is overwhelming them with content&#8221;</em> instead of <em>&#8220;make the logo <span style="color: #000000;"><strong>bigger</strong></span>&#8220;</em>. By stating their concern, we can provide solutions that may or may not include making the logo bigger (for example, brand presence can be increased through colour and pattern, typographic treatments, minimizing other distracting elements etc&#8230; not just making the logo bigger.) Sometimes these alternatives are better than the client&#8217;s self-diagnosed and self-prescribed treatment.</p>
<h2>How does a designer build this kind of trust in the client to step back and not rush to solutions?</h2>
<p>Confidence has to be one of the key motivators. Once a client feels secure that their design issues are going to be addressed in a thoughtful and intelligent way, they&#8217;re far more willing to let the process unfold. How do you inspire that kind of confidence? That&#8217;s the million dollar answer, and I don&#8217;t have it, yet. Proven experience, self-confidence, the ability to listen and give thoughtful feedback, a dazzling portfolio of staggering genius – maybe all of the above..?</p>
<p>We&#8217;ll keep working on it, and continue to tell our story. Communication is the key ingredient in arriving at a final product that everyone is proud of – something that fulfills business communication goals, has a rich user experience, and is visually stunning. So let&#8217;s get back to the drawing board.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.twg.ca/2010/02/good-clients-make-good-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Please welcome the newest TWGer: Todd Charron</title>
		<link>http://blog.twg.ca/2010/02/please-welcome-the-newest-twger-todd-charron/</link>
		<comments>http://blog.twg.ca/2010/02/please-welcome-the-newest-twger-todd-charron/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 16:17:01 +0000</pubDate>
		<dc:creator>Andrés</dc:creator>
				<category><![CDATA[TWG News]]></category>
		<category><![CDATA[Team]]></category>

		<guid isPermaLink="false">http://blog.twg.ca/?p=472</guid>
		<description><![CDATA[The entire TWG cast would like to formally welcome Todd Charron to the team. Todd joined TWG at the beginning of 2010, and has been pivotal in helping us evolve our Agile development practices and project management system.
As a Certified ScrumMaster, Todd is ideal in leading TWG&#8217;s formal transition from &#8220;Scrum-ish&#8221; to an actual Scrum [...]]]></description>
			<content:encoded><![CDATA[<p>The entire TWG cast would like to formally welcome <a href="http://twg.ca/about-us/our-team#todd">Todd Charron</a> to the team. Todd joined TWG at the beginning of 2010, and has been pivotal in helping us evolve our Agile development practices and project management system.</p>
<p>As a Certified ScrumMaster, Todd is ideal in leading TWG&#8217;s formal transition from &#8220;Scrum-ish&#8221; to an actual Scrum Agile Development process. Dom and I have always desired for our agile methodology to improve, but without the experience of scrum training we always seemed to stop short of ideal.</p>
<p>Todd has over 9-years of software development experience, and as a former lead developer, he has a terrific understanding of the dev team&#8217;s needs. We&#8217;re happy that Todd has decided to join us, and you can look forward to learning a lot more about Scrum, as Todd will be active in updating you on our Scrum-Evolution right here on this blog.</p>
<p>Welcome Todd, great to have you aboard!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.twg.ca/2010/02/please-welcome-the-newest-twger-todd-charron/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remember Rcov?</title>
		<link>http://blog.twg.ca/2009/12/remember-rcov/</link>
		<comments>http://blog.twg.ca/2009/12/remember-rcov/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 21:31:21 +0000</pubDate>
		<dc:creator>Oleg</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[rake task]]></category>
		<category><![CDATA[rcov]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://blog.twg.ca/?p=429</guid>
		<description><![CDATA[Rcov helps to identify code that is not being being hit by your tests (or maybe some functions left behind after refactoring). It&#8217;s very easy to get it running as well:
$ sudo gem install rcov
Plug this rake task into /lib/tasks/rcov.rake
require 'rcov/rcovtask'

namespace :rcov do
&#160; desc 'Measures test coverage using rcov'
&#160; Rcov::RcovTask.new&#40;:test&#41; do &#124;rcov&#124;
&#160; &#160; rcov.pattern &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>Rcov helps to identify code that is not being being hit by your tests (or maybe some functions left behind after refactoring). It&#8217;s very easy to get it running as well:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ sudo gem install rcov</div></div>
<p>Plug this rake task into /lib/tasks/rcov.rake</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rcov/rcovtask'</span><br />
<br />
namespace <span style="color:#ff3333; font-weight:bold;">:rcov</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; desc <span style="color:#996600;">'Measures test coverage using rcov'</span><br />
&nbsp; <span style="color:#6666ff; font-weight:bold;">Rcov::RcovTask</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:test</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>rcov<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; rcov.<span style="color:#9900CC;">pattern</span> &nbsp; &nbsp;= <span style="color:#006600; font-weight:bold;">%</span>w<span style="color:#006600; font-weight:bold;">&#40;</span>test<span style="color:#006600; font-weight:bold;">/</span>unit<span style="color:#006600; font-weight:bold;">/**/*</span>_test.<span style="color:#9900CC;">rb</span> test<span style="color:#006600; font-weight:bold;">/</span>functional<span style="color:#006600; font-weight:bold;">/**/*</span>_test.<span style="color:#9900CC;">rb</span> test<span style="color:#006600; font-weight:bold;">/</span>integration<span style="color:#006600; font-weight:bold;">/**/*</span>_test.<span style="color:#9900CC;">rb</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; rcov.<span style="color:#9900CC;">output_dir</span> = <span style="color:#996600;">'rcov'</span><br />
&nbsp; &nbsp; rcov.<span style="color:#9900CC;">verbose</span> &nbsp; &nbsp;= <span style="color:#0000FF; font-weight:bold;">true</span><br />
&nbsp; &nbsp; rcov.<span style="color:#9900CC;">rcov_opts</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">'--exclude &quot;gems/*&quot;'</span><br />
&nbsp; &nbsp; rcov.<span style="color:#9900CC;">rcov_opts</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">'--rails'</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>And finally run it:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ rake rcov:test</div></div>
<p>It&#8217;s so easy you have no excuse not to have it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.twg.ca/2009/12/remember-rcov/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Harnessing Ruby Enumerable</title>
		<link>http://blog.twg.ca/2009/12/harnessing-ruby-enumerable/</link>
		<comments>http://blog.twg.ca/2009/12/harnessing-ruby-enumerable/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 21:53:16 +0000</pubDate>
		<dc:creator>Scott Tadman</dc:creator>
				<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://blog.twg.ca/?p=381</guid>
		<description><![CDATA[You&#8217;re probably afraid to ask about some of the methods in the Ruby Enumerable mixin. Not only are there a whole bunch of them, 41 in Ruby 1.9 to be exact, but selecting the right one for the problem can be an exercise in frustration. Part of the problem is there&#8217;s no easy way to [...]]]></description>
			<content:encoded><![CDATA[<p>You&#8217;re probably afraid to ask about some of the methods in the Ruby Enumerable mixin. Not only are there a whole bunch of them, 41 in Ruby 1.9 to be exact, but selecting the right one for the problem can be an exercise in frustration. Part of the problem is there&#8217;s no easy way to identify what method might suit your requirements. While the names are usually self-explanatory, it can be tricky to remember block arguments or if they return an Array or a particular element.</p>
<p>Any toolbox needs to be organized, so it&#8217;s probably best to sort the various Enumerable methods into groups based on the kind of result you want to get. Grouped together like this, the methodology within Ruby becomes more apparent.</p>
<style> .enumerable th { font-weight: bold; padding-bottom: 5px; border-bottom: 1px solid #ccc;} .enumerable td { padding: 5px 0px 5px 0px; } .enumerable td.remark { padding: 0px 5px 20px 30px; } .enumerable .method, span.method { font-family: monospace; } .enumerable .optional { color: #999; font-style: italic; } .enumerable .clarify { color: #999; } </style>
<h2>Conventions</h2>
<p>In this description, &#8220;true / false&#8221; refers to values that are equivalent to true, or equivalent to false. In practical terms this means that <span class="method">nil</span> and <span class="method">false</span> are both considered false, and everything else is non-false, (or in general terms, true). Note: things that evaluate as true include what might be considered false in other languages such as 0, empty strings, and empty Array or Hash structures.</p>
<p>When describing the blocks, e refers to an element in the set. For an Array, this is simply the element at a particular index. For a Hash this is a key/value pair, so the block semantics should be expanded to <span class="method">{ |(k,v)| }</span> or <span class="method">e.first</span> and <span class="method">e.last</span> will need to be used within the block.</p>
<h2>Assessment</h2>
<p>One of the simplest features of Enumerable is the methods that provide a quick true/false assessment based on the content involved. Often these will be used to decide how to handle an Array or Hash, or if its in a condition that can be utilized.</p>
<table class="enumerable" border="0" width="100%">
<tbody>
<tr>
<th width="25%">Method</th>
<th width="20%">Arguments</th>
<th width="30%">Block Definition</th>
<th width="25%">Return</th>
</tr>
<tr>
<td class="method">all?</td>
<td></td>
<td><span class="method">{ |e| &#8230; } <span class="clarify">=&gt; true / false</span></span><br />
<span class="optional">* Optional</span></td>
<td><span class="method">true / false</span></td>
</tr>
<tr>
<td class="remark" colspan="4">Runs each element through the given block with and returns true if <strong>all</strong> of the block results evaluate true, otherwise false. Without a block returns true if all the elements evaluate as true, otherwise false.</td>
</tr>
<tr>
<td class="method">any?</td>
<td></td>
<td><span class="method">{ |e| &#8230; } <span class="clarify">=&gt; true / false</span></span><br />
<span class="optional">* Optional</span></td>
<td><span class="method">true / false</span></td>
</tr>
<tr>
<td class="remark" colspan="4">Runs each element through the given block with and returns true if <strong>any</strong> of the block results evaluate true, otherwise false. Without a block returns true if any the elements evaluate as true, otherwise false.</td>
</tr>
<tr>
<td class="method">none?</td>
<td></td>
<td><span class="method">{ |e| &#8230; } <span class="clarify">=&gt; true / false</span></span><br />
<span class="optional">* Optional</span></td>
<td><span class="method">true / false</span></td>
</tr>
<tr>
<td class="remark" colspan="4">Runs each element through the given block with and returns true if <strong>none</strong> of the block results evaluate true, otherwise false. Without a block returns true if none the elements evaluate as true, otherwise false.</td>
</tr>
<tr>
<td class="method">one?</td>
<td></td>
<td><span class="method">{ |e| &#8230; } <span class="clarify">=&gt; true / false</span></span><br />
<span class="optional">* Optional</span></td>
<td><span class="method">true / false</span></td>
</tr>
<tr>
<td class="remark" colspan="4">Runs each element through the given block with and returns true if <strong>one</strong> of the block results evaluate true, otherwise false. Without a block returns true if one the elements evaluate as true, otherwise false.</td>
</tr>
</tbody>
</table>
<h2>Single Element</h2>
<p>Often you&#8217;ll want to extract a single element from a set. In this case there are many ways to get what you want, each with their particular quirks.</p>
<table class="enumerable" border="0" width="100%">
<tbody>
<tr>
<th width="25%">Method</th>
<th width="20%">Arguments</th>
<th width="30%">Block Definition</th>
<th width="25%">Return</th>
</tr>
<tr>
<td class="method">detect</td>
<td class="method">ifnone <span class="clarify">= nil</span></td>
<td><span class="method">{ |e| &#8230; } <span class="clarify">=&gt; true / false</span></span></td>
<td><span class="method"><em>element</em> / nil</span></td>
</tr>
<tr>
<td class="remark" colspan="4">Runs each element through the given block with and returns the first element for which the block result is true. If all return false, the result is nil.</td>
</tr>
<tr>
<td class="method">find</td>
<td class="method">ifnone <span class="clarify">= nil</span></td>
<td><span class="method">{ |e| &#8230; } <span class="clarify">=&gt; true / false</span></span></td>
<td><span class="method"><em>element</em> / nil</span></td>
</tr>
<tr>
<td class="remark" colspan="4">The same as <span class="method">detect</span>, this runs each element through the given block with and returns the first element for which the block result is true. If all return false, the result is nil.</td>
</tr>
<tr>
<td class="method">first</td>
<td class="method"></td>
<td></td>
<td><span class="method"><em>element</em> / nil</span></td>
</tr>
<tr>
<td class="remark" colspan="4">Returns the first element in the set, of if the set is empty then nil.</td>
</tr>
<tr>
<td class="method">max</td>
<td></td>
<td><span class="method">{ |a,b| &#8230; } <span class="clarify">=&gt; -1 / 0 / 1</span></span><br />
<span class="optional">* Optional</span></td>
<td><span class="method"><em>element</em> / nil</span></td>
</tr>
<tr>
<td class="remark" colspan="4">Returns the largest element in the set, of if the set is empty then nil. The result of the optional block should be compatible with Comparable and return -1, 0, or 1.</td>
</tr>
<tr>
<td class="method">max_by</td>
<td></td>
<td><span class="method">{ |e| &#8230; }</span></td>
<td><span class="method"><em>element</em> / nil</span></td>
</tr>
<tr>
<td class="remark" colspan="4">Returns the largest element in the set where comparisons are performed on the result of the block, of if the set is empty then nil. Anything returned by the block must be compatible with Comparable.</td>
</tr>
<tr>
<td class="method">min</td>
<td></td>
<td><span class="method">{ |a,b| &#8230; } <span class="clarify">=&gt; -1 / 0 / 1</span></span><br />
<span class="optional">* Optional</span></td>
<td><span class="method"><em>element</em> / nil</span></td>
</tr>
<tr>
<td class="remark" colspan="4">Returns the smallest element in the set, of if the set is empty then nil. The result of the optional block should be compatible with Comparable and return -1, 0, or 1.</td>
</tr>
<tr>
<td class="method">min_by</td>
<td></td>
<td><span class="method">{ |e| &#8230; }</span></td>
<td><span class="method"><em>element</em> / nil</span></td>
</tr>
<tr>
<td class="remark" colspan="4">Returns the smallest element in the set where comparisons are performed on the result of the block, of if the set is empty then nil. Anything returned by the block must be compatible with Comparable.</td>
</tr>
</tbody>
</table>
<h2>Filtering</h2>
<table class="enumerable" border="0" width="100%">
<tbody>
<tr>
<th width="25%">Method</th>
<th width="20%">Arguments</th>
<th width="30%">Block Definition</th>
<th width="25%">Return</th>
</tr>
<tr>
<td class="method">grep</td>
<td class="method">regexp</td>
<td><span class="method">{ |e| &#8230; }</span><br />
<span class="optional">* Optional</span></td>
<td><span class="method">Array</span></td>
</tr>
<tr>
<td class="remark" colspan="4">Matches each element against the supplied regexp and returns all that match in an Array. If a block is supplied, all matching elements are transformed by the block before being inserted into the result Array, which avoids having to chain the result through a <span class="method">map</span> call.</td>
</tr>
<tr>
<td class="method">reject</td>
<td class="method"></td>
<td><span class="method">{ |e| &#8230; } <span class="clarify">=&gt; true / false</span></span></td>
<td><span class="method">Array</span></td>
</tr>
<tr>
<td class="remark" colspan="4">Runs all elements through the supplied block and excludes those from the result array where the block evaluates as true.</td>
</tr>
<tr>
<td class="method">select</td>
<td class="method"></td>
<td><span class="method">{ |e| &#8230; } <span class="clarify">=&gt; true / false</span></span></td>
<td><span class="method">Array</span></td>
</tr>
<tr>
<td class="remark" colspan="4">The inverse of , this runs all elements through the supplied block and includes those from the result array where the block evaluates as true.</td>
</tr>
<tr>
<td class="method">select</td>
<td class="method"></td>
<td><span class="method">{ |e| &#8230; } <span class="clarify">=&gt; true / false</span></span></td>
<td><span class="method">Array</span></td>
</tr>
<tr>
<td class="remark" colspan="4">The inverse of , this runs all elements through the supplied block and includes those from the result array where the block evaluates as true.</td>
</tr>
</tbody>
</table>
<h2>Transformation</h2>
<p>There are a few powerful methods for transforming the content of one set into an Array.</p>
<table class="enumerable" border="0" width="100%">
<tbody>
<tr>
<th width="25%">Method</th>
<th width="20%">Arguments</th>
<th width="30%">Block Definition</th>
<th width="25%">Return</th>
</tr>
<tr>
<td class="method">collect</td>
<td class="method"></td>
<td><span class="method">{ |e| &#8230; }</span></td>
<td><span class="method">Array</span></td>
</tr>
<tr>
<td class="remark" colspan="4">Runs each element through the provided block and puts each block result in the Array that is returned.</td>
</tr>
<tr>
<td class="method">map</td>
<td class="method"></td>
<td><span class="method">{ |e| &#8230; }</span></td>
<td><span class="method">Array</span></td>
</tr>
<tr>
<td class="remark" colspan="4">The same as <span class="method">collect</span>, runs each element through the provided block and puts each block result in the Array that is returned.</td>
</tr>
<tr>
<td class="method">inject</td>
<td class="method">memo <span class="clarify">= first</span></td>
<td><span class="method">{ |memo, e| &#8230; }</span></td>
<td><span class="method"><em>last block result</em> / nil</span></td>
</tr>
<tr>
<td class="remark" colspan="4">This is perhaps the most understood and under-utilized method in the Enumerable toolkit. In general terms, this method takes a seed &#8220;memo&#8221; value, and runs that through the block in conjunction with each element. The result of the first block call is supplied to the second, and so on, which leaves the door wide open as to what this method can do. For instance, every other Enumerable method can be expressed as a form of <span class="method">inject</span>.</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://blog.twg.ca/2009/12/harnessing-ruby-enumerable/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Active state for link_to == active_link_to. A solution for building navigation systems in Rails.</title>
		<link>http://blog.twg.ca/2009/11/active-state-for-link_to-active_link_to/</link>
		<comments>http://blog.twg.ca/2009/11/active-state-for-link_to-active_link_to/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 18:07:45 +0000</pubDate>
		<dc:creator>Oleg</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[active state]]></category>
		<category><![CDATA[active_link]]></category>
		<category><![CDATA[active_link_to]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[navigation]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://blog.twg.ca/?p=346</guid>
		<description><![CDATA[I have a question for you. How do you deal with the logic of setting links as active in your navs?
Actually, I don&#8217;t want to know. It&#8217;s probably awful. I might have a pretty good solution for you. Let&#8217;s take a look at a very simple nav. These examples all use HAML:
%ul
&#160; %li= link_to 'Home', [...]]]></description>
			<content:encoded><![CDATA[<p>I have a question for you. How do you deal with the logic of setting links as active in your navs?</p>
<p>Actually, I don&#8217;t want to know. It&#8217;s probably awful. I might have a pretty good solution for you. Let&#8217;s take a look at a very simple nav. These examples all use <a href="http://haml-lang.com/">HAML</a>:</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#006600; font-weight:bold;">%</span>ul<br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= link_to <span style="color:#996600;">'Home'</span>, home_path<br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= link_to <span style="color:#996600;">'Puppies'</span>, puppies_path<br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= link_to <span style="color:#996600;">'Kittens'</span>, kittens_path<br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= link_to <span style="color:#996600;">'Froggies'</span>, froggies_path</div></div>
<p>Right, that&#8217;s great. But how do I insert logic as to what link gets marked as active? To begin, let&#8217;s quickly install this random gem:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">sudo</span> gem <span style="color: #c20cb9; font-weight: bold;">install</span> active_link_to</div></div>
<p>And then change our nav a bit:</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#006600; font-weight:bold;">%</span>ul<br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= active_link_to <span style="color:#996600;">'Home'</span>, home_path<br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= active_link_to <span style="color:#996600;">'Puppies'</span>, puppies_path<br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= active_link_to <span style="color:#996600;">'Kittens'</span>, kittens_path<br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= active_link_to <span style="color:#996600;">'Froggies'</span>, froggies_path</div></div>
<p>And that&#8217;s pretty much it.</p>
<p>So, for example, if you navigate to /kittens/1-my-fluffy-kitten navigation link for &#8216;Kittens&#8217; will have &#8216;active&#8217; class attached to it. It&#8217;s almost like magic.</p>
<p>You probably noticed that &#8216;Home&#8217; is highlighted as well. It happened because whatever URL you are currently on is a child of the home_path. I guess we want to mark it as active only if we find ourselves on the home page and not anywhere else. We can fix this:</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#006600; font-weight:bold;">%</span>ul<br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= active_link_to <span style="color:#996600;">'Home'</span>, home_path, <span style="color:#ff3333; font-weight:bold;">:active</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:<span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:self_only</span><span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= active_link_to <span style="color:#996600;">'Puppies'</span>, puppies_path<br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= active_link_to <span style="color:#996600;">'Kittens'</span>, kittens_path<br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= active_link_to <span style="color:#996600;">'Froggies'</span>, froggies_path</div></div>
<p>Hey, wanna render a sub nav when you find yourself browsing /puppies or any page under that URL? It&#8217;s just sooo easy:</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#006600; font-weight:bold;">%</span>ul<br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= active_link_to <span style="color:#996600;">'Home'</span>, home_path, <span style="color:#ff3333; font-weight:bold;">:active</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:<span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:self_only</span><span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li<br />
&nbsp; &nbsp; = active_link_to <span style="color:#996600;">'Puppies'</span>, puppies_path<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#9966CC; font-weight:bold;">if</span> is_active_link?<span style="color:#006600; font-weight:bold;">&#40;</span>puppies_path<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">%</span>ul<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= active_link_to <span style="color:#996600;">'Big'</span>, big_puppies_path<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= active_link_to <span style="color:#996600;">'Small'</span>, small_puppies_path<br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= active_link_to <span style="color:#996600;">'Kittens'</span>, kittens_path<br />
&nbsp; <span style="color:#006600; font-weight:bold;">%</span>li= active_link_to <span style="color:#996600;">'Froggies'</span>, froggies_path</div></div>
<p>And that&#8217;s the skinny of what active_link_to is for.</p>
<p>For more documentation on more functionality checkout project on GitHub: <a href="http://github.com/theworkinggroup/active_link_to">http://github.com/theworkinggroup/active_link_to</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.twg.ca/2009/11/active-state-for-link_to-active_link_to/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making a world of difference with 0.05em</title>
		<link>http://blog.twg.ca/2009/11/making-a-world-of-difference-with-0-05em/</link>
		<comments>http://blog.twg.ca/2009/11/making-a-world-of-difference-with-0-05em/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 18:28:09 +0000</pubDate>
		<dc:creator>Vivian</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Typography]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[designer vs. developer]]></category>
		<category><![CDATA[letter-spacing]]></category>

		<guid isPermaLink="false">http://blog.twg.ca/?p=298</guid>
		<description><![CDATA[Typographic sensibility can make or break a design, both in print pieces and online. In web design, attention to typography is especially important since the majority of online content is written information. It is often said that the strength of a web designer can be judged through their ability to create an engaging UI with [...]]]></description>
			<content:encoded><![CDATA[<p>Typographic sensibility can make or break a design, both in print pieces and online. In web design, attention to typography is especially important since the majority of online content is <a href="http://informationarchitects.jp/the-web-is-all-about-typography-period/" target="new">written information.</a> It is often said that the strength of a web designer can be judged through their ability to create an engaging UI with just text.</p>
<p>There are many tools and tricks available to web designers when it comes to styling type: <a href="http://www.kyleschaeffer.com/best-practices/css-font-size-em-vs-px-vs-pt-vs/" target="new">size</a>, <a href="http://kuler.adobe.com/" target="new">colour</a>, <a href="http://en.wikipedia.org/wiki/Typographic_alignment" target="new">alignment</a>, <a href="http://www.dev-archive.net/articles/line-height.html" target="new">line-height</a> (leading), <a href="http://webdesign.about.com/od/examples/l/blstyleswordspacingexamples.htm" target="new">word-spacing</a> (don&#8217;t do it), but an important one I find most often ignored by developers is <a href="http://en.wikipedia.org/wiki/Letter-spacing" target="new">letter-spacing</a> (tracking). Letter-spacing is literally the space between the letters&#8230; and it can make a big difference in terms of legibility and the overall feel of a site.</p>
<p><img src="http://blog.twg.ca/wp-content/uploads/2009/10/letter-spacing-importance2.jpg" alt="letter-spacing-importance" title="letter-spacing-importance" width="552" height="170" class="alignleft size-full wp-image-340" /></p>
<h2>&#8220;Don’t blame me; you forgot the letter-spacing&#8230;&#8221;</h2>
<p>As a designer, it feels like I am often getting flack from developers for type that is &#8220;too small&#8221;. Ninety-nine percent of the time after I hand off an Illustrator file or PSD of a design, the coded page comes back to me without any letter-spacing included in the CSS. Letter-spacing is like air: you don&#8217;t really notice it, but it makes a difference whether it is there or not. </p>
<h2>It’s easy, just do it.</h2>
<p>I&#8217;m really bad at math, but the other day it dawned on me how to figure out the CSS letter-spacing measurement from my AI (or PSD) file. Tracking in Adobe programs is measured in 1/1000em so when the design file specifies &#8220;50&#8243; or &#8220;100&#8243; in the tracking character palette, it is 100/1000 = 0.1em. That 0.1em can take a 10px all caps style from &#8220;too small&#8221; to &#8220;completely awesome&#8221;. See below:</p>
<p style="letter-spacing:0em; font-size:10px; color: #70BC1F">EXAMPLE WITHOUT ANY LETTER-SPACING, OMG SO TIGHT, NOT IN A GOOD/SEXY WAY.</p>
<p style="letter-spacing:0.1em; font-size:10px; color: #70BC1F">ADDED 0.1EM OF LETTER-SPACING. LOOK HOW AMAZING IT IS NOW.</p>
<p style="letter-spacing:2px; font-size:10px; color: #70BC1F">2PX OF LETTER-SPACING? CRAZYTOWN! GET THE EFF OUT OF HERE!</p>
<h2>Of course there are issues&#8230;</h2>
<p>Like in many cases, basically Firefox is the only browser that <a href="http://blarg.aaronpropst.com/IE-CSS-does-letter-spacing-stupidly" target="new">does</a> <a href="http://vhg-design.com/blog/tag/letter-spacing/" target="new">letter-spacing</a> <a href="http://www.sitepoint.com/forums/showthread.php?p=4203006" target="new">right</a>. Depending on your product/audience, this may not be an issue, but it is definitely something to keep in mind when specifying sub-pixel measurements that may be rounded up or down in browsers other than Firefox.</p>
<h2>Negative letter-spacing: it’s just a fad, right?</h2>
<p style="letter-spacing:-0.1em; font-size:30px; color: #B3B3B3; font-family:helvetica, arial;">This is so tight, yo! I can’t even read it!</p>
<p>Over the last couple years a big web typography trend has been the bold sans type with negative letter-spacing, <a href="http://css-tricks.com/helvetica-bold-big-negative-letter-spacing/" target="new">&#8220;all the cool kids are doing it.&#8221;</a> While I can see the appeal (in that it speaks to the whole web 2.0 design aesthetic), I expect that this trend will soon remedy itself. Letter-spacing is meant to be applied with a gentle touch, and when heavy-handed negative (or positive) tracking occurs, it can definitely affect the legibility, as some of those examples clearly show. </p>
<h2>The bottom line</h2>
<p>Always use letter-spacing to your advantage and not to your own detriment, just  because it’s &#8220;in&#8221;. Yell at developers when they omit it from the CSS and then decide to blame you, the designer. And if that doesn’t work, do what I had to do: get the keys to the site or app, then tweak to your heart’s content.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.twg.ca/2009/11/making-a-world-of-difference-with-0-05em/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>geeks + beer + friday = ?</title>
		<link>http://blog.twg.ca/2009/10/geeks-beer-friday/</link>
		<comments>http://blog.twg.ca/2009/10/geeks-beer-friday/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 21:50:28 +0000</pubDate>
		<dc:creator>Georges</dc:creator>
				<category><![CDATA[Friday]]></category>
		<category><![CDATA[Team]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[beer]]></category>
		<category><![CDATA[geeks]]></category>
		<category><![CDATA[vi]]></category>

		<guid isPermaLink="false">http://blog.twg.ca/?p=291</guid>
		<description><![CDATA[Every so often a text editor war will flare up in the office. We all have our favourites, but no one likes vi the way Scott likes vi.
Here&#8217;s the first in Dr. Tadman&#8217;s twelve part lecture series on how vi will make your life better:

Click For Full-Size Image
]]></description>
			<content:encoded><![CDATA[<p>Every so often a text editor war will flare up in the office. We all have our favourites, but no one likes vi the way <a href="http://theworkinggroup.ca/about-us/our-team#scott">Scott</a> likes vi.</p>
<p>Here&#8217;s the first in <a href="http://theworkinggroup.ca/about-us/our-team#scott">Dr. Tadman</a>&#8217;s twelve part lecture series on how vi will make your life better:</p>
<p style="text-align: center;"><a href="http://blog.twg.ca/wp-content/uploads/2009/10/TWGtadman-viforbeginners.jpg"><img class="size-full wp-image-292 aligncenter" title="TWGtadman-viforbeginners_thumb" src="http://blog.twg.ca/wp-content/uploads/2009/10/TWGtadman-viforbeginners_thumb.jpg" alt="TWGtadman-viforbeginners_thumb" width="640" height="200" /></a></p>
<p style="text-align: center;"><a href="http://blog.twg.ca/wp-content/uploads/2009/10/TWGtadman-viforbeginners.jpg">Click For Full-Size Image</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.twg.ca/2009/10/geeks-beer-friday/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rails mass mailing &#8211; it shouldn&#8217;t be this complicated</title>
		<link>http://blog.twg.ca/2009/09/rails-mass-mailing-it-shouldnt-be-this-complicated/</link>
		<comments>http://blog.twg.ca/2009/09/rails-mass-mailing-it-shouldnt-be-this-complicated/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 21:16:32 +0000</pubDate>
		<dc:creator>Jack</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[ar_mailer]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[posategapp]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://blog.theworkinggroup.ca/?p=57</guid>
		<description><![CDATA[The requests we get from our clients for &#8220;social networking&#8221; type tools and features has grown exponentially over the past two years. To make a user experience relevant, easy, secure, means that an application will need to send email notifications to that user (to register, to tell them of friend&#8217;s messages, to send them newsletters [...]]]></description>
			<content:encoded><![CDATA[<p>The requests we get from our clients for &#8220;<em>social networking</em>&#8221; type tools and features has grown exponentially over the past two years. To make a user experience relevant, easy, secure, means that an application will need to send email notifications to that user (to register, to tell them of friend&#8217;s messages, to send them newsletters or updates, to send tickets, calendar bookings .. the list goes on).<br />
<strong><br />
Why is this a problem?</strong> Because sending an email is not an instantaneous action. The more emails you try to send, the longer you may have to wait as the application sends them. Imagine an app that lets you invite 300 friends to an event. Multiply this with 300 people sending the same invite to their friends.</p>
<p>While Rails was kind enough to provide a simple way to send emails, it left out one important detail. <em>You can only send one at a time!</em></p>
<p>If you find yourself in the unfortunate position where you need to mass mail then you&#8217;re on your own. So what do you do? You Google around of course. Someone is bound to have figured this one out.</p>
<p><strong>It looks like there are 3 ways to solve this:</strong></p>
<p><strong>1. Use existing email marketing services</strong></p>
<p>You can go with this option. There are plenty out there: Mail Chimp, Constant Contact, Thin Data, Campaign Monitor, Campaigner and others. All you need to do is generate some kind of mailing list and import it into one of these systems and then keep it up to date. But that&#8217;s not always practical. Not if you want your users to be able to initiate the mass mailing by themselves.  Don&#8217;t get me wrong, these services are great at what they do, but what we really want to do is to send mass emails from our own app.</p>
<p><strong>2. Use existing code</strong></p>
<p>If you really want your Rails app to be able to send mass mails at a click of a button you can try using Eric Hodel&#8217;s ar_mailer which is on version 1.4.0 as of June 2009. This has the advantage of letting you use the email addresses that you already have on your system (no exporting and importing to a different system) but before you get to that you still have to integrate it with whatever version of Rails you happen to be using.  Assuming you get it working properly, now you have a brand new background process to take care of.</p>
<p>Ar_mailer is great but leaves you half way there.</p>
<p>* The queue is not smart enough to prioritize emails. If one user sends 5000 invitations and after that another user wants to recover his password, he&#8217;ll have to wait until all 5000 emails are sent before he gets his password back. The users receiving the invitation won&#8217;t notice if  it takes a bit longer to reach them, but the guy that is trying to recover his password will be upset if he doesn&#8217;t get it right away. This is obviously not good enough.<br />
* How do you monitor if an email has been sent or failed?<br />
* If you have an email template and your client wants to change it all the time, what do you do?</p>
<p><strong>3. Build it all from scratch</strong></p>
<p>Even if you decide to do it yourself from scratch you&#8217;ll still need a queue to store the emails that will be sent at some time in the near future by another process running in the background. From there on, it depends on what you really need. Be prepared to put aside some extra time because it ain&#8217;t simple.</p>
<p><strong>So what would be the perfect solution? </strong>Simply put: I don&#8217;t want to have to worry about it. I want to be able to say: &#8220;Here&#8217;s my email, here&#8217;s the list of people I want it sent to. Go and do it &#8230; please&#8221;.</p>
<p>Wouldn&#8217;t that be great? Sure it would! We&#8217;ve encountered this problem enough times to make us want to solve it for good.</p>
<p><strong>And so we&#8217;ve set out to build it and this is what we think a mass mailing solution:</strong></p>
<ol>
<li>I want to be able to use it independently of the language I&#8217;m coding in &#8211; it needs to have an API</li>
<li>I want to be able to use the same code I have right now (layouts, email templates, etc.) &#8211; it needs to integrate easily</li>
<li>I want to know if a specific email was sent, failed or if it hasn&#8217;t been sent yet and I want to know why &#8211; it needs reporting</li>
<li>If a client complains that the emails aren&#8217;t rendering correctly I want to be able to see what they are receiving &#8211; it needs to let me look at the emails sent</li>
<li>I want to be able to easily resend any email &#8211; it needs to let me act on it</li>
<li>I want to create and manage email templates so that my client can edit them without asking me every time and without forcing me to change the code and to deploy my app all over again &#8211; it needs an optional template management system.</li>
<li>I want the queue system to be smart enough to distinguish between a single email and a batch of 5000 emails and prioritize them accordingly &#8211; it needs a smart queue system.</li>
<li>And most importantly, how can all of this be done with minimal effort to set it up each time I create a new app. &#8211; it needs a plugin.</li>
</ol>
<p><strong>Postage App!</strong></p>
<p style="text-align: center;"><img class="size-full wp-image-204 aligncenter" title="Mass mailing app" src="http://theworkinggroup.ca/system/files/19/original/postageapp-mailing-diagram.jpg" alt="Mass mailing app" width="525" height="300" /></p>
<p>We are currently developing this system which will help us build better apps. We&#8217;re building it according to our needs and we think that these might also be the needs of other developers out there. <a href="http://postageapp.com/" target="_blank">Check it out and sign up</a> for an update on the developer free release!</p>
<p style="text-align: center;"><img src="file:///Users/jneto/Library/Caches/TemporaryItems/moz-screenshot.png" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.twg.ca/2009/09/rails-mass-mailing-it-shouldnt-be-this-complicated/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
