<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
	<channel>
		<title>Viget.com Blogs</title>
		<link>http://viget.com/</link>
		<language>en</language>
		<dc:rights>Copyright 2013</dc:rights>
		<pubDate>Fri, 17 May 2013 21:01:06 GMT</pubDate>
		<admin:generatorAgent rdf:resource="http://expressionengine.com/" />

		
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/VigetExtend" /><feedburner:info uri="vigetextend" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
				<title>The Neo Fallacy: How Our Mental Model of Developers Leads to Bad Bug Reports</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/TYByyaGwCSM/the-neo-fallacy-why-bug-reports-should-include-steps-to-reproduce</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/the-neo-fallacy-why-bug-reports-should-include-steps-to-reproduce#When:14:28</guid>
				
				<pubDate>Fri, 10 May 2013 14:28 GMT</pubDate>
				<dc:creator>Josh Korr</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;
	In two &lt;a href="http://viget.com/extend/tips-for-writing-better-bug-reports" target="_blank"&gt;previous&lt;/a&gt; &lt;a href="http://viget.com/inspire/what-a-car-rental-taught-me-about-ui-conventions-and-bug-reports" target="_blank"&gt;posts&lt;/a&gt; about writing better bug reports, I&amp;#39;ve detailed the information developers need to be able to reproduce &amp;mdash; and hence diagnose and fix &amp;mdash; bugs. Since then, an unstated assumption in both posts has been nagging at me: that developers must be able to reproduce a bug in order to diagnose and fix it.&lt;/p&gt;
&lt;p&gt;
	To a developer, this is not an assumption &amp;mdash; it&amp;#39;s truth, and obvious. But to non-developers, the necessity of reproducibility is not obvious. If it were, devs wouldn&amp;#39;t see so many bug reports that say little more than "A vague thing vaguely happened &amp;mdash; fix it!!!"&lt;/p&gt;
&lt;p&gt;
	I think this disconnect is the primary cause of frustrating-to-devs bug reports. If we can better understand the reason for the disconnect, maybe it&amp;#39;ll be easier to convince non-devs of the necessity of reproducibility.&amp;nbsp;&lt;/p&gt;

						&lt;p&gt;
	So what causes this disconnect? Here&amp;#39;s my theory:&lt;/p&gt;
&lt;p&gt;
	I believe that most non-developers think developers are like Neo in &lt;em&gt;The Matrix&lt;/em&gt;: that devs can see all parts of an app simultaneously at all times, like Neo&amp;#39;s &lt;a href="http://theathleticnerd.com/wp-content/uploads/2011/08/matrix-code-agents-ending.gif" target="_blank"&gt;living-ASCII-art view&lt;/a&gt; of the Matrix itself.&amp;nbsp;That devs are omniscient, omnipotent beings in regard to an app. I&amp;#39;ve come to think of this mental model as the Neo Fallacy.&lt;/p&gt;
&lt;p&gt;
	If pressed, I don&amp;#39;t think we could say &lt;em&gt;how&lt;/em&gt; we think developers do this. (Optic fiber running from servers to devs&amp;#39; brain stems? Magic emanating from the bowels of 4chan? Google Glass?) But I can&amp;#39;t think of a better explanation for why so many of us assume devs can figure out a bug from so little information.&lt;/p&gt;
&lt;p&gt;
	Returning to theory No. 1, I asked some Viget developers why reproducibility is so important. Some of their answers:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		"So we can hopefully write a failing test first, and then have one in place to prevent future regressions"&lt;/li&gt;
	&lt;li&gt;
		"To confirm it&amp;#39;s an actual bug"&lt;/li&gt;
	&lt;li&gt;
		"To know when we&amp;#39;ve fixed it"&lt;/li&gt;
	&lt;li&gt;
		"To be able to investigate the issue deeply"&lt;/li&gt;
	&lt;li&gt;
		"So we don&amp;#39;t waste our super valuable time"&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	All make sense. But those answers are beside the point to someone operating under the Neo Fallacy: "Fine, but why do you need to reproduce the bug to achieve all those things? Can&amp;#39;t you just &amp;#39;see&amp;#39; what&amp;#39;s happening?"&lt;/p&gt;
&lt;p&gt;
	Here&amp;#39;s an answer that I hope helps reframe the way we think about developers:&lt;/p&gt;
&lt;p&gt;
	Developers are not Neo. Yes, they have superpowers when it comes to writing code. But they&amp;#39;re mere mortals when it comes to knowing what&amp;#39;s happening in an app in real time. They&amp;#39;re not omniscient.&lt;/p&gt;
&lt;p&gt;
	Occasionally, they may be able to quickly ascertain a problem based on an intuitive sense of an app&amp;#39;s behavior and an auto-generated error report from &lt;a href="https://airbrake.io/pages/home" target="_blank"&gt;Airbrake&lt;/a&gt;. But most of the time, a context-free, vague bug report will mean no more to a developer than it would to you. Literally: without the details I outlined in my other posts &amp;mdash; URLs, login creds, specific steps &amp;mdash; you might as well submit the bug report to yourself.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	And having to spend time trying to glean meaning from such a vague report? For devs, that&amp;#39;s about as fun as hanging out with &lt;a href="http://photos.imageevent.com/afap/wallpapers/thematrix//Matrix_Reloaded15.jpg" target="_blank"&gt;these guys&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/TYByyaGwCSM" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/the-neo-fallacy-why-bug-reports-should-include-steps-to-reproduce#When:14:28</feedburner:origLink></item>
		
			<item>
				<title>Simplify your build-out process using Layouts with Views</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/5XNzSp5R2SI/simplifying-buildout-for-layouts-with-views</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/simplifying-buildout-for-layouts-with-views#When:15:16</guid>
				
				<pubDate>Fri, 03 May 2013 15:16 GMT</pubDate>
				<dc:creator>Tommy Marshall</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;
	I recently found myself building out a comp which seemed to have only enough code repetition to include a header and footer. However, the further I got into build-out the more code repetition emerged. I saw an opportunity for a MVC-like views system to help, so I set out to build one to make my build-out process easier.&lt;/p&gt;

						&lt;h3&gt;
	Code Examples&lt;/h3&gt;
&lt;p&gt;
	Let&amp;#39;s say you have a basic layout with a reusable header and footer, like the one in the example below.&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;
&amp;lt;!-- location: views/layouts/default.php --&amp;gt;&amp;#10;&amp;lt;html lang="en"&amp;gt;&amp;#10;&amp;lt;head&amp;gt;&amp;#10;    &amp;lt;title&amp;gt;Example Layout&amp;lt;/title&amp;gt;&amp;#10;&amp;lt;/head&amp;gt;&amp;#10;&amp;lt;body&amp;gt;&amp;#10;&amp;#10;    &amp;lt;header&amp;gt;&amp;#10;        &amp;lt;?php $this-&amp;gt;render(&amp;#39;shared/header&amp;#39;); ?&amp;gt;&amp;#10;    &amp;lt;/header&amp;gt;&amp;#10;&amp;#10;    &amp;lt;div class="content"&amp;gt;&amp;#10;        &amp;lt;?php $this-&amp;gt;getContent(); ?&amp;gt;&amp;#10;    &amp;lt;/div&amp;gt;&amp;#10;&amp;#10;    &amp;lt;footer&amp;gt;&amp;#10;        &amp;lt;?php $this-&amp;gt;render(&amp;#39;shared/footer&amp;#39;); ?&amp;gt;&amp;#10;    &amp;lt;/footer&amp;gt;&amp;#10;&amp;#10;&amp;lt;/body&amp;gt;&amp;#10;&amp;lt;/html&amp;gt;&lt;/pre&gt;
&lt;div&gt;
	This default layout is rendering a header and footer file located in the &lt;strong&gt;views/shared/&lt;/strong&gt; directory. Now, if we wanted to create an About page&amp;nbsp;with some content that uses this default layout, we would do something like this:&lt;/div&gt;
&lt;pre&gt;
&amp;lt;!-- location: views/about.php --&amp;gt;&amp;#10;&amp;lt;?php $this-&amp;gt;layout(&amp;#39;default&amp;#39;); ?&amp;gt;&amp;#10;&amp;#10;&amp;lt;h2&amp;gt;About Page&amp;lt;/h2&amp;gt;&amp;#10;&amp;#10;&amp;lt;p&amp;gt;Lorem ipsum dolor copy.&amp;lt;/p&amp;gt;&lt;/pre&gt;
&lt;p&gt;
	If we opened domain.com/about in the browser, we would see the About page content loaded within the default layout we created above. (Note: In the above example we could lose the layout declaration at the top since Layouts with Views expects to load &lt;strong&gt;default.php&lt;/strong&gt;&amp;nbsp;as the default layout. This setting can be changed in &lt;strong&gt;settings/config.php&lt;/strong&gt;.)&lt;/p&gt;
&lt;p&gt;
	The above example shows a basic application of&amp;nbsp;&lt;a href="http://tommymarshall.github.io/layouts-with-views"&gt;Layouts with Views&lt;/a&gt;. Check out the &lt;a href="http://tommymarshall.github.io/layouts-with-views"&gt;Github page&lt;/a&gt;&amp;nbsp;for examples of features like:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Multiple layouts&lt;/li&gt;
	&lt;li&gt;
		Nested views&lt;/li&gt;
	&lt;li&gt;
		Passing variables to views&lt;/li&gt;
	&lt;li&gt;
		Allow for common control structures (if, foreach, etc.)&lt;/li&gt;
	&lt;li&gt;
		Referencing page assets (images, stylesheets) using an absolute path&lt;/li&gt;
	&lt;li&gt;
		Simple routing (Create the file, done)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
	Download&lt;/h3&gt;
&lt;pre&gt;
git clone git@github.com:tommymarshall/layouts-with-views.git &lt;/pre&gt;
&lt;div&gt;
	.. or &lt;a href="http://tommymarshall.github.io/layouts-with-views/archive/master.zip"&gt;click here&lt;/a&gt; to download a zip.&lt;/div&gt;
&lt;h3&gt;
	In Conclusion&lt;/h3&gt;
&lt;p&gt;
	&lt;a href="http://tommymarshall.github.io/layouts-with-views"&gt;Layouts with Views&lt;/a&gt; sets out to solve a small problem and that&amp;#39;s it. There&amp;#39;s no customizable routing, no crazy templating features, no unusal syntax to learn. It&amp;rsquo;s just a simple way for me to build out comps. That&amp;#39;s what I like about it.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/5XNzSp5R2SI" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/simplifying-buildout-for-layouts-with-views#When:15:16</feedburner:origLink></item>
		
			<item>
				<title>JavaScript Execution Patterns for Non-Web Apps</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/dz906nSde6M/javascript-execution-patterns-for-non-web-apps</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/javascript-execution-patterns-for-non-web-apps#When:13:29</guid>
				
				<pubDate>Tue, 30 Apr 2013 13:29 GMT</pubDate>
				<dc:creator>Trevor Davis</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;
	A big challege with sites utilizing JavaScript is determining which JS should be executed on each page. Here are some approaches to doing this, along with my preferred method. While libraries like &lt;a href="http://backbonejs.org/"&gt;Backbone&lt;/a&gt; and &lt;a href="http://emberjs.com/"&gt;Ember&lt;/a&gt;&amp;nbsp;have ways of executing JavaScript, this article will mainly focus on executing JavaScript for &lt;strong&gt;web sites, not web apps&lt;/strong&gt;. So I&amp;#39;m talking about more marketing style sites instead of applications. An example would be this very site versus something like Gmail.&lt;/p&gt;

						&lt;p&gt;
	For these examples, I&amp;#39;m assuming the following:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		jQuery is being used on the site&lt;/li&gt;
	&lt;li&gt;
		All of the JS for the site is concatenated into a single file and loaded on every page.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
	Everything in document.ready&lt;/h2&gt;
&lt;p&gt;
	Before I go into preferred methods, I figured that it makes sense to talk about what you shouldn&amp;#39;t do. This is how I used to do it when I first learned how to use jQuery, and I still see some people doing this today.&lt;/p&gt;
&lt;pre&gt;
$(document).ready(function() {&amp;#10;&amp;#9;$(&amp;#39;.tabs&amp;#39;).tabs();&amp;#10;&amp;#9;&amp;#10;&amp;#9;$(&amp;#39;.carousel&amp;#39;).carousel();&amp;#10;&amp;#9;&amp;#10;&amp;#9;$(&amp;#39;.slider&amp;#39;).slider();&amp;#10;});&lt;/pre&gt;
&lt;p&gt;
	&lt;img alt="NO" src="http://media.giphy.com/media/vJuQAOM5EKGNa/original.gif" /&gt;&lt;/p&gt;
&lt;p&gt;
	Just don&amp;#39;t do this. Even though jQuery fails silently, there is no reason to just throw stuff at the DOM and hope it sticks. Come up with a plan to execute only the JS that you need for each page.&lt;/p&gt;
&lt;h2&gt;
	Dom Based Routing&lt;/h2&gt;
&lt;p&gt;
	Paul Irish initially talked about &lt;a href="http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/"&gt;this technique&lt;/a&gt; in 2009. The idea is to use the id and class attributes on the body element to determine which JavaScript should be fired.&lt;/p&gt;
&lt;p&gt;
	Let&amp;#39;s pretend that your body element looks like this:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;body class="shopping" id="cart"&amp;gt;&lt;/pre&gt;
&lt;p&gt;
	And you have some JS that looks like this:&lt;/p&gt;
&lt;pre&gt;
SITE = {&amp;#10;&amp;#9;common: {&amp;#10;&amp;#9;&amp;#9;init: function(){ ... },&amp;#10;&amp;#9;&amp;#9;finalize: function(){ ... }&amp;#10;&amp;#9;},&amp;#10;&amp;#9;shopping: {&amp;#10;&amp;#9;&amp;#9;init: function(){ ... },&amp;#10;&amp;#9;&amp;#9;cart: function(){ ... },&amp;#10;&amp;#9;&amp;#9;category: function(){ ... }&amp;#10;&amp;#9;}&amp;#10;};&lt;/pre&gt;
&lt;p&gt;
	The execution code is set up so that it calls the following methods:&lt;/p&gt;
&lt;pre&gt;
SITE.common.init()&amp;#10;SITE.shopping.init()&amp;#10;SITE.shopping.cart()&amp;#10;SITE.common.finalize()&lt;/pre&gt;
&lt;h2&gt;
	Garber-Irish Implementation&lt;/h2&gt;
&lt;p&gt;
	&lt;a href="http://viget.com/inspire/extending-paul-irishs-comprehensive-dom-ready-execution"&gt;This technique&lt;/a&gt; came out of my coworker, &lt;a href="http://viget.com/about/team/jgarber"&gt;Jason Garber&lt;/a&gt;, working on a Rails project and had a desire for a little more structure. The idea is to use the Rails controller and action to execute specific JavaScript.&lt;/p&gt;
&lt;p&gt;
	For example, on the &lt;strong&gt;users show&lt;/strong&gt; page, the body element would look like this:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;body data-controller="users" data-action="show"&amp;gt;&lt;/pre&gt;
&lt;p&gt;
	So you create objects based on controllers with a method for the action. The JavaScript would look like this:&lt;/p&gt;
&lt;pre&gt;
SITE = {&amp;#10;&amp;#9;common: {&amp;#10;&amp;#9;&amp;#9;init: function() {}&amp;#10;&amp;#9;},&amp;#10; &amp;#10;&amp;#9;users: {&amp;#10;&amp;#9;&amp;#9;init: function() {},&amp;#10;&amp;#9;&amp;#9;index: function() {},&amp;#10;&amp;#9;&amp;#9;show: function() {}&amp;#10;&amp;#9;}&amp;#10;};&lt;/pre&gt;
&lt;p&gt;
	The execution code is set up to call the following methods:&lt;/p&gt;
&lt;pre&gt;
SITE.common.init();&amp;#10;SITE.users.init();&amp;#10;SITE.users.show();&lt;/pre&gt;
&lt;p&gt;
	This pattern has worked great for a number of sites, and I&amp;#39;ve even used the pattern for non-Rails projects. But, as we have continued to build more responsive and modular sites that are more system-based instead of page-based, the pattern has become less and less ideal.&lt;/p&gt;
&lt;h2&gt;
	Feature-Based Execution&lt;/h2&gt;
&lt;p&gt;
	This technique takes a feature based approach instead of a page specific approach. The idea is to break each feature out into a separate object, and then add the features that you want to execute as an attribute on the body. Here is an example of what our body element would look like:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;body data-features="timeline tabs filters modal"&amp;gt;&lt;/pre&gt;
&lt;p&gt;
	Here is how we have each of the features broken out into separate objects:&lt;/p&gt;
&lt;pre&gt;
SITE.features = {&amp;#10;&amp;#9;filters: {&amp;#10;&amp;#9;&amp;#9;init: function() {}&amp;#10;&amp;#9;},&amp;#10;&amp;#10;&amp;#9;modal: {&amp;#10;&amp;#9;&amp;#9;init: function() {}&amp;#10;&amp;#9;},&amp;#10;&amp;#10;&amp;#9;tabs: {&amp;#10;&amp;#9;&amp;#9;init: function() {}&amp;#10;&amp;#9;},&amp;#10;&amp;#10;&amp;#9;timeline: {&amp;#10;&amp;#9;&amp;#9;init: function() {}&amp;#10;&amp;#9;}&amp;#9;&amp;#10;};&lt;/pre&gt;
&lt;p&gt;
	Then, I typically add an init method onto our SITE.features object to initialize all of the feature based execution:&lt;/p&gt;
&lt;pre&gt;
SITE.features = {&amp;#10;&amp;#9;init: function() {&amp;#10;&amp;#9;&amp;#9;var features = $(&amp;#39;body&amp;#39;).data(&amp;#39;features&amp;#39;);&amp;#10;&amp;#9;&amp;#9;var featuresArray = [];&amp;#10;&amp;nbsp;&amp;#10;&amp;#9;&amp;#9;if(features) {&amp;#10;&amp;#9;&amp;#9;&amp;#9;featuresArray = features.split(&amp;#39; &amp;#39;);&amp;#10;&amp;nbsp;&amp;#10;&amp;#9;&amp;#9;&amp;#9;for(var x = 0, length = featuresArray.length; x &amp;lt; length; x++) {&amp;#10;&amp;#9;&amp;#9;&amp;#9;&amp;#9;var func = featuresArray[x];&amp;#10;&amp;nbsp;&amp;#10;&amp;#9;&amp;#9;&amp;#9;&amp;#9;if(this[func] &amp;amp;&amp;amp; typeof this[func].init === &amp;#39;function&amp;#39;) {&amp;#10;&amp;#9;&amp;#9;&amp;#9;&amp;#9;&amp;#9;this[func].init();&amp;#10;&amp;#9;&amp;#9;&amp;#9;&amp;#9;}&amp;#10;&amp;#9;&amp;#9;&amp;#9;}&amp;#10;&amp;#9;&amp;#9;}&amp;#10;&amp;#9;}&amp;#10;};&lt;/pre&gt;
&lt;p&gt;
	&lt;a href="https://gist.github.com/davist11/738c2dfb248427904d07"&gt;View as Gist&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	So when we call &lt;strong&gt;SITE.features.init()&lt;/strong&gt; on document load, we grab the data attribute off of the body, and execute each feature. It would execute the following methods:&lt;/p&gt;
&lt;pre&gt;
SITE.features.timeline.init()&amp;#10;SITE.features.tabs.init()&amp;#10;SITE.features.filters.init()&amp;#10;SITE.features.modal.init()&lt;/pre&gt;
&lt;h2&gt;
	Feature-Based Execution + Script Loader&lt;/h2&gt;
&lt;p&gt;
	An idea that I have been playing with, but haven&amp;#39;t implemented yet on a site, is to use a script loader to load features for the page instead of including them in a single concatenated file. Here is what the modified &lt;strong&gt;SITE.features.init()&lt;/strong&gt; method looks like using the &lt;a href="http://yepnopejs.com/"&gt;yepnope script loader&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;
SITE.features = {&amp;#10;&amp;#9;init: function() {&amp;#10;&amp;#9;&amp;#9;var features = $(&amp;#39;body&amp;#39;).data(&amp;#39;features&amp;#39;);&amp;#10;&amp;#9;&amp;#9;var featuresArray = [];&amp;#10;&amp;nbsp;&amp;#10;&amp;#9;&amp;#9;if (features) {&amp;#10;&amp;#9;&amp;#9;&amp;#9;featuresArray = features.split(&amp;#39; &amp;#39;);&amp;#10;&amp;nbsp;&amp;#10;&amp;#9;&amp;#9;&amp;#9;for(var x = 0, length = featuresArray.length; x &amp;lt; length; x++) {&amp;#10;&amp;#9;&amp;#9;&amp;#9;&amp;#9;var func = featuresArray[x];&amp;#10;&amp;nbsp;&amp;#10;&amp;#9;&amp;#9;&amp;#9;&amp;#9;yepnope([{&amp;#10;&amp;#9;&amp;#9;&amp;#9;&amp;#9;&amp;#9;load: &amp;#39;scripts/features/&amp;#39; + func + &amp;#39;.js&amp;#39;,&amp;#10;&amp;#9;&amp;#9;&amp;#9;&amp;#9;&amp;#9;complete: function () {&amp;#10;&amp;#9;&amp;#9;&amp;#9;&amp;#9;&amp;#9;&amp;#9;if(this[func] &amp;amp;&amp;amp; typeof this[func].init === &amp;#39;function&amp;#39;) {&amp;#10;&amp;#9;&amp;#9;&amp;#9;&amp;#9;&amp;#9;&amp;#9;&amp;#9;this[func].init();&amp;#10;&amp;#9;&amp;#9;&amp;#9;&amp;#9;&amp;#9;&amp;#9;}&amp;#10;&amp;#9;&amp;#9;&amp;#9;&amp;#9;&amp;#9;}&amp;#10;&amp;#9;&amp;#9;&amp;#9;&amp;#9;}]);&amp;#10;&amp;#9;&amp;#9;&amp;#9;}&amp;#10;&amp;#9;&amp;#9;}&amp;#10;&amp;#9;}&amp;#10;};&lt;/pre&gt;
&lt;p&gt;
	&lt;a href="https://gist.github.com/davist11/7a26d71bac8e1a7dc076"&gt;View as Gist&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
	jQuery Meetup&lt;/h2&gt;
&lt;p&gt;
	I recently had the opportunity to give a presentation on this topic, along with jQuery plugin development (go to slide 72 if you want to skip the jQuery plugin development piece) at the &lt;a href="http://www.meetup.com/DC-jQuery-Users-Group/events/109918942/"&gt;DC jQuery Meetup&lt;/a&gt;.&lt;/p&gt;
&lt;script async class="speakerdeck-embed" data-id="80fa54c08ac1013041e5123139283542" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"&gt;&lt;/script&gt;
&lt;h2&gt;
	What Did We Learn?&lt;/h2&gt;
&lt;p&gt;
	Don&amp;rsquo;t just haphazardly fire a bunch of JS functions that may or may not be used. Come up with a pattern for triggering JS on each page that makes sense for your site.&lt;/p&gt;
&lt;p&gt;
	So what methods have you used for executing JavaScript on sites?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/dz906nSde6M" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/javascript-execution-patterns-for-non-web-apps#When:13:29</feedburner:origLink></item>
		
			<item>
				<title>Why I Chose to Learn C</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/i0RXmFq81EU/why-i-chose-to-learn-c</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/why-i-chose-to-learn-c#When:16:05</guid>
				
				<pubDate>Fri, 29 Mar 2013 16:05 GMT</pubDate>
				<dc:creator>Patrick Reagan</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;
	This past fall, a group of us set out to (re-)learn the C programming language using Zed&amp;#39;s &lt;a href="http://c.learncodethehardway.org/book/"&gt;Learn C the Hard Way&lt;/a&gt; as our primary resource. In the age of high-level languages like Ruby and JavaScript, it may seem a bit strange to take such a "step back" when it&amp;#39;s been 10+ years since I have had any significant experience using the language. So why do it?&lt;/p&gt;
&lt;p&gt;
	I wanted a new challenge.&lt;/p&gt;

						&lt;p&gt;
	As an experienced programmer, the basics of the language were unsurprising (as expected). Variables, conditionals, and loops presented no surprises as I&amp;#39;ve seen these concepts time and time again in other languages. I will admit that understanding pointers was initially as confusing as when I first encountered them more than 15 years ago. This confusion reinforced the fact that C is not a language for the faint of heart -- there are a number of challenges that a programmer has to overcome when working in a lower-level language.&lt;/p&gt;
&lt;p&gt;
	These challenges weren&amp;#39;t without their benefits. During our course of study, we became proficient with a number of language features and related tools:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		&lt;strong&gt;Memory allocation&lt;/strong&gt; &amp;mdash; Once I moved past writing trivial programs, heap allocation became a necessity. Not only did I learn how to use &lt;tt&gt;malloc&lt;/tt&gt; and &lt;tt&gt;free&lt;/tt&gt; appropriately, but also when to use &lt;tt&gt;realloc&lt;/tt&gt; to create dynamic data structures and &lt;tt&gt;calloc&lt;/tt&gt; to create robust allocations for storing string data.&lt;/li&gt;
	&lt;li&gt;
		&lt;strong&gt;Makefiles&lt;/strong&gt; &amp;mdash; Zed&amp;#39;s introduction to &lt;tt&gt;make&lt;/tt&gt; and subsequent discussion of its advanced features really helped to de-mystify the tool for me. The &lt;a href="http://www.gnu.org/software/make/manual/html_node/index.html"&gt;additional documentation&lt;/a&gt; and &lt;a href="http://bost.ocks.org/mike/make/"&gt;alternate applications&lt;/a&gt; helped me understand its utility for building C programs and other automated tasks.&lt;/li&gt;
	&lt;li&gt;
		&lt;strong&gt;Function pointers&lt;/strong&gt; &amp;mdash; It was interesting to me to see that such a low-level language contained functional programming concepts. I found function pointers a useful refactoring technique when dealing with different collections of structs. For example, when sorting an array of integers or strings, I was able to use functions with the same signature and behavior but with different implementations.&lt;/li&gt;
	&lt;li&gt;
		&lt;strong&gt;C pre-processor&lt;/strong&gt; &amp;mdash; From the beginning, Zed made heavy use of the C pre-processor to create macros for debugging, iterating, and otherwise simplifying the code that I needed to write. After gaining more experience with the language, I learned when to choose a pre-processor macro over a subroutine (or vice versa) to refactor and improve readability of the code.&lt;/li&gt;
	&lt;li&gt;
		&lt;strong&gt;Variable argument functions&lt;/strong&gt; &amp;mdash; Surprisingly, this language feature came in handy more often than I thought. Internally, this is how the &lt;tt&gt;printf&lt;/tt&gt; family of functions is implemented. I used it to create functions like &lt;tt&gt;max_length(char *s1, char *s2, ...)&lt;/tt&gt; to get the overall maximum length of &lt;strong&gt;&lt;tt&gt;n&lt;/tt&gt;&lt;/strong&gt; number of strings, and &lt;tt&gt;array_push(Array *array, ...)&lt;/tt&gt;` to add elements to an array based on its underlying storage type.&lt;/li&gt;
	&lt;li&gt;
		&lt;strong&gt;&lt;a href="http://valgrind.org/"&gt;Valgrind&lt;/a&gt;&lt;/strong&gt; &amp;mdash; I have no idea how you would create a stable program without this tool. Time and time again, I would write what I &lt;em&gt;thought&lt;/em&gt; was robust code, but valgrind would call me out on my mistakes. Whether it was a simple memory leak or an off-by-one error when accessing a segment of memory, I was able to quickly diagnose those mistakes and correct them. Without valgrind, these errors could easily slip by undetected.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Overall, the challenges presented with C really forced me to think deeply about how I organized my code and interacted with the machine. Understanding that balance between bare-metal performance and human understandability definitely revealed the language&amp;#39;s sweet spot. Even in an industry where older technologies are constantly rendered obsolete, that balance is the reason developers of major modern software projects continue to choose C for their implementation language.&lt;/p&gt;
&lt;p&gt;
	If you&amp;#39;re interested in (re-)learning the language yourself, I recommend LCTHW as a good starting resource. Working through the exercises as a group helps keep everyone motivated and generates some &lt;a href="https://github.com/vigetlabs/bode"&gt;fun&lt;/a&gt; &lt;a href="https://github.com/reagent/http"&gt;ideas&lt;/a&gt; for &lt;a href="https://github.com/reagent/encode"&gt;other&lt;/a&gt; &lt;a href="https://github.com/reagent/buffer"&gt;programs&lt;/a&gt; to write.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/i0RXmFq81EU" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/why-i-chose-to-learn-c#When:16:05</feedburner:origLink></item>
		
			<item>
				<title>Preventing Interface-Induced Backbone.sync Firestorms</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/u_0dOdtsW5E/preventing-backbone.sync-firestorms</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/preventing-backbone.sync-firestorms#When:14:19</guid>
				
				<pubDate>Tue, 26 Feb 2013 14:19 GMT</pubDate>
				<dc:creator>Nate Hunzaker</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;
	Draggable controls raise an interesting challenge when&amp;nbsp; &lt;code&gt;Backbone.Views&lt;/code&gt; share a common model.&lt;/p&gt;

						&lt;p&gt;
	Such controls include colorpickers, slides, and positionable elements. When users move around a color wheel or acutely adjust the position of an element, change events should trigger to let other components know their portion of the interface needs updating.&lt;/p&gt;
&lt;p&gt;
	For this to happen, the browser&amp;#39;s data layer must update immediately. But how does the application know when to pass the torch to the database?&lt;/p&gt;
&lt;p&gt;
	Requesting to persist data on every pixel deviation can be disastrous. When a user wants the perfect shade of yellow, there&amp;#39;s nothing like a torrent of &lt;code&gt;PUT&lt;/code&gt; requests to dampen their mood.&lt;/p&gt;
&lt;p&gt;
	To illustrate:&lt;/p&gt;
&lt;p&gt;
	&lt;iframe allowfullscreen="allowfullscreen" frameborder="0" src="http://jsfiddle.net/vt9Hq/17/embedded/result" style="width: 100%; height: 365px"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;
	Not exactly performant. Fortunately &lt;a href="http://underscorejs.org/"&gt;UnderscoreJS&lt;/a&gt; provides a great toolset for tackling exactly this problem.&lt;/p&gt;
&lt;h2&gt;
	Only you can prevent forest-fires, &lt;em&gt;by debouncing&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;
	&lt;a href="http://underscorejs.org/#debounce"&gt;UnderscoreJS&amp;#39;s &lt;code&gt;debounce&lt;/code&gt;&lt;/a&gt; method is particularly well suited for our use case: it postpones invocation of a function until a specified expiration time that resets on every function call. This can be used to bundle together &lt;code&gt;Backbone.sync&lt;/code&gt; executions from the same source, significantly lowering requests without nasty side effects.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Update&lt;/strong&gt;: Originally I handled debouncing directly within the &lt;code&gt;sync&lt;/code&gt; method of the &lt;code&gt;Backbone.Model&lt;/code&gt;, however a sharp commenter has suggested a more optimal solution by moving this functionality into the &lt;code&gt;Backbone.View&lt;/code&gt; that oversees the input.&lt;/p&gt;
&lt;p&gt;
	To avoid directly manipulating the &lt;code&gt;Backbone.sync&lt;/code&gt; method, an event must be bound in the view that controls such inputs. On change, the view should immediately provide actions required to update the user interface, requesting to sync in the background.&lt;/p&gt;
&lt;pre&gt;
var View = Backbone.View.extend({&amp;#10;&amp;#10;    events: {&amp;#10;        &amp;#39;change input.slider&amp;#39; : &amp;#39;onSliderChange&amp;#39;&amp;#10;    },&amp;#10;&amp;#10;    saveInBackground: _.debounce(function(params) {&amp;#10;        return this.model.save(params, { silent: true });&amp;#10;    }, 800),&amp;#10;&amp;#10;    onSliderChange: function(e) {&amp;#10;&amp;#10;        // Take immediate action, such as setting the values locally:&amp;#10;        this.model.set({&amp;#10;            value: e.target.value&amp;#10;        });&amp;#10;       &amp;#10;        // Then call a debounced save method, which will eventually&amp;#10;        // trigger Backbone.sync&amp;#10;        this.saveInBackground();&amp;#10;       &amp;#10;    }&amp;#10;&amp;#10;&amp;#10;});&lt;/pre&gt;
&lt;p&gt;
	&lt;iframe allowfullscreen="allowfullscreen" frameborder="0" src="http://jsfiddle.net/9SDxy/5/embedded/result/" style="width: 100%; height: 365px"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;h2&gt;
	Beautiful and Simple&lt;/h2&gt;
&lt;p&gt;
	This minor addition achieves exactly what is needed! No matter how furiously the user updates information, the &lt;strike&gt;model&lt;/strike&gt; view is now smart enough to send an AJAX request once, a short period after the drag motion has completed. Minor tweaks may be required depending on the purposes of the application, but the resulting code lets the user interface immediately respond to the change, while not causing servers to catch on fire.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/u_0dOdtsW5E" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/preventing-backbone.sync-firestorms#When:14:19</feedburner:origLink></item>
		
			<item>
				<title>Arduino, Redis, Dropcam + Holiday Cheer = Jinglebots!</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/jUrYndU_l2I/arduino-redis-dropcam-holiday-cheer-jinglebots</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/arduino-redis-dropcam-holiday-cheer-jinglebots#When:21:33</guid>
				
				<pubDate>Wed, 19 Dec 2012 21:33 GMT</pubDate>
				<dc:creator>Eli Fatsi</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;
	Hopefully, you&amp;#39;ve been able to experience our Jinglebots -- the 2012&amp;nbsp;&lt;a href="http://pointlesscorp.com/"&gt;Pointless Corp&lt;/a&gt;&amp;nbsp;holiday project -- for yourself. Klaus 5000, Cornelius, and Ru 2 Dee 2 are the Jinglebots -- &amp;ldquo;robots&amp;rdquo; which reside in each of our Viget offices.&amp;nbsp; They &amp;ldquo;speak&amp;rdquo; tweets and messages for all of the world to hear through a&amp;nbsp;&lt;a href="https://www.dropcam.com/"&gt;Dropcam&lt;/a&gt; feed. As a user, you can check out the &lt;a href="http://jinglebots.com"&gt;web site&lt;/a&gt;&amp;nbsp;and either tweet with the #jinglebots hashtag or submit a message through a basic messenger on the site.&lt;/p&gt;
&lt;p&gt;
	I&amp;#39;ve estimated the amount of coordinating technologies to be around a bazillion. For those who may be interested in how to use your computer to control Christmas lights, power electric toy trains, or do other cool things (using Ruby!), I&amp;rsquo;ll walk you through how to do it below.&lt;/p&gt;

						&lt;h2&gt;
	Step 1 - Instant Communication&lt;/h2&gt;
&lt;p&gt;
	We knew that we&amp;#39;d be responding to messages and tweets in real time. For this, we made use of&amp;nbsp;&lt;a href="redis.io"&gt;Redis&lt;/a&gt; pub/sub capabilities. Redis is super simple to get going locally and use of&amp;nbsp;&lt;a href="redistogo.com"&gt;RedisToGo&lt;/a&gt; gives you access to a free online Redis instance you can use in production. When a message comes in, we publish the message data (sender name, message, timestamp, etc.) in JSON to a Redis channel.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;REDIS.publish("holiday_messages", data.to_json)&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	Each of our Jinglebots is subscribed to the &lt;code&gt;holiday_messages&lt;/code&gt; channel.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;REDIS.subscribe(&amp;#39;holiday_messages&amp;#39;) do |on|&amp;#10;  on.message do |channel, raw_data|&amp;#10;    data = JSON.parse(raw_data)&amp;#10;    ... some awesome stuff using the data&amp;#10;  end&amp;#10;end&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	Instant communication has never been easier.&lt;/p&gt;
&lt;h2&gt;
	Step 2 - Receiving Messages/Tweets&lt;/h2&gt;
&lt;p&gt;
	On the web site, a form allows users to submit a message and a name. On submission success, the app then compiles the necessary data, converts it to JSON, and publishes it to the&amp;nbsp;&lt;code&gt;holiday_messages&lt;/code&gt; Redis channel.&lt;/p&gt;
&lt;p&gt;
	To capture incoming tweets with the #jinglebots hashtag, we made use of&amp;nbsp;&lt;a href="https://github.com/eventmachine/eventmachine"&gt;EventMachine&lt;/a&gt; and the &lt;a href="https://github.com/voloko/twitter-stream"&gt;twitter-stream&lt;/a&gt; gem. This bit of code owes great credit to &lt;a href="http://twerribletowel.com/"&gt;Twerrible Towel&lt;/a&gt; which has their &lt;a href="https://gist.github.com/814514"&gt;code&lt;/a&gt; open sourced. The following code takes care of all the Twitter listening for us.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;EventMachine::run do&amp;#10;&amp;#10;  stream = Twitter::JSONStream.connect(&amp;#10;    :path    =&amp;gt; &amp;#39;/1/statuses/filter.json&amp;#39;,&amp;#10;    :auth    =&amp;gt; "#&amp;#123;twitter_username&amp;#125;:#&amp;#123;twitter_password&amp;#125;",&amp;#10;    :method  =&amp;gt; &amp;#39;POST&amp;#39;,&amp;#10;    :content =&amp;gt; "track=#jinglebots"&amp;#10;  )&amp;#10;&amp;#10;  stream.each_item do |item|&amp;#10;    tweet = JSON.parse(item)&amp;#10;    if tweet &amp;amp;&amp;amp; tweet["user"]&amp;#10;      data = assemble_data(tweet)&amp;#10;      REDIS.publish("holiday_messages", data.to_json)&amp;#10;    end&amp;#10;  end&amp;#10;end&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
	Step 3 - The Fun Part&lt;/h2&gt;
&lt;p&gt;
	So, with a stream of messages coming in, we had to figure out what to do with them. If you&amp;#39;re on a Mac, open up the terminal and type &lt;code&gt;say hello master&lt;/code&gt;. With the volume turned up, your computer has been given a voice! After some massaging of the incoming message (removing special characters, subbing out bad words for a system beeeeep), we now had robots which could speak any message we threw at them.&lt;/p&gt;
&lt;p&gt;
	We weren&amp;#39;t done though. What&amp;#39;s a talking robot without a face? Enter the tag team work of designer &lt;a href="http://viget.com/about/team/josephle"&gt;Joseph Le&lt;/a&gt; and front-end developer &lt;a href="http://viget.com/about/team/nhunzaker"&gt;Nate Hunzaker&lt;/a&gt;. A simple-yet-awesome &lt;a href="http://nodejs.org/"&gt;Node.js&lt;/a&gt; app on &lt;a href="http://expressjs.com/"&gt;Express&lt;/a&gt; meant that we had three different faces (one for each Jinglebot) which could be turned to "talking" and "not talking" mode with a curl command to the local server.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;`curl --data "" http://localhost:3000/say?message=true`&amp;#10;`curl --data "" http://localhost:3000/shutup`&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	Open sourced code is available &lt;a href="https://github.com/vigetlabs/talking-heads"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
	Using the same Node.js/Express combination, a &lt;a href="https://github.com/vigetlabs/jinglebots-gif-displayer"&gt;gif(t) displayer&lt;/a&gt; was coded up so the talking robots had something to display while they read your message aloud.&lt;/p&gt;
&lt;h2&gt;
	Step 3.5 - The Really Fun Part&lt;/h2&gt;
&lt;p&gt;
	&lt;a href="http://www.arduino.cc/"&gt;Arduino&lt;/a&gt;&amp;nbsp;time! An Arduino is a programmable microcontroller which allows you to develop in &lt;a href="http://www.processing.org/"&gt;Processing&lt;/a&gt; and do cool things like turn on LEDs or make an &lt;a href="http://www.instructables.com/id/Iron-Man-Suit-with-Tech/"&gt;Iron Man Costume&lt;/a&gt;. We&amp;#39;re still pretty new at this stuff, so we went with the ability to control Christmas lights and an old electronic toy train set (maybe next year we&amp;#39;ll go for the Iron Man Costume).&lt;/p&gt;
&lt;p&gt;
	There&amp;#39;s one more piece of this puzzle to introduce which made this process super easy -- &lt;a href="https://github.com/austinbv/dino"&gt;dino&lt;/a&gt;. Dino is an awesome gem which lets you control your Arduino using Ruby. Simply load up the dino &lt;a href="https://raw.github.com/austinbv/dino/master/src/du.ino"&gt;code&lt;/a&gt; to your Arduino, set up your board in Ruby, and start sending power where you want it.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;require &amp;#39;dino&amp;#39;&amp;#10;&amp;#10;board = Dino::Board.new(Dino::TxRx.new)&amp;#10;pin   = Dino::Components::Led.new(pin: 13, board: board)&amp;#10;&amp;#10;pin.on&amp;#10;sleep 4&amp;#10;pin.off&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	We made use of a relay and a power cord cut in half. When the relay switch is open, no power can pass from the wall to our appliance. When we give the command &lt;code&gt;pin.on&lt;/code&gt;, we send 5V to our relay, closing the switch, powering our appliance with a full 120V from the wall. A basic tutorial of how to set this up is available &lt;a href="https://gist.github.com/1d37daefde78533ba4fb"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
	&lt;i&gt;Note: To get the Christmas lights to flash, we actually set a Redis key named "flash" to true or false and had a Ruby script checking that variable every second and flashing the lights independent of the robot. This was done to keep blocking operations from interfering with each other.&lt;/i&gt;&lt;/p&gt;
&lt;h2&gt;
	Step 4 - The Web Site&lt;/h2&gt;
&lt;p&gt;
	Viget&amp;#39;s home turf. Designer &lt;a href="http://viget.com/about/team/msteinruck"&gt;Mark Steinruck&lt;/a&gt;, UXers &lt;a href="http://viget.com/about/team/jtoth"&gt;Jason Toth&lt;/a&gt; and &lt;a href="http://viget.com/about/team/lgutin"&gt;Lance Gutin&lt;/a&gt;, and again the almighty front-end developer &lt;a href="http://viget.com/about/team/nhunzaker"&gt;Nate&lt;/a&gt; came together to make a festive, easy, and fun-to-use site. We leveraged the Dropcam already set up at each office to let users watch each Jinglebot right on the sight, and displayed a running list of the most recent messages, as well as aggregate stats, on the bots and messages.&lt;/p&gt;
&lt;p&gt;
	Messages and tweets that came in were not only published to the Redis channel, but were also saved to a &lt;a href="http://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt; database with the help of &lt;a href="http://datamapper.org/getting-started.html"&gt;DataMapper&lt;/a&gt;. In this way, we had a clean and organized record of all messages that came in to the Jinglebots.&lt;/p&gt;
&lt;h2&gt;
	Step 5 - The Jingle Report&lt;/h2&gt;
&lt;p&gt;
	As a little bonus, we wanted to give the user more than just a talking robot. A Jingle Report was created for every message or tweet that came in, and tweets were sent to users with the Report link to view. Here&amp;#39;s a personal favorite - &lt;a href="http://jinglebots.com/report/901"&gt;http://jinglebots.com/report/901&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
	Each report required a screenshot of a Jinglebot scene, as well as a voice recording of the message. &lt;a href="http://lame.sourceforge.net/"&gt;LAME&lt;/a&gt; was used to convert the saved audio files (&lt;code&gt;say -o file/path/to/save.aiff message&lt;/code&gt;) into web-friendly formats, some Dropcam craftiness was used to grab screenshots from a given time (thanks to a post in &lt;a href="http://support.dropcam.com/entries/21455573-dropcam-api"&gt;this&lt;/a&gt; forum), and &lt;a href="http://aws.amazon.com/s3/"&gt;Amazon S3&lt;/a&gt; was used to store these assets. Boom: Jingle Reports.&lt;/p&gt;
&lt;h2&gt;
	Step 6 - The Auto Pilot&lt;/h2&gt;
&lt;p id="scroll_to_here"&gt;
	Cronjobs were a big win for this project. Having the code systematically restart every so often meant that if anything did go wrong (a lot of coordinated tech -&amp;gt; a lot of potential problems), it would take care of restarting itself.&lt;/p&gt;
&lt;p&gt;
	This was a major component for things like the amount of sleep&amp;nbsp;&lt;a href="http://viget.com/about/team/beckerson"&gt;Ben&lt;/a&gt;&amp;nbsp;and I could get without having to restart the Jinglebots after they mysteriously crashed in the middle of the night. The code behind this is &lt;a href="https://gist.github.com/4340349"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
	Summary&lt;/h2&gt;
&lt;p&gt;
	On Friday the 21st, the &lt;a href="http://jinglebots.com"&gt;Jinglebots&lt;/a&gt; had been spreading holiday cheer for two whole weeks, and the project was a blast to work on. It was a great combination of Viget&amp;rsquo;s coding skills, as well as our discovered "building-real-things" skills. More on why the crew involved came together to build something like this can be read &lt;a href="http://viget.com/advance/making-things-just-because"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
	Jinglebots was the brainchild of &lt;a href="http://viget.com/about/team/beckerson"&gt;Ben Eckerson&lt;/a&gt; (without him the project would never have existed) and the collaborative effort of many - &lt;a href="http://viget.com/about/team/btornes"&gt;Becky Tornes&lt;/a&gt;, &lt;a href="http://viget.com/about/team/kstenberg"&gt;Khanh Stenberg&lt;/a&gt;, &lt;a href="http://viget.com/about/team/amckenzie"&gt;Anjali Mckenzie&lt;/a&gt;, &lt;a href="http://viget.com/about/team/mackerman"&gt;Mike Ackerman&lt;/a&gt;, and the whole Viget dev team for their advice and mentorship.&lt;/p&gt;
&lt;p&gt;
	Happy Jinglebottin!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/jUrYndU_l2I" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/arduino-redis-dropcam-holiday-cheer-jinglebots#When:21:33</feedburner:origLink></item>
		
			<item>
				<title>Using Time Zones with Rails</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/YvtCBJZSv8Y/using-time-zones-with-rails</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/using-time-zones-with-rails#When:15:25</guid>
				
				<pubDate>Wed, 19 Dec 2012 15:25 GMT</pubDate>
				<dc:creator>Eli Fatsi</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;
	On a recent Rails application I built, I needed to determine which time zone a user was in to correctly display and use time-related information. I&amp;#39;ll walk through two techniques I&amp;#39;ve found to get the job done.&lt;/p&gt;
&lt;p&gt;
	The theory around working with time zones is pretty straightforward. Save all time-related data in Coordinated Universal Time (UTC), and display all time-related data in the time zone of any given user. If you&amp;#39;re unfamiliar with ActiveSupport&amp;#39;s &lt;code&gt;TimeWithZone&lt;/code&gt;, quickly check out this &lt;a href="http://viget.com/extend/protip-timewithzone-all-the-time"&gt;blog post&lt;/a&gt; from &lt;a href="http://viget.com/about/team/deisinger"&gt;David Eisinger&lt;/a&gt; and familiarize yourself with the &lt;code&gt;in_time_zone&lt;/code&gt; method for display purposes.&lt;/p&gt;
&lt;p&gt;
	The question then becomes, "How do we know what time zone a user is in?"&lt;/p&gt;

						&lt;h2&gt;
	Method 1 - Quick, simple, 90% right&lt;/h2&gt;
&lt;p&gt;
	In search for the answer, I first discovered some simple JavaScript code:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;var currentTime = new Date();&amp;#10;var utcOffset   = currentTime.getTimezoneOffset()&amp;#10;document.cookie = &amp;#39;time_zone_offset=&amp;#39;+utcOffset+&amp;#39;;&amp;#39;;&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	&lt;code&gt;new Date()&lt;/code&gt; constructs a date object with the current time based on your system clock. &lt;code&gt;getTimezoneOffset()&lt;/code&gt; returns the number of minutes from which you differ from UTC. Throw that in a cookie and you&amp;#39;re done with the JavaScript.&lt;/p&gt;
&lt;p&gt;
	On the Rails side of things, you can grab that offset from the cookies and run the following code to determine which time zone has that offset.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;offset    = cookies["time_zone_offset"].to_i&amp;#10;time_zone = ActiveSupport::TimeZone[-offset.minutes]&amp;#10;current_user.update_attribute(:time_zone =&amp;gt; time_zone)&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	&lt;b&gt;However&lt;/b&gt;, This doesn&amp;#39;t exactly work. There are multiple time zones that share a common offset. If you use this technique on the east coast of America, it&amp;#39;s likely you&amp;#39;ll get &lt;code&gt;(GMT-05:00) Bogota&lt;/code&gt;, the capitol of Columbia, or &lt;code&gt;(GMT-04:00) Atlantic Time (Canada)&lt;/code&gt;, depending on if you&amp;#39;ve recently sprung forward or fallen back. This is due to the fact that these time zones come before &lt;code&gt;(GMT-04/05:00) Eastern Time (US &amp;amp; Canada)&lt;/code&gt; alphabetically.&lt;/p&gt;
&lt;p&gt;
	While this approach will still give you the accurate time for the present day, Daylight Savings standards of other regions could affect your code in the future. If your app does not care about the future, this solution is fine. My app does care about the future, though, and suddenly all my tests started failing when Daylight Savings Time came around.&lt;/p&gt;
&lt;h2&gt;
	Method 2 - Quick, a little less simple, 100% right&lt;/h2&gt;
&lt;p&gt;
	Enter &lt;a href="http://www.pageloom.com/automatic-timezone-detection-with-javascript"&gt;JSTZ&lt;/a&gt;! This stands for jsTimezoneDetect and is a sweet bit of code which parses out the &lt;i&gt;actual&lt;/i&gt; time zone from your computer&amp;#39;s system time. Source code can be found &lt;a href="https://bitbucket.org/pellepim/jstimezonedetect/src"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
	With the set of functions &lt;code&gt;jstz&lt;/code&gt; offers, the following lines of code will correctly determine the user&amp;#39;s system time zone and store it in a cookie called &lt;code&gt;jstz_time_zone&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;var timeZone = jstz.determine();&amp;#10;document.cookie = &amp;#39;jstz_time_zone=&amp;#39;+timeZone.name()+&amp;#39;;&amp;#39;;&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	From there, you can retrieve the cookie in any controller and update the &lt;code&gt;time_zone&lt;/code&gt; attribute on the user.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;current_user.update_attribute(:time_zone =&amp;gt; cookies["jstz_time_zone"])&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	Excellent! Now we are correctly retrieving a user&amp;#39;s time zone from their computer and saving it on the user.&lt;/p&gt;
&lt;h2&gt;
	Confirming&lt;/h2&gt;
&lt;p&gt;
	At this point you have retrieved the user&amp;#39;s system time zone, however it&amp;#39;s possible that this is not the &lt;i&gt;correct&lt;/i&gt; time zone. While it&amp;#39;s a good guess to have when asking the user for input on the matter, it&amp;#39;s necessary that you ask the user to confirm or select a time zone to guarantee correctness.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;% unless cookies[:selected_a_time_zone] %&amp;gt;&amp;#10;  &amp;lt;div class="time-zone-confirmation"&amp;gt;&amp;#10;    &amp;lt;%= "Are you currently in the following time zone: #&amp;#123;current_user.time_zone&amp;#125;?" %&amp;gt;&amp;#10;    &amp;lt;%= button_tag "Yes", :class =&amp;gt; &amp;#39;hide-time-zone-confirmation&amp;#39; %&amp;gt;&amp;#10;    &amp;lt;%= button_tag "No",  :class =&amp;gt; &amp;#39;show-time-zone-selection&amp;#39; %&amp;gt;&amp;#10;    &amp;lt;div class="time-zone-selection" style="display:none;"&amp;gt;&amp;#10;      &amp;lt;%= simple_form_for @user, :url =&amp;gt; "/time_zone", :method =&amp;gt; :put do |f| %&amp;gt;&amp;#10;        &amp;lt;%= f.input :time_zone, :collection =&amp;gt; ActiveSupport::TimeZone.us_zones.map(&amp;amp;:name) %&amp;gt;&amp;#10;        &amp;lt;%= f.submit "Submit" %&amp;gt;&amp;#10;      &amp;lt;% end %&amp;gt;&amp;#10;    &amp;lt;/div&amp;gt;&amp;#10;  &amp;lt;/div&amp;gt;&amp;#10;&amp;lt;% end %&amp;gt;&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	The following jQuery code accompanies the form to make for a nice user interaction.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;$(&amp;#39;button.hide-time-zone-confirmation&amp;#39;).on(&amp;#39;click&amp;#39;, function() &amp;#123;&amp;#10;  document.cookie = &amp;#39;selected_a_time_zone=true;&amp;#39;;&amp;#10;  $(&amp;#39;.time-zone-confirmation&amp;#39;).hide();&amp;#10;&amp;#125;);&amp;#10;&amp;#10;$(&amp;#39;button.show-time-zone-selection&amp;#39;).on(&amp;#39;click&amp;#39;, function() &amp;#123;&amp;#10;  $(&amp;#39;.time-zone-selection&amp;#39;).show();&amp;#10;&amp;#125;);&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	A route is added in &lt;code&gt;routes.rb&lt;/code&gt; to direct the post to the correct controller.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;put "/time_zone" =&amp;gt; "time_zones#update"&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	And lastly, here is the controller code to save the decision.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;def update&amp;#10;  current_user.update_attribute(:time_zone =&amp;gt; params["user"]["time_zone"])&amp;#10;  cookies[:selected_a_time_zone] = true&amp;#10;  redirect_to :back&amp;#10;end&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	To sum up, we first make our best guess as to what time zone the user is in. We then ask the user to either confirm our guess, or select a time zone from a given list. In both cases, a cookie named &lt;code&gt;selected_a_time_zone&lt;/code&gt; is set to &lt;code&gt;true&lt;/code&gt;, which prevents the confirmation form from being displayed in the future. Updating a &lt;code&gt;time_zone&lt;/code&gt; attribute on the &lt;code&gt;current_user&lt;/code&gt; can then be used to correctly display all time-related info.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/YvtCBJZSv8Y" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/using-time-zones-with-rails#When:15:25</feedburner:origLink></item>
		
			<item>
				<title>Rails Engine Testing with RSpec, Capybara, and FactoryGirl</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/4aiuNi6zOdY/rails-engine-testing-with-rspec-capybara-and-factorygirl</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/rails-engine-testing-with-rspec-capybara-and-factorygirl#When:14:15</guid>
				
				<pubDate>Thu, 06 Dec 2012 14:15 GMT</pubDate>
				<dc:creator>Brian Landau</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;&lt;ins&gt;&lt;strong&gt;UPDATED:&lt;/strong&gt; I've updated the instructions based on feedback in the comments suggesting the use of the &lt;code&gt;--dummy-path=spec/dummy --skip-test-unit&lt;/code&gt; options on the &lt;code&gt;rails plugin new&lt;/code&gt; command.&lt;/ins&gt;&lt;/p&gt;

&lt;p&gt;
	Recently, we&amp;#39;ve been doing a lot more with &lt;a href="http://api.rubyonrails.org/classes/Rails/Engine.html"&gt;Rails engines&lt;/a&gt;. We&amp;#39;ve developed a &lt;a href="https://github.com/vigetlabs/redirector"&gt;few&lt;/a&gt; &lt;a href="https://github.com/vigetlabs/active_admin_associations"&gt;engines&lt;/a&gt; that we&amp;#39;ve &lt;a href="https://github.com/vigetlabs/stat_board"&gt;released&lt;/a&gt; publicly, and even more that we use privately on applications. We&amp;#39;ve found it&amp;#39;s a good way to organize and share reusable code across a number of applications.&lt;/p&gt;
&lt;p&gt;
	We really like using &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt;, &lt;a href="http://jnicklas.github.com/capybara/"&gt;Capybara&lt;/a&gt;, and &lt;a href="https://github.com/thoughtbot/factory_girl"&gt;FactoryGirl&lt;/a&gt; to test our Rails applications, and we like to use them to test our engines too. Here&amp;#39;s a few steps to get your new engine up and running with these gems in no time:&lt;/p&gt;

						&lt;ol&gt;
	&lt;li&gt;
		Run &lt;code&gt;rails plugin new ENGINE_NAME --dummy-path=spec/dummy --skip-test-unit --full&lt;/code&gt; or &lt;code&gt;rails plugin new ENGINE_NAME --dummy-path=spec/dummy --skip-test-unit --mountable&lt;/code&gt;. &lt;a href="http://stackoverflow.com/questions/6118905/rails-3-1-engine-vs-mountable-app#answer-6833288" title="Rails 3: Engine vs. Mountable App"&gt;This is a good discussion&lt;/a&gt; of why you&amp;#39;d choose mountable or full engines.&lt;/li&gt;
	&lt;li&gt;
		&lt;p&gt;
			Add these lines to the &lt;code&gt;gemspec&lt;/code&gt; file:&lt;/p&gt;
		&lt;pre&gt;
&lt;code&gt;s.add_development_dependency &amp;#39;rspec-rails&amp;#39;&amp;#10;s.add_development_dependency &amp;#39;capybara&amp;#39;&amp;#10;s.add_development_dependency &amp;#39;factory_girl_rails&amp;#39;&lt;/code&gt;&lt;/pre&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;p&gt;
			Add this line to your &lt;code&gt;gemspec&lt;/code&gt; file:&lt;/p&gt;
		&lt;pre&gt;
&lt;code&gt;s.test_files = Dir["spec/**/*"]&lt;/code&gt;&lt;/pre&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;p&gt;
			Modify &lt;code&gt;Rakefile&lt;/code&gt; to look like this:&lt;/p&gt;
		&lt;pre&gt;
&lt;code&gt;#!/usr/bin/env rake&amp;#10;begin&amp;#10;  require &amp;#39;bundler/setup&amp;#39;&amp;#10;rescue LoadError&amp;#10;  puts &amp;#39;You must `gem install bundler` and `bundle install` to run rake tasks&amp;#39;&amp;#10;end&amp;#10;&amp;#10;APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)&amp;#10;load &amp;#39;rails/tasks/engine.rake&amp;#39;&amp;#10;&amp;#10;Bundler::GemHelper.install_tasks&amp;#10;&amp;#10;Dir[File.join(File.dirname(__FILE__), &amp;#39;tasks/**/*.rake&amp;#39;)].each &amp;#123;|f| load f &amp;#125;&amp;#10;&amp;#10;require &amp;#39;rspec/core&amp;#39;&amp;#10;require &amp;#39;rspec/core/rake_task&amp;#39;&amp;#10;&amp;#10;desc "Run all specs in spec directory (excluding plugin specs)"&amp;#10;RSpec::Core::RakeTask.new(:spec =&amp;gt; &amp;#39;app:db:test:prepare&amp;#39;)&amp;#10;&amp;#10;task :default =&amp;gt; :spec&lt;/code&gt;&lt;/pre&gt;
		&lt;p&gt;
			This will setup your &lt;code&gt;Rakefile&lt;/code&gt; to run your specs and make that the default task. It will also setup the specs to reload the test database just like how it works inside a Rails application.&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;p&gt;
			Create a &lt;code&gt;spec/spec_helper.rb&lt;/code&gt; file:&lt;/p&gt;
		&lt;pre&gt;
&lt;code&gt;ENV[&amp;#39;RAILS_ENV&amp;#39;] ||= &amp;#39;test&amp;#39;&amp;#10;&amp;#10;require File.expand_path("../dummy/config/environment.rb",  __FILE__)&amp;#10;require &amp;#39;rspec/rails&amp;#39;&amp;#10;require &amp;#39;rspec/autorun&amp;#39;&amp;#10;require &amp;#39;factory_girl_rails&amp;#39;&amp;#10;&amp;#10;Rails.backtrace_cleaner.remove_silencers!&amp;#10;&amp;#10;# Load support files&amp;#10;Dir["#&amp;#123;File.dirname(__FILE__)&amp;#125;/support/**/*.rb"].each &amp;#123; |f| require f &amp;#125;&amp;#10;&amp;#10;RSpec.configure do |config|&amp;#10;  config.mock_with :rspec&amp;#10;  config.use_transactional_fixtures = true&amp;#10;  config.infer_base_class_for_anonymous_controllers = false&amp;#10;  config.order = "random"&amp;#10;end&lt;/code&gt;&lt;/pre&gt;
		&lt;p&gt;
			This code requires all the gems you need for writing your specs, loads the dummy application, and configures RSpec.&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;p&gt;
			Finally, add this config to your engine file (lives at &lt;code&gt;lib/my_engine/engine.rb&lt;/code&gt;):&lt;/p&gt;
		&lt;pre&gt;
&lt;code&gt;module MyEngine&amp;#10;  class Engine &amp;lt; ::Rails::Engine&amp;#10;&amp;#10;    config.generators do |g|&amp;#10;      g.test_framework      :rspec,        :fixture =&amp;gt; false&amp;#10;      g.fixture_replacement :factory_girl, :dir =&amp;gt; &amp;#39;spec/factories&amp;#39;&amp;#10;      g.assets false&amp;#10;      g.helper false&amp;#10;    end&amp;#10;&amp;#10;  end&amp;#10;end&lt;/code&gt;&lt;/pre&gt;
		&lt;p&gt;
			Here, we&amp;#39;re telling Rails when generating models, controllers, etc. for your engine to use RSpec and FactoryGirl, instead of the default of &lt;code&gt;Test::Unit&lt;/code&gt; and fixtures&lt;/p&gt;
	&lt;/li&gt;
&lt;/ol&gt;
&lt;hr style="height:6px;margin:30px 0px;" /&gt;
&lt;p&gt;
	After this, you can start writing specs with FactoryGirl factories and integration specs (&lt;a href="https://github.com/jnicklas/capybara#using-capybara-with-rspec"&gt;inside the &lt;code&gt;spec/features&lt;/code&gt; directory&lt;/a&gt;) with Capybara. Have fun testing!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/4aiuNi6zOdY" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/rails-engine-testing-with-rspec-capybara-and-factorygirl#When:14:15</feedburner:origLink></item>
		
			<item>
				<title>Rescuing exceptions without notifications or: How to fail without knowing</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/ifluyKYIrmo/rescuing-exceptions-without-notifications-or-how-to-fail-without-knowing</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/rescuing-exceptions-without-notifications-or-how-to-fail-without-knowing#When:13:30</guid>
				
				<pubDate>Mon, 03 Dec 2012 13:30 GMT</pubDate>
				<dc:creator>Brian Landau</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;
	Have you ever written code like this:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;def my_method&amp;#10;  begin&amp;#10;    object.method_that_can_raise_exception&amp;#10;  rescue Exception&amp;#10;    # some exception handling&amp;#10;  end&amp;#10;end&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	Whenever we write code like this we should stop ourselves and ask: &amp;ldquo;Is this an exception I need to know about?&amp;rdquo; Sometimes the answer is legitimately &amp;ldquo;no&amp;rdquo;, but there are important cases where you need to know about these caught exceptions.&lt;/p&gt;
&lt;p&gt;
	For instance, sometimes you&amp;rsquo;re just rescuing a &lt;code&gt;ActiveRecord::RecordNotFound&lt;/code&gt; error, in these cases you often know exactly why the error happened, and you know exactly what needs to happen because of it. In these very specific cases you have excellent insight into what&amp;rsquo;s happening, and the error you&amp;rsquo;re rescuing is very specific, so silently swallowing these errors is fine.&lt;/p&gt;
&lt;p&gt;
	However, there are some common situations where you need to be aware that exceptions are happening:&lt;/p&gt;

						&lt;h3 id="1_rescuing_a_very_generic_exception_class"&gt;
	1. Rescuing a very generic exception class&lt;/h3&gt;
&lt;p&gt;
	If you&amp;rsquo;re going to be rescuing &lt;code&gt;Exception&lt;/code&gt;,&amp;nbsp; &lt;code&gt;StandardError&lt;/code&gt;,&amp;nbsp; &lt;code&gt;TimeoutError&lt;/code&gt;,&amp;nbsp; &lt;code&gt;IOError&lt;/code&gt;,&amp;nbsp; &lt;code&gt;RuntimeError&lt;/code&gt;, a descendant of &lt;code&gt;SignalException&lt;/code&gt;, or something equally generic, you should probably be notifying yourself of these. If you&amp;rsquo;re going to be rescuing something this generic, it&amp;rsquo;s a signal to yourself that you probably don&amp;rsquo;t know a lot about what can go wrong here or why. Capturing what went wrong is the first step to understanding and solving a problem.&lt;/p&gt;
&lt;h3 id="2_making_a_connection_to_an_external_service"&gt;
	2. Making a connection to an external service&lt;/h3&gt;
&lt;p&gt;
	If you&amp;rsquo;re putting a rescue around a network call to an external service (any service you don&amp;rsquo;t control, and perhaps maybe those you do control but are on separate servers), you should probably notify yourself that something went wrong. Similar to the situation above, you often have little insight (at the time you&amp;rsquo;re writing the code) into why it might fail. The external service may be down, or maybe your servers are having network issues. Whatever the reason, a remedy needs to be found, and the easiest way to start diagnosing the problem is with good insight into went wrong.&lt;/p&gt;
&lt;h3 id="3_mystery_code"&gt;
	3. Mystery code&lt;/h3&gt;
&lt;p&gt;
	Perhaps you&amp;rsquo;re using someone else&amp;rsquo;s library, or maybe some code internal to your application was written long ago and is now legacy code. Whatever the reason, even if you&amp;rsquo;re using a more specific exception class, if you don&amp;rsquo;t know why you need to rescue the exception you should probably be notifying yourself that it&amp;rsquo;s happening.&lt;/p&gt;
&lt;p&gt;
	How you notify yourself and track these errors is entirely up to you. We use &lt;a href="http://airbrake.io/"&gt;Airbrake&lt;/a&gt;, but there are lots of options available including just using ActionMailer. Here&amp;rsquo;s an example of how I might use Airbrake to handle catching an error from an external service:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;module APIClient&amp;#10;&amp;#10;  private&amp;#10;&amp;#10;  def api_call(method, options)&amp;#10;    # network code to external service&amp;#10;  rescue Exception =&amp;gt; &lt;code&gt;exception&lt;/code&gt;&amp;#10;    Airbrake.notify(exception, {&amp;#10;      :component  =&amp;gt; self.class.to_s,&amp;#10;      :action     =&amp;gt; method,&amp;#10;      :url        =&amp;gt; url_of_api_we_are_using,&amp;#10;      :parameters =&amp;gt; options,&amp;#10;      :cgi_data   =&amp;gt; ENV&amp;#10;    })&amp;#10;  end&amp;#10;&amp;#10;end&amp;#10;&amp;#10;class MyAPI&amp;#10;  include APIClient&amp;#10;&amp;#10;  def some_api_method(options)&amp;#10;    # some other code perhaps&amp;#10;    api_call(&amp;#39;api_method&amp;#39;, options)&amp;#10;  end&amp;#10;&amp;#10;end&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	With this notification, I&amp;rsquo;m trying to capture the name of the API (&lt;code&gt;self.class.to_s&lt;/code&gt;), the API endpoint/method called (&lt;code&gt;method&lt;/code&gt;), the exact URL we are hitting (&lt;code&gt;url_of_api_we_are_using&lt;/code&gt;), the options/parameters we&amp;rsquo;re passing to the API (&lt;code&gt;options&lt;/code&gt;), and any &lt;code&gt;ENV&lt;/code&gt; data that might be configured on the server. If you&amp;rsquo;re worried about any portion of this having sensitive data (the &lt;code&gt;options&lt;/code&gt; or the &lt;code&gt;ENV&lt;/code&gt; for instance), you should scrub that data first, or not include that data at all. If you&amp;rsquo;re constructing a large body to post (in an XML API for instance), it can be valuable to capture that too. With Airbrake, I&amp;rsquo;d probably put a large body like that in the hash I pass to &lt;code&gt;:parameters&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;
	For errors not connecting to an external service, there&amp;rsquo;s often a lot less data to report. It might be as simple as this:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;Airbrake.notify(exception, &amp;#123;&amp;#10;  :component  =&amp;gt; self.class.to_s,&amp;#10;  :cgi_data   =&amp;gt; ENV&amp;#10;&amp;#125;)&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	You might, however, have something relevant to put in the &lt;code&gt;:parameters&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;
	Whatever service you choose and data you send though, it&amp;rsquo;s important that you get these notifications and investigate exactly what went wrong. You&amp;rsquo;ll thank yourself later.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/ifluyKYIrmo" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/rescuing-exceptions-without-notifications-or-how-to-fail-without-knowing#When:13:30</feedburner:origLink></item>
		
			<item>
				<title>Simple App Stats with StatBoard</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/b4MRJtCVV3s/simple-app-stats-with-statboard</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/simple-app-stats-with-statboard#When:21:16</guid>
				
				<pubDate>Wed, 28 Nov 2012 21:16 GMT</pubDate>
				<dc:creator>David Eisinger</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;
	We build a lot of small apps here at Viget as part of &lt;a href="http://pointlesscorp.com/"&gt;Pointless Corp&lt;/a&gt;, like &lt;a href="http://speakerrate.com/"&gt;SpeakerRate&lt;/a&gt;, &lt;a href="http://officegam.es/"&gt;OfficeGames&lt;/a&gt;, and &lt;a href="http://babybookie.com/"&gt;BabyBookie&lt;/a&gt;. It&amp;rsquo;s fun to track how many people are using them, and rather than write yet another Rakefile to generate reports, I decided to create a simple &lt;a href="http://edgeapi.rubyonrails.org/classes/Rails/Engine.html"&gt;Rails Engine&lt;/a&gt; to display some basic stats. Announcing, then, &lt;a href="https://github.com/vigetlabs/stat_board"&gt;StatBoard&lt;/a&gt;:&lt;/p&gt;

						&lt;p&gt;
	&lt;img src="https://raw.github.com/vigetlabs/stat_board/master/screenshot.png" style="box-shadow: none" /&gt;&lt;/p&gt;
&lt;p&gt;
	Installation is a cinch: add the gem to your Gemfile, mount the app in &lt;code&gt;routes.rb&lt;/code&gt;, and set the models to query (full instructions available on the &lt;a href="https://github.com/vigetlabs/stat_board#basic-configuration"&gt;GitHub page&lt;/a&gt;). The code itself is embarrassingly simple, so if you have any ideas for improvements, or just want to see how a simple Rails Engine works, take a look.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/b4MRJtCVV3s" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/simple-app-stats-with-statboard#When:21:16</feedburner:origLink></item>
		
			<item>
				<title>Refactoring Patterns: The Rails Middleware Response Handler</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/_aeU-0gvMIQ/refactoring-patterns-the-rails-middleware-response-handler</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/refactoring-patterns-the-rails-middleware-response-handler#When:14:29</guid>
				
				<pubDate>Mon, 26 Nov 2012 14:29 GMT</pubDate>
				<dc:creator>Patrick Reagan</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;
	Recently, I have found myself &lt;a href="http://guides.rubyonrails.org/rails_on_rack.html"&gt;writing more middlewares&lt;/a&gt; to handle responses that need to live outside of the main Rails application. The API that Rack provides works well for something trivial, maybe where you want to allow a load balancer to query the application&amp;#39;s status:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;#10;class HealthCheck&amp;#10;  class Middleware&amp;#10;&amp;#10;    def initialize(application)&amp;#10;      @application = application&amp;#10;    end&amp;#10;&amp;#10;    def call(environment)&amp;#10;      if environment[&amp;#39;PATH_INFO&amp;#39;] == &amp;#39;/health-check&amp;#39;&amp;#10;        if HealthCheck.healthy?&amp;#10;          [200, &amp;#123;&amp;#125;, [&amp;#39;OK&amp;#39;]]&amp;#10;        else&amp;#10;          [500, &amp;#123;&amp;#125;, [&amp;#39;PROBLEM&amp;#39;]]&amp;#10;        end&amp;#10;      else&amp;#10;        @application.call(environment)&amp;#10;      end&amp;#10;    end&amp;#10;  end&amp;#10;end&amp;#10;  &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	I&amp;#39;m sure you&amp;#39;ve seen something similar to the above code in some projects you&amp;#39;ve worked on &amp;mdash; it&amp;#39;s not particularly offensive, so there&amp;#39;s no urgent need to refactor. But what about those times when your middleware is more complex than just a simple health check?&lt;/p&gt;

						&lt;p&gt;
	Consider the example of delivering a mobile-optimized version of your site to your clients:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;#10;module Mobile&amp;#10;  class Format&amp;#10;&amp;#10;    def initialize(application)&amp;#10;      @application = application&amp;#10;    end&amp;#10;&amp;#10;    def call(environment)&amp;#10;      request = Rack::Request.new(environment)&amp;#10;&amp;#10;      user_agent = ::Mobile::UserAgent.new(request.env[&amp;#39;HTTP_USER_AGENT&amp;#39;])&amp;#10;&amp;#10;      if request.params[&amp;#39;mobile&amp;#39;] == &amp;#39;1&amp;#39; || user_agent.mobile?&amp;#10;        request.env[&amp;#39;HTTP_ACCEPT&amp;#39;] = &amp;#39;text/html+mobile&amp;#39;&amp;#10;      end&amp;#10;&amp;#10;      status, headers, body = @application.call(request.env)&amp;#10;&amp;#10;      response = Rack::Response.new(body, status, headers)&amp;#10;      response.finish&amp;#10;    end&amp;#10;  end&amp;#10;end&amp;#10;  &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	Although this code functions as expected, it&amp;#39;s not particularly clear what&amp;#39;s going on to someone who will later need to maintain this codebase. In addition to ensuring that my code works, part of my job as a programmer is to create code that&amp;#39;s easy to understand and, by extension, maintain. Working within the constraints of the middleware API, I might opt for some named abstractions to improve understandability:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;#10;module Mobile&amp;#10;  class Format&amp;#10;&amp;#10;    def initialize(application)&amp;#10;      @application = application&amp;#10;    end&amp;#10;&amp;#10;    def call(environment)&amp;#10;      request = Rack::Request.new(environment)&amp;#10;&amp;#10;      set_mobile_accept_header(request) if serve_mobile?(request)&amp;#10;      response = response(request)&amp;#10;      response.finish&amp;#10;    end&amp;#10;&amp;#10;    private&amp;#10;&amp;#10;    def user_agent(request)&amp;#10;      Mobile::UserAgent.new(request.env[&amp;#39;HTTP_USER_AGENT&amp;#39;])&amp;#10;    end&amp;#10;&amp;#10;    def mobile_requested?(request)&amp;#10;      request.params[&amp;#39;mobile&amp;#39;] == &amp;#39;1&amp;#39;&amp;#10;    end&amp;#10;&amp;#10;    def serve_mobile?(request)&amp;#10;      mobile_requested?(request) || user_agent(request).mobile?&amp;#10;    end&amp;#10;&amp;#10;    def set_mobile_accept_header(request)&amp;#10;      request.env[&amp;#39;HTTP_ACCEPT&amp;#39;] = &amp;#39;text/html+mobile&amp;#39;&amp;#10;    end&amp;#10;&amp;#10;    def response(request)&amp;#10;      status, headers, body = @application.call(request.env)&amp;#10;      Rack::Response.new(body, status, headers)&amp;#10;    end&amp;#10;&amp;#10;  end&amp;#10;end&amp;#10;  &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	This refactoring is a step toward the goals of clarity and maintainability, but this code could still be improved. The passing of &lt;tt&gt;request&lt;/tt&gt; to supporting methods is a code smell. It suffers from two problems &amp;mdash; it decreases the clarity of my named abstractions and it breaks encapsulation. To fix this problem, you might be tempted to store &lt;tt&gt;environment&lt;/tt&gt; as an instance variable and instead lazily load &lt;tt&gt;request&lt;/tt&gt;:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;#10;module Mobile&amp;#10;  class Format&amp;#10;&amp;#10;    def initialize(application)&amp;#10;      @application = application&amp;#10;    end&amp;#10;&amp;#10;    def call(environment)&amp;#10;      @environment = environment&amp;#10;&amp;#10;      set_mobile_accept_header if serve_mobile?&amp;#10;      response.finish&amp;#10;    end&amp;#10;&amp;#10;    private&amp;#10;&amp;#10;    def request&amp;#10;      @request ||= Rack::Request.new(@environment)&amp;#10;    end&amp;#10;&amp;#10;    def user_agent&amp;#10;      Mobile::UserAgent.new(request.env[&amp;#39;HTTP_USER_AGENT&amp;#39;])&amp;#10;    end&amp;#10;&amp;#10;    def mobile_requested?&amp;#10;      request.params[&amp;#39;mobile&amp;#39;] == &amp;#39;1&amp;#39;&amp;#10;    end&amp;#10;&amp;#10;    def serve_mobile?&amp;#10;      mobile_requested? || user_agent.mobile?&amp;#10;    end&amp;#10;&amp;#10;    def set_mobile_accept_header&amp;#10;      request.env[&amp;#39;HTTP_ACCEPT&amp;#39;] = &amp;#39;text/html+mobile&amp;#39;&amp;#10;    end&amp;#10;&amp;#10;    def response&amp;#10;      status, headers, body = @application.call(request.env)&amp;#10;      Rack::Response.new(body, status, headers)&amp;#10;    end&amp;#10;&amp;#10;  end&amp;#10;end&amp;#10;  &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	While it looks like this solves our problems, lazily loading &lt;tt&gt;request&lt;/tt&gt; actually introduces a subtle bug. Because the value is memoized across all requests, the first request to this middleware will determine the result for subsequent requests. This means if the first client is to be served the mobile version of the site, then all other clients will see that version as well.&lt;/p&gt;
&lt;p&gt;
	Out of the options I&amp;#39;ve explored above, none are viable solutions for a production application. Instead, I opt for an approach that I&amp;#39;ve found successful on some of our recent projects that I have been calling the "middleware response handler":&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;#10;module Mobile&amp;#10;  class Format&amp;#10;&amp;#10;    def initialize(application)&amp;#10;      @application = application&amp;#10;    end&amp;#10;&amp;#10;    def call(environment)&amp;#10;      responder = Mobile::Format::Responder.new(@application, environment)&amp;#10;      responder.respond&amp;#10;    end&amp;#10;&amp;#10;    class Responder&amp;#10;&amp;#10;      def initialize(application, environment)&amp;#10;        @application = application&amp;#10;        @environment = environment&amp;#10;      end&amp;#10;&amp;#10;      def respond&amp;#10;        set_mobile_accept_header if serve_mobile?&amp;#10;        response.finish&amp;#10;      end&amp;#10;&amp;#10;      private&amp;#10;&amp;#10;      def request&amp;#10;        @request ||= Rack::Request.new(@environment)&amp;#10;      end&amp;#10;&amp;#10;      def user_agent&amp;#10;        ::Mobile::UserAgent.new(request.env[&amp;#39;HTTP_USER_AGENT&amp;#39;])&amp;#10;      end&amp;#10;&amp;#10;      def mobile_requested?&amp;#10;        request.params[&amp;#39;mobile&amp;#39;] == &amp;#39;1&amp;#39;&amp;#10;      end&amp;#10;&amp;#10;      def serve_mobile?&amp;#10;        mobile_requested? || user_agent.mobile?&amp;#10;      end&amp;#10;&amp;#10;      def set_mobile_accept_header&amp;#10;        request.env[&amp;#39;HTTP_ACCEPT&amp;#39;] = &amp;#39;text/html+mobile&amp;#39;&amp;#10;      end&amp;#10;&amp;#10;      def response&amp;#10;        @response ||= begin&amp;#10;          status, headers, body = @application.call(request.env)&amp;#10;          Rack::Response.new(body, status, headers)&amp;#10;        end&amp;#10;      end&amp;#10;    end&amp;#10;  end&amp;#10;end&amp;#10;  &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	The key change here is that by introducing the &lt;tt&gt;Mobile::Format::Responder&lt;/tt&gt; class that encapsulates &lt;tt&gt;environment&lt;/tt&gt;, I can more easily perform an extract method refactoring and improve the readability of this code. Additionally, each time that this middleware is invoked, I&amp;#39;m guaranteed to have a new instance of the responder &amp;mdash; I won&amp;#39;t see state bleeding over from previous requests. In my experience on projects like &lt;a href="http://viget.com/work/puma"&gt;Puma&lt;/a&gt;, &lt;a href="http://viget.com/work/time-life"&gt;TimeLife&lt;/a&gt;, and &lt;a href="http://www.shure.com/americas"&gt;Shure&lt;/a&gt;, this strategy has been a great way to significantly improve the maintainability of our middleware code.&lt;/p&gt;
&lt;p&gt;
	&lt;em&gt;The above code is also &lt;a href="https://gist.github.com/4125732"&gt;available as a Gist&lt;/a&gt; for your forking pleasure.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/_aeU-0gvMIQ" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/refactoring-patterns-the-rails-middleware-response-handler#When:14:29</feedburner:origLink></item>
		
			<item>
				<title>Server Maintenance Mode for Rails, Capistrano and Apache2</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/CGWgW5nScEg/server-maintenance-mode-for-rails-capistrano-and-apache2</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/server-maintenance-mode-for-rails-capistrano-and-apache2#When:03:09</guid>
				
				<pubDate>Tue, 06 Nov 2012 03:09 GMT</pubDate>
				<dc:creator>Ryan Foster</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;
	It&amp;#39;s a good idea to have a server maintenance strategy in place during the early phases of any project.&amp;nbsp; Along with CI, provisioning multiple stages, and an efficient way to deploy new features to the client and eventually to production, a strategy for server maintenance from the outset of the project will save time as the application ages.&lt;/p&gt;

						&lt;p&gt;
	If your Rails app is already in the wild, no worries.&amp;nbsp; Here are a few easy steps to modify Apache to detect a maintenance mode and a Capistrano task to turn it on and off.&lt;/p&gt;
&lt;p&gt;
	First, you&amp;#39;ll need to add these lines to you Apache virtual host configuration:&lt;/p&gt;
&lt;pre&gt;
RewriteEngine On&amp;#10;ErrorDocument 503 /system/maintenance.html&amp;#10;RewriteCond %{REQUEST_URI} !.(css|gif|jpg|png)$&amp;#10;RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f&amp;#10;RewriteCond %{SCRIPT_FILENAME} !maintenance.html&amp;#10;RewriteRule ^.*$ - [L,R=503]&lt;/pre&gt;
&lt;p&gt;
	This tells Apache to bypass the app when it detects the presence of a maintenance file.&amp;nbsp; Instead of serving the request, it will return the maintenance page with the status code 503.&amp;nbsp; If Apache is already running, you&amp;#39;ll want to restart it before you try to roll it into maintenance mode.&lt;/p&gt;
&lt;p&gt;
	Next, you&amp;#39;ll want to create a maintenance page for your app.&amp;nbsp; A good place to put the file is &lt;code&gt;/public/maintenance.html&lt;/code&gt;.&amp;nbsp; Remember, the page will bypass Rails completely, so make sure it&amp;#39;s a fully valid HTML file (although the rewrite rules will still serve CSS and image files).&lt;/p&gt;
&lt;p&gt;
	Last, add two Capistrano tasks to turn maintenance mode on and off. &amp;nbsp;The first copies the maintenance page to the place where Apache will start serving it. &amp;nbsp;The second will remove it. &amp;nbsp;Add these lines to deploy.rb:&lt;/p&gt;
&lt;pre&gt;
namespace :deploy&amp;#10;  namespace :web do&amp;#10;    desc "Enable maintenance mode for apache"&amp;#10;    task :disable, :roles =&amp;gt; :web do&amp;#10;      on_rollback { run "rm -f #{shared_path}/system/maintenance.html" }&amp;#10;      page = File.read(&amp;#39;public/maintenance.html&amp;#39;)&amp;#10;      put page, "#{shared_path}/system/maintenance.html", :mode =&amp;gt; 0644&amp;#10;    end&amp;#10;&amp;#10;    desc "Disable maintenance mode for apache"&amp;#10;    task :enable, :roles =&amp;gt; :web do&amp;#10;      run "rm -f #{shared_path}/system/maintenance.html"&amp;#10;    end&amp;#10;  end&amp;#10;end&lt;/pre&gt;
&lt;p&gt;
	Now when you want to set a stage into maintenance mode (integration in this example), just run the task:&lt;/p&gt;
&lt;pre&gt;
cap integration deploy:web:disable&lt;/pre&gt;
&lt;p&gt;
	To disable maintenance mode, run:&lt;/p&gt;
&lt;pre&gt;
cap integration deploy:web:enable&lt;/pre&gt;
&lt;p&gt;
	And there you have it: maintenance mode, easy mode.&lt;/p&gt;
&lt;p&gt;
	A few caveats:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;
		&amp;nbsp;Make sure the shared path for Capistrano has a system directory.&amp;nbsp; Otherwise, you&amp;#39;ll get an error writing the maintenance file there.&lt;/li&gt;
	&lt;li&gt;
		Be careful if there is a load balancer in front of your app servers.&amp;nbsp; It might be configured NOT to serve 503s, but instead start ignoring that app server.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
	A few links I used to write this post:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;
		&lt;a href="http://bitly.com/ccJwKS"&gt;Stack Overflow post&lt;/a&gt; on the cap task for maintenance mode.&lt;/li&gt;
	&lt;li&gt;
		&lt;a href="http://bitly.com/PSQ5dU"&gt;Gist&lt;/a&gt; for the suggested Capistrano maintenance check.&lt;/li&gt;
	&lt;li&gt;
		The &lt;a href="https://github.com/capistrano/capistrano"&gt;Capistrano&lt;/a&gt; tasks used to exist but have &lt;a href="https://github.com/capistrano/capistrano/commit/4ece7902d5058c3c0222fe4d198c33b4eaf7110b"&gt;since been removed&lt;/a&gt;. &amp;nbsp;&lt;a href="https://github.com/tvdeyen/capistrano-maintenance"&gt;This gem&lt;/a&gt; will add them back.&lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/CGWgW5nScEg" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/server-maintenance-mode-for-rails-capistrano-and-apache2#When:03:09</feedburner:origLink></item>
		
			<item>
				<title>Client-Side Separation of Concerns: Are We Doing It Wrong?</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/TjDiDI-OUtw/client-side-separation-of-concerns-are-we-doing-it-wrong</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/client-side-separation-of-concerns-are-we-doing-it-wrong#When:13:40</guid>
				
				<pubDate>Wed, 31 Oct 2012 13:40 GMT</pubDate>
				<dc:creator>Doug Avery</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;
	&lt;a href="http://en.wikipedia.org/wiki/Separation_of_concerns#Origin"&gt;Separation of Concerns&lt;/a&gt; is a programming principle that encourages grouping functionality in ways that reduce overlap. &amp;#39;Concern&amp;#39; is loosely defined - Wikipedia describes it as &amp;#39;any piece of interest&amp;#39;, like a behavior or piece of functionality. The core concept is that by improving the separation of concerns, you improve a program&amp;#39;s clarity and durability. Actual separation is done in three ways:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		&lt;strong&gt;Encapsulation&lt;/strong&gt; &amp;mdash; bundling the concern as a single idea, in a single place&lt;/li&gt;
	&lt;li&gt;
		&lt;strong&gt;Modularity&lt;/strong&gt; &amp;mdash; making concerns portable and independent&lt;/li&gt;
	&lt;li&gt;
		&lt;strong&gt;&lt;a href="http://en.wikipedia.org/wiki/Information_hiding"&gt;Information Hiding&lt;/a&gt;&lt;/strong&gt;&amp;nbsp;&amp;mdash; smoothing concern interaction by providing interfaces between them&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Using these methods, you increase the separation of your concerns, and strengthen your system. Easy enough in programming, but how do we apply this principle when working on the client side &amp;mdash; that is, CSS/HTML/JS?&lt;/p&gt;
&lt;p&gt;
	I always thought I knew, but in the past few years, some new challenges caused me to rethink the approach. To explain, I&amp;#39;ll start by examining the most common SoC model: &lt;strong&gt;Content, Presentation, Behavior.&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;

						&lt;h3&gt;
	The Classics: CPB&lt;/h3&gt;
&lt;p&gt;
	If you haven&amp;#39;t heard of the SoC principle, you&amp;#39;ve probably heard of the three &amp;#39;layers&amp;#39; of Content, Presentation, and Behavior. These are the three classic concerns that front-end developers are taught to keep separate. &lt;em&gt;How&lt;/em&gt; to separate them is another matter, owing to some interpretation.&amp;nbsp;Here&amp;#39;s the version I learned:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		The concerns are divided into their own files (and languages)&lt;/li&gt;
	&lt;li&gt;
		The content (markup) is dumb &amp;mdash; that is, style- and behavior-agnostic. Usually, this means writing it first, and only minimally changing it to accommodate JS and CSS when necessary.&lt;/li&gt;
	&lt;li&gt;
		Classes are content-oriented, not presentational (&amp;#39;additional-info&amp;#39; vs. &amp;#39;right-col&amp;#39;)&lt;/li&gt;
	&lt;li&gt;
		Elements are styled using clever selectors and the cascade&lt;/li&gt;
	&lt;li&gt;
		JavaScript is unobtrusive &amp;mdash; it selects, operates on, and injects markup to aid behaviors&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	This should look familiar; it&amp;#39;s the classic &amp;#39;best practice&amp;#39; for front-end work. Comparing it with the first three bullets about SoC, how does it stack up?&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		&lt;strong&gt;Encapsulation&lt;/strong&gt; &amp;mdash; check. Concerns are clearly encapsulated.&lt;/li&gt;
	&lt;li&gt;
		&lt;strong&gt;Modularity&lt;/strong&gt; &amp;mdash; arguable. While there&amp;#39;s a degree of portability (see CSS Zen Garden), it depends on having a very consistent markup structure, which brings us to...&lt;/li&gt;
	&lt;li&gt;
		&lt;strong&gt;Information Hiding&lt;/strong&gt; &amp;mdash; the big missing piece with the classic, &amp;#39;markup-first&amp;#39; separation of CPB. Dumb markup, markup that&amp;#39;s written solely for content and not for presentation or behavior,&lt;em&gt;&amp;nbsp;doesn&amp;#39;t provide an interface.&lt;/em&gt;&amp;nbsp;By doing this, it simply offloads the complexity to CSS and JS, which have to parse and select it in clever ways. This leads to all the problems SoC is supposed to prevent &amp;mdash; brittleness, overrides, excessive coupling.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	This issue &amp;mdash; exactly &lt;em&gt;how &lt;/em&gt;to separate content, presentation, and behavior &amp;mdash; is at the heart of new CSS strategies like &lt;a href="http://coding.smashingmagazine.com/2011/12/12/an-introduction-to-object-oriented-css-oocss/"&gt;OOCSS&lt;/a&gt; and &lt;a href="http://smacss.com/"&gt;SMACSS&lt;/a&gt;. The traditional wisdom that dumb markup is good markup is under seige.&lt;/p&gt;
&lt;p&gt;
	So, maybe we don&amp;#39;t know exactly how to separate our concerns. But let&amp;#39;s step back &amp;mdash; why are content, presentation, and behavior our primary concerns in the first place?&lt;/p&gt;
&lt;h3&gt;
	Are they the right ones?&lt;/h3&gt;
&lt;p&gt;
	CPB is certainly an appropriate concern set for documents, where the content is core and CSS/JS just &amp;#39;theme&amp;#39; it. This problem domain is what HTML was designed for, and it&amp;#39;s what most of us started our careers writing. The question, though: is CPB is right for a Rails site with 100+ views, an all-JS chat application, an online store, or a web-only game?&lt;/p&gt;
&lt;p&gt;
	If not CPB, then what? To take a cue from programming, maybe the right concerns are simply the aspects of your buildout, and your task should be to determine those aspects and how best to separate them. Once you understand your concerns, the task is not how to separate them along the CSS/JS/HTML lines, but to separate them from &lt;em&gt;eachother.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;
	Easier said than done, right? How do we identify concerns, and how do we detangle them? The rest of this post is just that &amp;mdash; some loose definitions of common concerns, and some very stripped-down examples of how a dev could improve their separation.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;
	New concerns&lt;/h3&gt;
&lt;h4&gt;
	Layout&lt;/h4&gt;
&lt;p&gt;
	&lt;a href="http://www.blueprintcss.org/"&gt;Blueprint,&lt;/a&gt; now 5 years old, was one of the first examples of client-side devs addressing a new concern &amp;mdash; Layout. It&amp;#39;s still one of the easiest concerns to abstract out from your build, and Blueprint has numerous competing frameworks that accomplish the same goal. The concept is simple: using presentational, layout-only classes separates the problem of visually &lt;em&gt;structuring&lt;/em&gt; your design from the task of visually &lt;em&gt;styling&lt;/em&gt; it.&lt;/p&gt;
&lt;h5&gt;
	Unseparated:&lt;/h5&gt;
&lt;p&gt;
	In this example, the &lt;strong&gt;article&lt;/strong&gt; type dictates a layout behavior for the &lt;strong&gt;additional-info&lt;/strong&gt; box. In some cases, this kind of behavior needlessly entangles two concerns that aren&amp;#39;t otherwise related.&lt;/p&gt;
&lt;pre&gt;
  .news-article .additional-info,&amp;#10;  .blog-article .additional-info {&amp;#10;    background: url(&amp;#39;more-news.png&amp;#39;);&amp;#10;    float: right;&amp;#10;    width: 320px;&amp;#10;  }&amp;#10;&lt;/pre&gt;
&lt;h5&gt;
	Separated:&lt;/h5&gt;
&lt;p&gt;
	By definining a &amp;#39;layout&amp;#39; to control this behavior, we can separate this responsibility more clearly. This makes the layout itself more portable, and cleans up the article-specific styles.&lt;/p&gt;
&lt;pre&gt;
  .wide-layout .aside-col {&amp;#10;    float: right;&amp;#10;    width: 320px;&amp;#10;  }&amp;#10;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h4&gt;
	Page&lt;/h4&gt;
&lt;p&gt;
	What page is a user on? Why does it matter? To separate the page as a concern, we have to consider how much control the current &amp;#39;location&amp;#39; of a user has over our design, and whether that control is warranted. It&amp;#39;s too easy let the Page micro-manage other concerns, which is unfortunate, because the Page is pretty bad at it &amp;mdash; reduce Page responsibilities whenever you can.&lt;/p&gt;
&lt;h5&gt;
	Unseparated:&lt;/h5&gt;
&lt;p&gt;
	In this example, the about and contact pages have a special contact form that appears the footer. The design calls for some additional padding above the form. You might think to handle it this way:&lt;/p&gt;
&lt;pre&gt;
  .about-page .footer,&amp;#10;  .contact-page .footer {&amp;#10;    padding-top: 30px;&amp;#10;  }&amp;#10;&lt;/pre&gt;
&lt;h5&gt;
	Separated:&lt;/h5&gt;
&lt;p&gt;
	...but really, it&amp;#39;s the &lt;em&gt;form&lt;/em&gt;, not the page, that makes the difference. Using the page class just because it&amp;#39;s there might be convenient, but it couples two very different concerns badly. Instead, we can give the footer the ability to modify itself, using a smart name that tells us why the modification is necessary:&lt;/p&gt;
&lt;pre&gt;
  .form-footer {&amp;#10;    padding-top: 30px;&amp;#10;  }&amp;#10;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h4&gt;
	Component&lt;/h4&gt;
&lt;p&gt;
	A reusable, portable, piece of the interface (this one should look pretty familiar).&lt;/p&gt;
&lt;p&gt;
	At the very least, you can give components a consistent interface in all three languages (by naming them), but you can go further by isolating their bits (CSS, JS, images, possibly markup as a template/partial) into a single directory. Give them subclasses for variations, instead of relying on the cascade or the DOM context. If you find that they interact with other components too much, give them a top-level object to talk to instead.&lt;/p&gt;
&lt;p&gt;
	&lt;em&gt;Each component is a concern&lt;/em&gt;, however minor. The key to durable components is separating them correctly from your other concerns.&lt;/p&gt;
&lt;h5&gt;
	Unseparated:&lt;/h5&gt;
&lt;p&gt;
	There are a few problems here. First, the component has mis-matching names throughout. Second, a supposedly self-contained component is scattered between several different, larger files. Third, the component itself reaches out to the Page.&lt;/p&gt;
&lt;pre&gt;
  // show.html.erb&amp;#10;  &amp;lt;ul class="photos"&amp;gt;&amp;#10;    &amp;lt;% @post.images.each do |img| %&amp;gt;&amp;#10;      &amp;lt;li&amp;gt;&amp;lt;%= image_tag(img) %&amp;gt;&amp;lt;/li&amp;gt;&amp;#10;    &amp;lt;% end %&amp;gt;&amp;#10;  &amp;lt;/ul&amp;gt;&amp;#10;&amp;#10;  // application.js&amp;#10;  $.fn.carousel = function(methodName) {&amp;#10;    if ($(body).hasClass(&amp;#39;gallery&amp;#39;)) {&amp;#10;      addPagers(this);&amp;#10;    }&amp;#10;    ...&amp;#10;  };&amp;#10;&amp;#10;  $(&amp;#39;.photos&amp;#39;).carousel();&amp;#10;&amp;#10;  // application.css.scss&amp;#10;  .js .photos {...}&amp;#10;&lt;/pre&gt;
&lt;h5&gt;
	Separated:&lt;/h5&gt;
&lt;p&gt;
	This concern can be cleaned up with some renaming, some new files, and a small interface provided by a data-attribute. Now, it&amp;#39;s much more neatly encapsulated.&lt;/p&gt;
&lt;pre&gt;
  // _carousel.html.erb&amp;#10;  &amp;lt;ul class="carousel" data-pagers="true"&amp;gt;&amp;#10;    &amp;lt;% images.each do |img| %&amp;gt;&amp;#10;      &amp;lt;li&amp;gt;&amp;lt;%= image_tag(img) %&amp;gt;&amp;lt;/li&amp;gt;&amp;#10;    &amp;lt;% end %&amp;gt;&amp;#10;  &amp;lt;/ul&amp;gt;&amp;#10;&amp;#10;  // components/carousel/scripts.js&amp;#10;  $.fn.carousel = function(methodName) {&amp;#10;    var options = ({}, $(this).data());&amp;#10;    options.pagers &amp;amp;&amp;amp; addPagers(this);&amp;#10;    ...&amp;#10;  };&amp;#10;&amp;#10;  $(&amp;#39;.photos&amp;#39;).carousel();&amp;#10;&amp;#10;  // components/carousel/styles.css.scss&amp;#10;  .carousel {...}&amp;#10;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h4&gt;
	Content&lt;/h4&gt;
&lt;p&gt;
	When I say Content, I don&amp;#39;t mean &amp;#39;everything on the page&amp;#39; &amp;mdash; there&amp;#39;s a big distinction between blocks of big, readable, WYSIWYGable text and the other stuff. WYSWIGable areas are &lt;em&gt;wildly&lt;/em&gt; unpredictable. They&amp;#39;re constantly breaking out of their boxes, using incorrect&amp;nbsp;heading tags, vomiting out iframes, and worse, they have tons of completely unclassed markup that you&amp;#39;re suppose to anticipate and make pretty.&lt;/p&gt;
&lt;p&gt;
	The traditional stylesheet wisdom is to style all your baseline elements first, and override those styles for other components, but this mixes the concerns (content, component) pretty badly. One way to detangle them is to apply Content styles/behaviors only in specific contexts:&lt;/p&gt;
&lt;h5&gt;
	Unseparated:&lt;/h5&gt;
&lt;p&gt;
	Setting the baseline styles up front means that later, we have to unset them. In this case, that means that every UL on the site is tied to this one &amp;mdash; when this UL changes, they might all have to change with it.&lt;/p&gt;
&lt;pre&gt;
  // show.html.erb:&amp;#10;  &amp;lt;%= @post.content %&amp;gt;&amp;#10;&amp;#10;  // application.css.scss&amp;#10;  h2 {&amp;#10;    font-size: 20px;&amp;#10;    margin: 0 0 15px;&amp;#10;  }&amp;#10;&amp;#10;  p {&amp;#10;    margin: 0.4em 0;&amp;#10;  }&amp;#10;&amp;#10;  ul {&amp;#10;    list-style-type: disc;&amp;#10;    margin-left: 20px;&amp;#10;  }&amp;#10;&amp;#10;  .sidebar p {&amp;#10;    margin: 0;&amp;#10;  }&amp;#10;&amp;#10;  .sidebar ul {&amp;#10;    list-style-type: none;&amp;#10;    margin-left: 0;&amp;#10;  }&lt;/pre&gt;
&lt;h5&gt;
	Separated:&lt;/h5&gt;
&lt;p&gt;
	Now that Content is treated like a separate concern, things clean up quite a bit. We can now safely work on styles inside .txt areas without worrying about how they affect other concerns in the interface.&lt;/p&gt;
&lt;pre&gt;
  // show.html.erb:&amp;#10;  &amp;lt;div class="txt"&amp;gt;&amp;#10;    &amp;lt;%= @post.content %&amp;gt;&amp;#10;  &amp;lt;/div&amp;gt;&amp;#10;&amp;#10;  // application.css.scss&amp;#10;  h2, &amp;#10;  p, &amp;#10;  ul {&amp;#10;    list-style-type: none;&amp;#10;    margin: 0;&amp;#10;  }&amp;#10;&amp;#10;  .txt {&amp;#10;    h2 {&amp;#10;      font-size: 20px;&amp;#10;      margin: 0 0 15px;&amp;#10;    }&amp;#10;&amp;#10;    p {&amp;#10;&amp;nbsp;&amp;nbsp;&amp;nbsp;   margin: 0.4em 0;&amp;#10;  &amp;nbsp; }&amp;#10;&amp;#10;&amp;nbsp;   ul {&amp;#10;&amp;nbsp;&amp;nbsp;&amp;nbsp;   list-style-type: disc;&amp;#10;  &amp;nbsp;&amp;nbsp;&amp;nbsp; margin-left: 20px;&amp;#10;  &amp;nbsp; }&amp;#10;  }&amp;#10;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h4&gt;
	Window&lt;/h4&gt;
&lt;p&gt;
	With responsive design, changes to the window become important information that informs both behavior and style. It&amp;#39;s easy to start mixing in media queries and window.innerWidth checks to your code, but the further down this path you go, the more Window starts to feel like its own concern.&lt;/p&gt;
&lt;h5&gt;
	Unseparated:&lt;/h5&gt;
&lt;p&gt;
	This code doesn&amp;#39;t look terrible, but it scales poorly. The window clearly has a special state (&amp;lt;320px), but there&amp;#39;s no communication about what this state means, and the logic for it might need to be re-applied across many instances. The Gallery actually binds a window-size check to the window itself.&lt;/p&gt;
&lt;pre&gt;
  @media screen and (max-width: 320px) {&amp;#10;    .content,&amp;#10;    .aside,&amp;#10;    .callouts .col,&amp;#10;    .nav {&amp;#10;      float: none;&amp;#10;    }&amp;#10;  }&amp;#10;&amp;#10;  var Gallery = function() {&amp;#10;    $(window).resize(function() {&amp;#10;      if(this.enabled &amp;amp;&amp;amp; window.innerWidth &amp;lt; 320) {&amp;#10;        this.disable();&amp;#10;      }&amp;#10;    }&amp;#10;    ...&amp;#10;  }&amp;#10;&lt;/pre&gt;
&lt;h5&gt;
	Separated:&lt;/h5&gt;
&lt;p&gt;
	The separated version moves responsibility to an &amp;#39;appWindow&amp;#39; object that publishes events out to any listening components with some help from&amp;nbsp;a super-dumb &amp;nbsp;&lt;a href="http://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjavascript"&gt;pub/sub-type pattern&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;
  @media screen and (max-width: 320px) {&amp;#10;    .stack-at-phone {&amp;#10;      float: none;&amp;#10;    }&amp;#10;  }&amp;#10;&amp;#10;  ...&amp;#10;&amp;#10;  appWindow = {&amp;#10;    subscribers: [],&amp;#10;    prevWidth: $(window).width(),&amp;#10;&amp;#10;    init: function() {&amp;#10;      $(window).resize(this.checkWidth.bind(this));&amp;#10;      this.checkWidth();&amp;#10;    }, &amp;#10;&amp;#10;    checkWidth: function() {&amp;#10;      var width = $(window).width();&amp;#10;      var sizingDown = width &amp;lt; 320 &amp;amp;&amp;amp; t&amp;#8203;his.prevWidth &amp;gt; 320;&amp;#10;      var sizingUp   = width &amp;gt; 320 &amp;amp;&amp;amp; t&amp;#8203;his.prevWidth &amp;lt; 320;&amp;#10;      sizingUp   &amp;amp;&amp;amp; this.publish(&amp;#39;phone&amp;#39;);&amp;#10;      sizingDown &amp;amp;&amp;amp; this.publish(&amp;#39;unphone&amp;#39;);&amp;#10;      this.prevWidth = width;&amp;#10;    },&amp;#10;&amp;#10;    publish: function(eventName) {&amp;#10;&amp;nbsp;&amp;nbsp;&amp;nbsp;   $.each(appWindow.subscribers, function() {&amp;#10;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   this();&amp;#10;&amp;nbsp;&amp;nbsp;&amp;nbsp;   });&amp;#10;&amp;nbsp;   },&amp;#10;&amp;#10;    subscribe: function(method) {&amp;#10;      this.subscribers.push(method);&amp;#10;    },&amp;#10;    &amp;#10;    ...&amp;#10;  };&amp;#10;&amp;#10;  var Gallery = function() {&amp;#10;    appWindow.subscribe(&amp;#39;phone&amp;#39;, this.disable);&amp;#10;    appWindow.subscribe(&amp;#39;unphone&amp;#39;, this.enable);&amp;#10;    ...&amp;#10;  };&amp;#10;&amp;#10;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h4&gt;
	Tracking&lt;/h4&gt;
&lt;p&gt;
	If you&amp;#39;re serious about tracking users&amp;#39; web use with GA (&lt;a href="http://viget.com/?ACT=33&amp;amp;result_page=advance/search&amp;amp;collection=blog&amp;amp;search_mode=all&amp;amp;loose_ends=yes&amp;amp;site_id=1&amp;amp;keywords=google%20analytics"&gt;we are!&lt;/a&gt;), you&amp;#39;ll know that tracking often puts its stubby fingers into the many pies of your other concerns. Good analytics folk want to track all kinds of interactions &amp;mdash; page resizes, carousel navigation, scroll distance, you name it &amp;mdash; and it can lead to a lot of disparate JS sprinkled around your application.&lt;/p&gt;
&lt;p&gt;
	&lt;em&gt;Because&lt;/em&gt; so many concerns need tracking, it can be hard to completely separate them, but you can at least encapsulate everything you can into a single object. Using a plugin like &lt;a href="http://viget.com/advance/trackiffer-ga-events-made-easier"&gt;Trackiffer&lt;/a&gt;, or the data-track-event approach, you can even wire your markup straight to your tracking with a thin interface.&lt;/p&gt;
&lt;h5&gt;
	Unseparated:&lt;/h5&gt;
&lt;p&gt;
	Finding and binding markup like this is unmaintainable at a certain scale. Calling _gaq.push directly also gets tricky past a point &amp;mdash; it hamstrings you when you want to add transformations or filtering to your tracking (for example, escaping characters).&lt;/p&gt;
&lt;pre&gt;
  // analytics.js&amp;#10;  $(&amp;#39;.callouts a&amp;#39;).click(function() {&amp;#10;    _gaq.push([&amp;#39;_trackEvent&amp;#39;, &amp;#39;Callout&amp;#39;, $(this).text()]);&amp;#10;  });&amp;#10;&amp;#10;   // gallery.js&amp;#10;  gallery.$pager.click(function() {&amp;#10;    _gaq.push([&amp;#39;_trackEvent&amp;#39;, &amp;#39;Gallery&amp;#39;, &amp;#39;Page&amp;#39;]);&amp;#10;  });&amp;#10;&lt;/pre&gt;
&lt;h5&gt;
	Separated:&lt;/h5&gt;
&lt;p&gt;
	Separation here is a matter of creating interfaces. First, between the markup and the tracking concern; allowing the markup to explicity talk to the tracking. Second, between everything else and the tracking concern &amp;mdash; creating a helpful object that can parse tracking data, watch for clicks, and take over the responsibility of tracking from other modules.&lt;/p&gt;
&lt;pre&gt;
  // show.html.erb&amp;#10;  &amp;lt;a href="#" data-track-event="Callout|Rebate"&amp;gt;Rebate&amp;lt;/a&amp;gt;&amp;#10;&amp;#10;  // gallery.js&amp;#10;  analytics.watch(this.$pager, &amp;#39;Gallery&amp;#39;, &amp;#39;Page&amp;#39;);&amp;#10;&amp;#10;  // analytics.js&amp;#10;  $(&amp;#39;body&amp;#39;).on(&amp;#39;click&amp;#39;, &amp;#39;a[data-track-event]&amp;#39;, analytics.track);&amp;#10;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h3&gt;
	Closing&lt;/h3&gt;
&lt;p&gt;
	I hope these points and examples, if nothing else, affected how you think about concerns in the context of front-end development. If you have any specifics you&amp;#39;d like to discuss, please add them to the comments.&lt;/p&gt;
&lt;h3&gt;
	Further reading:&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;
		More thoughts on SoC, CSS, and HTML from &lt;a href="http://coding.smashingmagazine.com/2012/04/20/decoupling-html-from-css/"&gt;Jonathan Snook&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;
		Andy Hume&amp;#39;s SXSW talk &lt;a href="https://speakerdeck.com/u/andyhume/p/css-for-grown-ups-maturing-best-practises"&gt;CSS For Grownups&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;
		Jeremy Keith&amp;#39;s 2006 ALA article about the &lt;a href="http://www.alistapart.com/articles/behavioralseparation"&gt;CPB Separation&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;
		Neils Matthjis writing about &lt;a href="http://coding.smashingmagazine.com/2012/10/23/road-reusable-html-components/"&gt;HTML Components&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/TjDiDI-OUtw" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/client-side-separation-of-concerns-are-we-doing-it-wrong#When:13:40</feedburner:origLink></item>
		
			<item>
				<title>Testing Google Analytics with PhantomJS</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/eUieHpuQOQc/testing-google-analytics-with-phantomjs</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/testing-google-analytics-with-phantomjs#When:16:19</guid>
				
				<pubDate>Wed, 17 Oct 2012 16:19 GMT</pubDate>
				<dc:creator>Nate Hunzaker</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;
	Google Analytics is a great tool for tracking events happening on your website. Yet ensuring that correct information is being recorded can be a tedious task. For my most recent engagement I needed to add analytics support to a large number of pages with challengingly different environments. There was a constant worry that some rules would collide with others or not fire correctly when juxtaposed with existing scripts.&lt;/p&gt;
&lt;p&gt;
	Navigating page-by-page to ensure stability can provide solid verification that code is working properly. However, when working with a nontrivial amount of pages, manually conducting this work is time-consuming and daunting.&lt;/p&gt;
&lt;p&gt;
	Cue &lt;a href="http://phantomjs.org/"&gt;PhantomJS&lt;/a&gt;, a headless WebKit browser designed for page automation and browser-based JavaScript testing. When coupled with &lt;a href="http://sinonjs.org/"&gt;SinonJS&lt;/a&gt; spies and the &lt;a href="http://visionmedia.github.com/mocha/"&gt;Mocha&lt;/a&gt; testing framework the difference between testing a single page and twenty at a time became marginal.&lt;/p&gt;
&lt;p&gt;
	I&amp;#39;d like to go over these technologies in detail and provide a basic tutorial of our methodology.&lt;/p&gt;

						&lt;h2&gt;
	What is a headless browser?&lt;/h2&gt;
&lt;p&gt;
	PhantomJS runs without a graphic interface. It can navigate as if it were Google Chrome or Safari without actually having to open a window. This is a great boon to JavaScript testing as it provides quick access to a browser-based environment with a simple API to automate page navigation and JavaScript interaction.&lt;/p&gt;
&lt;div class="highlight"&gt;
	&lt;pre&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"webpage"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&amp;#10;&amp;#10;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"http://google.com"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&amp;#10;&amp;#10;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&amp;#10;    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Something went horribly wrong!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&amp;#10;&lt;span class="p"&gt;};&lt;/span&gt;&amp;#10;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;
	SinonJS&lt;/h2&gt;
&lt;p&gt;
	&lt;a href="http://sinonjs.org/"&gt;SinonJS&lt;/a&gt; is a testing library that provides access to spies in JavaScript testing. Spies can track activity surrounding targeted bits of code. They help to verify that the correct methods are being called and if they behaved as expected.&lt;/p&gt;
&lt;p&gt;
	When testing we&amp;#39;ll trigger an event that activates Google Analytics and use a spy to see if the correct method was fired. We&amp;#39;ll also use them to confirm that the correct parameters were pushed up to Google Analytics, which will provide some additional comfort that cross-pollution between events is not occuring.&lt;/p&gt;
&lt;div class="highlight"&gt;
	&lt;pre&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;spy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_gaq&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"push"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&amp;#10;&amp;#10;&lt;span class="nx"&gt;_gaq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;_trackEvent&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Header Links&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Click&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;&amp;#10;&amp;#10;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;spy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;called&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; true&lt;/span&gt;&amp;#10;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;
	Mocha&lt;/h2&gt;
&lt;p&gt;
	Mocha is a JavaScript testing framework authored by the ever prolific &lt;a href="http://tjholowaychuk.com/"&gt;TJ Holowaychuck&lt;/a&gt; for &lt;a href="http://nodejs.org/"&gt;Node.js&lt;/a&gt; and browser environments. Its syntax is similar to &lt;a href="http://pivotal.github.com/jasmine/"&gt;Jasmine&lt;/a&gt; and in some cases the two are mistaken for one another.&lt;/p&gt;
&lt;div class="highlight"&gt;
	&lt;pre&gt;
&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Sample test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&amp;#10;&amp;#10;    &lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"should perform a sanity check"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&amp;#10;        &lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&amp;#10;    &lt;span class="p"&gt;});&lt;/span&gt;&amp;#10;&amp;#10;&lt;span class="p"&gt;});&lt;/span&gt;&amp;#10;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
	Later in this article we&amp;#39;ll delve deeper into Mocha, creating some more tests and integrate a custom test reporter that will help us to communicate the results back to PhantomJS.&lt;/p&gt;
&lt;h2&gt;
	Digging in to the code&lt;/h2&gt;
&lt;p&gt;
	I have hosted the final result of this article on &lt;a href="https://github.com/nhunzaker/phantomjs_ga"&gt;Github&lt;/a&gt;. I am working with the following file structure:&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="http://viget.com/uploads/image/blog/file_structure.jpg" style="width: 368px; height: 250px;" /&gt;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		&lt;a href="https://raw.github.com/visionmedia/mocha/master/mocha.js"&gt;Direct link to mocha.js&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;
		&lt;a href="http://sinonjs.org/releases/sinon-1.4.2.js"&gt;Direct link to sinon.js&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;
		&lt;a href="https://raw.github.com/gist/3912335/500067ebf61b4b2a9d53b8d283cacde963a9b8b9/reporter.js"&gt;Direct link to src/reporter.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
	Building the sample rules&lt;/h2&gt;
&lt;p&gt;
	First we need to add some events to the page that we want to track. We&amp;#39;ll add a couple of rules to the homepage to track some of the various activities on the site. Remember we&amp;#39;re navigating to &lt;a href="http://viget.com"&gt;viget.com&lt;/a&gt; which already loads jQuery:&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;src/rules.js&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;
	&lt;pre&gt;
&lt;span class="p"&gt;(function($) {&amp;#10;    &amp;#10;    // Track clicks on outbound links&amp;#10;    $("body").delegate("a", "click", function(e) {&amp;#10;        &amp;#10;        if (this.hostname === &amp;#39;viget.com&amp;#39;) return;&amp;#10;&amp;#10;        e.preventDefault();&amp;#10;        &amp;#10;        _gaq.push([&amp;#10;            &amp;#39;_trackEvent&amp;#39;, &amp;#39;Outbound Links&amp;#39;, &amp;#39;Click&amp;#39;, this.text&amp;#10;        ]);&amp;#10;&amp;#10;        setTimeout(function(url) {&amp;#10;            document.location = url;&amp;#10;        }, 100, this.href);&amp;#10;&amp;#10;    });&amp;#10;&amp;#10;    // Track clicks on the news items section&amp;#10;    $(".grouping-homepage-news-items a").click(function(e) {&amp;#10;&amp;#10;        e.preventDefault();&amp;#10;        &amp;#10;        var data = $(this).data("track-event").split(",");&amp;#10;        data.unshift(&amp;#39;_trackEvent&amp;#39;);&amp;#10;        &amp;#10;        _gaq.push(data);&amp;#10;&amp;#10;        setTimeout(function(url) {&amp;#10;            document.location = url;&amp;#10;        }, 100, this.href);&amp;#10;&amp;#10;    });&amp;#10;&amp;#10;    // Tracks links to careers&amp;#10;    $("a[href*=&amp;#39;about#careers&amp;#39;]").click(function(e) {&amp;#10;&amp;#10;        e.preventDefault();&amp;#10;&amp;#10;        _gaq.push([&amp;#39;_trackEvent&amp;#39;, &amp;#39;Careers&amp;#39;, &amp;#39;Click Link&amp;#39;]);&amp;#10;&amp;#10;        setTimeout(function(url) {&amp;#10;            document.location = url;&amp;#10;        }, 100, this.href);&amp;#10;&amp;#10;    });&amp;#10;    &amp;#10;}(window.jQuery));&lt;/span&gt;&amp;#10;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
	Pretty straightforward. Remember that we need to delay the link so that &lt;strike&gt;&lt;code&gt;.push()&lt;/code&gt; has enough time to send information&lt;/strike&gt; Google Analytics has &lt;a href="http://support.google.com/analytics/bin/answer.py?hl=en&amp;amp;answer=1136920"&gt;enough time to setup&lt;/a&gt; before the browser navigates to a new page.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Lines 3-18: &lt;/strong&gt;Whenever an outbound link is clicked, track it.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Lines 20-34:&lt;/strong&gt; When a news item is clicked, pull some out some data and track it.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Lines 36-47:&lt;/strong&gt; When a link to our careers section is clicked, track it.&lt;/p&gt;
&lt;h2&gt;
	Creating the tests&lt;/h2&gt;
&lt;p&gt;
	Now that we know what we want to track, let&amp;#39;s build a test that evaluates if we were successful:&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;tests/home-test.js:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;
	&lt;pre&gt;
&lt;span class="nx"&gt;describe("Viget Home Test", function() {&amp;#10;&amp;#10;    var spy = sinon.spy(window._gaq, "push");&amp;#10;    var assert = sinon.assert;&amp;#10;&amp;#10;    beforeEach(function() {&amp;#10;        spy &amp;amp;&amp;amp; spy.restore();&amp;#10;        spy = sinon.spy(window._gaq, "push");&amp;#10;    });  &amp;#10;    &amp;#10;    it ("tracks outbound links", function() {&amp;#10;&amp;#10;        var link = $("a[href=&amp;#39;http://www.pointlesscorp.com/&amp;#39;]");&amp;#10;&amp;#10;        link.click();&amp;#10;        &amp;#10;        assert.called(spy);&amp;#10;        assert.calledWith(spy, [&amp;#10;            &amp;#39;_trackEvent&amp;#39;, &amp;#39;Outbound Links&amp;#39;, &amp;#39;Click&amp;#39;, &amp;#10;            &amp;#39;Pointless Corp.&amp;#39;&amp;#10;        ]);&amp;#10;&amp;#10;    });&amp;#10;&amp;#10;    it ("tracks clicks on the news items section", function() {&amp;#10;        &amp;#10;        var link = $(".grouping-homepage-news-items a").first();&amp;#10;        &amp;#10;        var data = link.data("track-event").split(",");&amp;#10;        data.unshift("_trackEvent");&amp;#10;        &amp;#10;        link.click();&amp;#10;&amp;#10;        assert.called(spy);&amp;#10;        assert.calledWith(spy, data);&amp;#10;&amp;#10;    });&amp;#10;&amp;#10;    it ("tracks clicks on careers links", function() {&amp;#10;        &amp;#10;        var link = $("[a[href*=&amp;#39;about#careers&amp;#39;]").first();&amp;#10;&amp;#10;        link.click();&amp;#10;&amp;#10;        assert.called(spy);&amp;#10;        assert.calledWith(spy, [&amp;#10;            &amp;#39;_trackEvent&amp;#39;, &amp;#39;Careers&amp;#39;, &amp;#39;Click Link&amp;#39;&amp;#10;        ]);&amp;#10;&amp;#10;    });&amp;#10;    &amp;#10;});&lt;/span&gt;&amp;#10;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
	In the code above, we generate a suite of tests for the Viget homepage. Here&amp;#39;s what&amp;#39;s going on:&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Line 3:&lt;/strong&gt; An empty variable for our spy. At the beginning of each test this spy will be regenerated so we need to provide a variable with this level of scope here.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Line 4:&lt;/strong&gt; The assertion library used for testing the results. This is a &lt;a href="http://sinonjs.org/docs/#assertions"&gt;set of functions provided by SinonJS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Lines 6-9:&lt;/strong&gt; Before each test a spy is generated to monitor activity around &lt;code&gt;_gaq.push()&lt;/code&gt;. This spy is reset for each test so that it has a fresh copy to work with.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Lines 11-50:&lt;/strong&gt; The tests. JavaScript is used to replicate the interaction we wish to track and assertions are executed to determine the activity around the &lt;code&gt;push&lt;/code&gt; method of &lt;code&gt;_gaq&lt;/code&gt;. A check is also made to confirm it was called with the correct arguments.&lt;/p&gt;
&lt;h2&gt;
	The Custom Reporter&lt;/h2&gt;
&lt;p&gt;
	Now that tests have been created a method of communicating the results back to PhantomJS need to be added. With Mocha this is done through &lt;a href="http://visionmedia.github.com/mocha/#reporters"&gt;reporters&lt;/a&gt;, which listen to activities that occur during the testing process and provide feedback to the tester.&lt;/p&gt;
&lt;p&gt;
	Reporters involve a lot of framework specific code that isn&amp;#39;t completely relevent to this article so I&amp;#39;ve included this reporter in the &lt;a href="https://gist.github.com/3912335"&gt;following Github Gist&lt;/a&gt;. For those of you interested in learning more about Mocha, reporters are a really cool part of the framework and I would encourage you to dig deeper into them.&lt;/p&gt;
&lt;h2&gt;
	Building the PhantomJS test runner&lt;/h2&gt;
&lt;p&gt;
	If you don&amp;#39;t have PhantomJS installed there&amp;#39;s an &lt;a href="http://phantomjs.org/download.html"&gt;excellent guide&lt;/a&gt; on their website. You&amp;#39;ll want to make sure that you have the latest version (1.7 at the publication of this article) as more recent versions of PhantomJS have a new method of communicating between the page and PhantomJS that we use in our reporter.&lt;/p&gt;
&lt;p&gt;
	Personally, I installed it using &lt;a href="http://mxcl.github.com/homebrew/"&gt;Homebrew&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;
	&lt;code&gt;brew install phantomjs&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;
	The following code will be used to run our tests:&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;./test-runner.js:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;
	&lt;pre&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"webpage"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&amp;#10;&amp;#10;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"http://www.viget.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&amp;#10;&amp;#10;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;success&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&amp;#10;        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Failed to open"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frameUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&amp;#10;        &lt;span class="nx"&gt;phantom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&amp;#10;    &lt;span class="p"&gt;}&lt;/span&gt;&amp;#10;&amp;#10;    &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;injectJs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"lib/mocha.js"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&amp;#10;    &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;injectJs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"lib/sinon.js"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&amp;#10;&amp;#10;    &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;injectJs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"src/reporter.js"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&amp;#10;    &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;injectJs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"src/rules.js"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&amp;#10;&amp;#10;    &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;injectJs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"tests/home-test.js"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&amp;#10;&amp;#10;    &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&amp;#10;&amp;#10;        &lt;span class="c1"&gt;// Undefine GA&lt;/span&gt;&amp;#10;        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_gat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&amp;#10;        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_gaq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;_setAccount&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;UA-00000000-1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]];&lt;/span&gt;&amp;#10;&amp;#10;        &lt;span class="c1"&gt;// Run tests&lt;/span&gt;&amp;#10;        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mocha&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&amp;#10;    &lt;span class="p"&gt;});&lt;/span&gt;&amp;#10;&amp;#10;&lt;span class="p"&gt;});&lt;/span&gt;&amp;#10;&amp;#10;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onCallback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&amp;#10;    &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&amp;#10;    &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;phantom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&amp;#10;&lt;span class="p"&gt;};&lt;/span&gt;&amp;#10;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
	This is a lot to take in all at once. Thinking in terms of regular browser use, here&amp;#39;s what happens:&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Line 1:&lt;/strong&gt; Create a new tab.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Line 3:&lt;/strong&gt; Navigate to &lt;a href="http://www.viget.com"&gt;http://www.viget.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Lines 5-8:&lt;/strong&gt; Could we successfully connect? If not, notify the user and exit PhantomJS&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Lines 10-16:&lt;/strong&gt; Add the JavaScript that runs our tests to the page&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Lines 18-26:&lt;/strong&gt; &lt;code&gt;page.evaluate&lt;/code&gt; lets us run JavaScript on the current page. Here we unset the current Google Analytics setup so that we don&amp;#39;t accidentally push our results. Once this has all been configured, we run our tests on line 26.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Lines 30-33:&lt;/strong&gt; PhantomJS 1.6 added the ability to send messages from the client back to PhantomJS. This activity can be seen within the &lt;code&gt;log&lt;/code&gt; function of the custom test reporter. Here we define a function to handle the event that is fired when this method is envoked.&lt;/p&gt;
&lt;h2&gt;
	Give it a spin&lt;/h2&gt;
&lt;p&gt;
	With all of this complete testing can begin. Use the following command to test the rules we&amp;#39;ve created:&lt;/p&gt;
&lt;p&gt;
	&lt;code&gt;phantomjs test-runner.js&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;
	You should see the following output:&lt;/p&gt;
&lt;p&gt;
	&lt;img alt="" src="http://viget.com/uploads/image/blog/Snapshot-10_18_12-12_26-PM.jpg" style="width: 526px; height: 181px;" /&gt;&lt;/p&gt;
&lt;h2&gt;
	Take aways from PhantomJS testing&lt;/h2&gt;
&lt;p&gt;
	I found that testing Google Analytics in this way is significantly faster and provides continuous confirmation that events are behaving as expected. Given the sheer volume of pages you are able to test, refactoring can be done safely. Reproducing and testing fringe issues also becomes much easier.&lt;/p&gt;
&lt;p&gt;
	The code for this article was simplified for brevity, however JavaScript remains at its core. Modification should be straightforward and I encourage you to use this code in other forms of front-end testing. These methodologies provide exciting opportunities for advancing the quality of tests for JavaScript applications and demonstrate the leaps the community has made to advance JavaScript as a language in the past few years.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/eUieHpuQOQc" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/testing-google-analytics-with-phantomjs#When:16:19</feedburner:origLink></item>
		
			<item>
				<title>Viget Intern Prank: How to Improve any Website</title>
				
					<link>http://feedproxy.google.com/~r/VigetExtend/~3/vIsryjSLZnM/viget-intern-prank-how-to-improve-any-website</link>
					<guid isPermalink="false" isPermaLink="false">http://viget.com/extend/viget-intern-prank-how-to-improve-any-website#When:14:08</guid>
				
				<pubDate>Mon, 01 Oct 2012 14:08 GMT</pubDate>
				<dc:creator>Eli Fatsi</dc:creator>
				<dc:subject>Extend</dc:subject>
				<description>&lt;p&gt;
	During my internship, I was given a summer checklist in the form of a so-called &amp;ldquo;Vigtories card&amp;rdquo; &amp;mdash; the idea was to accomplish as many non-work-related activities (some quirkier than others) as possible. You can see the interns&amp;rsquo; final Vigtories on the &lt;a href="http://vignettesfromviget.tumblr.com/page/2"&gt;intern tumblr blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
	Throughout the summer, I made some decent progress (bike to work, go hiking with a fellow Viget, learn something new about &lt;a href="http://viget.com/about/team/bwilliams"&gt;Brian&lt;/a&gt; or &lt;a href="http://viget.com/about/team/arankin"&gt;Andy&lt;/a&gt;), but one particular task remained unchecked for the majority of the summer - &amp;ldquo;pull one harmless prank in coordination with your mentor&amp;rdquo;.&lt;/p&gt;

						&lt;h1 id="the_idea"&gt;
	THE IDEA&lt;/h1&gt;
&lt;p&gt;
	While celebrating Intern Appreciation Day at a local brewpub with the Boulder developers, we decided to hijack Viget&amp;rsquo;s DNS and redirect the intern tumblr blog to something funny. Weeks went by however and as the internship neared its end, we&amp;rsquo;d yet to decide what would be something funny. With one day left however a formal plan was crafted: we would manipulate the intern blog itself.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;h1 id="initial_implementation"&gt;
	INITIAL IMPLEMENTATION&lt;/h1&gt;
&lt;p&gt;
	Since the task at hand was fairly lightweight, I went with building up a simple Sinatra proxy app. The basic idea was to load the original source using &lt;code&gt;Nokogiri&lt;/code&gt; and fiddle with all the images to our liking. We targeted author images first, but what to do with them? Mustachify.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;center&gt;
	&lt;img alt="Adey Mustachifyed" src="http://viget.com/uploads/image/blog/adey_transformed.jpeg" /&gt;&lt;/center&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	The following snippet was the first implementation. It flipped through the HTML and replaced every image of class &amp;lsquo;author-photo&amp;rsquo; with the mustachifyed version of itself, then returned the new HTML for eyes of the world to see.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;get &amp;#39;/&amp;#39; do&amp;#10;  doc = Nokogiri::HTML(open("http://vignettesfromviget.tumblr.com/"))&amp;#10;  doc.css(&amp;#39;.author-photo img&amp;#39;).each do |image|&amp;#10;    image[&amp;#39;src&amp;#39;] = "http://mustachify.me/?src=" + image[&amp;#39;src&amp;#39;]&amp;#10;  end&amp;#10;&amp;#10;  halt 200, &amp;#123;&amp;#39;Content-Type&amp;#39; =&amp;gt; &amp;#39;text/html&amp;#39;&amp;#125;, doc.to_html&amp;#10;end&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;h1 id="stepping_things_up"&gt;
	STEPPING THINGS UP&lt;/h1&gt;
&lt;p&gt;
	Things then got real as &lt;a href="http://viget.com/about/team/preagan"&gt;Pat&lt;/a&gt; jumped in with some &lt;code&gt;MiniMagick&lt;/code&gt; and &lt;code&gt;Digest::MD5&lt;/code&gt; craftiness. This time the manipulation was targeted towards images in the bodies of every post. Since the new site was already riddled with mustaches, we decided to flip these images upside down. Using &lt;code&gt;Nokogiri&lt;/code&gt; still to pluck all the posted images from the HTML, &lt;code&gt;MiniMagick&lt;/code&gt; was used to make flipped copies of everything, and &lt;code&gt;Digest::MD5&lt;/code&gt; was used to save the new and improved copies to our own directory.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;def flip_images&amp;#10;  document.css(&amp;#39;.content img&amp;#39;).each do |image_node|&amp;#10;    image_source = image_node[&amp;#39;src&amp;#39;]&amp;#10;    extension    = File.extname(image_source)&amp;#10;    output_name  = Digest::MD5.hexdigest(image_source) + extension&amp;#10;&amp;#10;    image = MiniMagick::Image.open(image_source)&amp;#10;    image.flip&amp;#10;    image.write "./public/#&amp;#123;output_name&amp;#125;"&amp;#10;&amp;#10;    image_node[&amp;#39;src&amp;#39;] = output_name&amp;#10;  end&amp;#10;end&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	The last line in this method adjusts the HTML so pictures are loaded from our new directory and tada! - images were flipped! But not all of them&amp;hellip;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;h1 id="one_last_roadblock"&gt;
	ONE LAST ROADBLOCK&lt;/h1&gt;
&lt;p&gt;
	If you upload multiple images into one Tumblr post, an iframe is created in the post instead of a simple image. This difference was allowing these iframe photos to slip under the radar. To fix this, first we broadened the scope of our image flipping function from &lt;code&gt;&amp;#39;.content img&amp;#39;&lt;/code&gt; to &lt;code&gt;&amp;#39;.content img,.photoset_row img&amp;#39;&lt;/code&gt; allowing us to capture, flip, and save the iframe images with the rest. We then wrote a method to change the source of the iframe images away from the tumblr blog server and to our own directory.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;def rewrite_iframe_source&amp;#10;  document.css(&amp;#39;iframe.photoset&amp;#39;).each do |iframe_node|&amp;#10;    iframe_node[&amp;#39;src&amp;#39;] = iframe_node[&amp;#39;src&amp;#39;].sub!("http://vignettesfromviget.tumblr.com", "")&amp;#10;  end&amp;#10;end&amp;#10;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;h1 id="the_result"&gt;
	THE RESULT&lt;/h1&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;center&gt;
	&lt;img alt="Vignette Transformed" src="http://viget.com/uploads/image/blog/vignette_transformed22.jpg" /&gt;&lt;/center&gt;
&lt;p&gt;
	A glorious manipulation of the intern tumblr blog. The last step in the prank was to hijack the Viget DNS and redirect anyone who visits vignettesfromviget.tumblr.com to the IP of the modified site. This requires some administrative access to the DNS and thus was a job for Pat. But, after all, this was a &amp;ldquo;prank in collaboration with my mentor&amp;rdquo;. This prank was purely local as we could only redirect people to the new IP address if they were on a Viget network. But, for your viewing pleasure, feel free to enjoy the fruits of our labor - &lt;a href="http://vignettesfromviget.tumblr.com/page/2"&gt;before&lt;/a&gt; and &lt;a href="http://198.101.228.80/page/2"&gt;after&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;h2 id="bonus_cageme"&gt;
	BONUS - CAGEME&lt;/h2&gt;
&lt;p&gt;
	You&amp;rsquo;ll notice a few posts do not have a mustachifyed young adult picture as the author, but instead a mustachifyed picture of Nicolas Cage as someone else. This indicates a post by Jack: one of the other Rails interns here this last summer, and the creator of one of the greatest websites around - &lt;a href="http://cageme.herokuapp.com"&gt;http://cageme.herokuapp.com&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/VigetExtend/~4/vIsryjSLZnM" height="1" width="1"/&gt;</description>
			<feedburner:origLink>http://viget.com/extend/viget-intern-prank-how-to-improve-any-website#When:14:08</feedburner:origLink></item>
		
	</channel>
</rss>
