<?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/" version="2.0">
  <channel>
    <description>Web Advent</description>
    <title>Web Advent</title>
    <link>http://webadvent.org/</link>
    <pubDate>Sat, 25 May 2013 19:56:11 -0400</pubDate>
                <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/phpadvent" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="phpadvent" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
              <title>Be Lazy</title>
              <dc:creator>Kitt Hodsden</dc:creator>
              <description><![CDATA[<p>The other day, I went to help a co-worker set up his laptop. When teaching new topics, I&#8217;m a big fan of active participation, letting the other person drive as a means to better understanding. So, during the setup, I explained what we were doing, what changes we were making and why, but insisted he make the actual changes on his system.</p>

<p>Watching him work, it quickly became apparent that--while he knew what he was doing--he wasn&#8217;t efficient. Using the tools on his laptop was onerous; he fought the system, taking the long way each time to achieve the desired results, but at the cost of lost time for both of us. As I was watching him, I wished he were more lazy.</p>

<p>Wait. Lazy? Well, sure.</p>

<p>Laziness is the <a href="http://c2.com/cgi/wiki?LazinessImpatienceHubris">first great virtue of a programmer</a>:</p>

<blockquote><p>&#8220;The quality that makes you go to great effort to reduce overall energy expenditure. It makes you write labor-saving programs that other people will find useful, and document what you wrote so you don&#8217;t have to answer so many questions about it. Hence, the first great virtue of a programmer.&#8221;</p></blockquote>
<p><cite>&#8212;&#8201;  <a href="http://en.wikipedia.org/wiki/Larry_Wall">Larry Wall</a></cite>

<p>Fortunately, laziness isn&#8217;t just for programmers; it&#8217;s for all who work and take pride in their accomplishements, and with computers, it&#8217;s possible to be lazy (and efficient!) with just a little effort.</p>

<p>And, look at all the ways you can be lazy!</p>

<h2>App launchers</h2>

<p>Moving hands away from the keyboard, or away from their default position if you use a secondary input device consistently, inherently creates inefficiencies. Use an app launcher that you can customize. Four or five keystrokes is all I need to open just about any app on my system: two to open the launcher, one or two to select the app or file, and enter to open it. You can also use app launchers to set up scripts and run workflows.</p>

<p>On OSX, options include <a href="http://www.alfredapp.com/">Alfred</a>, <a href="http://www.obdev.at/products/launchbar/">Launchbar</a>, and <a href="http://qsapp.com/">Quicksilver</a>.</p>

<p>On Linux, options include <a href="https://live.gnome.org/">Gnome Launch Box</a>, <a href="http://do.davebsd.com/">Gnome Do</a>, and <a href="http://www.launchy.net/">Launchy</a>.</p>

<p>On Windows, options include <a href="http://www.candylabs.com/skylight">Skylight</a> and <a href="http://www.launchy.net/">Launchy</a>.</p>

<p>Launchy also lets you <a href="http://pylaunchy.sourceforge.net/docs/">use Python to extend its functionality</a>, so you can automate common work patterns.</p>

<p>Or, if you&#8217;re on OS X, use the highly-underrated <a href="http://support.apple.com/kb/HT2488">Automator</a> workflows for tasks on your system. You can have your workflows triggered manually or automatically. An example could be instead of the default action to import all photos into iPhoto whenever you mount an SD card, you could have all images post to a private folder on <a href="http://openphoto.me/">OpenPhoto</a> and tag them with the date.</p>

<h2>Befriend the command line</h2>

<p>Not all workflows, however, need be triggered from an app launcher or automatically. Using the command line, you can trigger most apps to run just the way you want. While some developers may roll their eyes, not everyone uses the command line. Befriending the command line is the best form of laziness.</p>

<p>If you&#8217;re on a Unix platform&#8201;&#8212;&#8201;yes, that includes OS X&#8201;&#8212;&#8201;these twelve commands will get you going: <code>cd</code>, <code>cp</code>, <code>less</code>, <code>which</code>, <code>ls</code>, <code>rm</code>, <code>pwd</code>, <code>cat</code>, <code>find</code>, <code>grep</code>, <code>!!</code>, and <code>!$</code>.

<p>Want to execute the last command again?</p>

<pre><code>!!</code></pre>

<p>Want to repeat a command you typed in a while ago?</p>

<pre><code>!{command}</code></pre>

<p>Want to go to the beginning of a line?</p>

<pre><code>^a</code></pre>

<p>Want to go to the end to edit the last argument?</p>

<pre><code>^e</code></pre>

<p>Want to switch back to your previous directory?</p>

<pre><code>cd -</code></pre>

<p>Want to look through your history to find the command you ran a while ago?</p>

<pre><code>^r</code></pre>

<p>My personal favorites are <code>pushd</code> and <code>popd</code>, with <code>dirs</code> to tell me where I am.</p>

<p><code>pushd</code> with an argument will add the current directory (<code>pwd</code>) onto the directories stack (listed with <code>dirs</code>) and change the working directory to the one specified by the argument:</p>

<pre><code>% pwd
/Users/kitt
% pushd ~/work/projects/web-advent
~/work/projects/web-advent ~
% pushd ~/work
~/work ~/work/projects/web-advent ~
% dirs -v
0       ~/work
1       ~/work/projects/web-advent
2       ~</code></pre>

<p><code>pushd</code> without arguments will swap the top two directories on the stack&#8201;&#8212;&#8201;the same behavior as <code>cd -</code>.</p>

<pre><code>% pushd
~/work/projects/web-advent ~/work ~
% dirs -v
0       ~/work/projects/web-advent
1       ~/work
2       ~</code></pre>

<p>The advantage here is when you have a number of places you need to be working:</p>

<pre><code>% dirs -v
0       /usr/sites/example.com/8929/website
1       /var/log/apache2/example.com/
2       /etc/apache2/extra
3       /home/kitt/work/reports/example.com</code></pre>

<p>Using the <code>+N</code> notation moves you among the directories, either popping the <em>N</em>th directory to the top of the stack, or rotating the stack around <em>N</em> positions:</p>

<pre><code>% pushd +2
/etc/apache2/extra /usr/sites/example.com/8929/website /var/log/apache2/example.com /home/kitt/work/reports/example.com
% d
0       /etc/apache2/extra
1       /usr/sites/example.com/8929/website
2       /var/log/apache2/example.com/
3       /home/kitt/work/reports/example.com</code></pre>

<p>I&#8217;m lazy even when using <code>pushd</code>, <code>popd</code>, and <code>dirs -v</code>. I have them aliased to <code>pu</code>, <code>po</code> and <code>d</code>. I alias my commands heavily, setting up aliases for project directories, common commands I run frequently, and uncommon commands (I hate trying to remember the full syntax).</p>

<p>If you run an even semi-complicated command more than once, <a href="http://en.wikipedia.org/wiki/Alias_%28command%29">write an alias</a>. No one wants to type in this command more than once:</p>

<pre><code>alias gen_ctags='/usr/local/bin/ctags \
  --langmap=php:.engine.inc.module.theme.php.install.test.profile \
  --php-kinds=cdfi --languages=php --recurse --exclude="\.git" \
  --exclude="\.svn" --exclude="\.hg" --exclude="\.bzr" \
  --exclude="CVS" --totals=yes --tag-relative=yes \
  --regex-PHP="/abstract\s+class\s+([^ ]+)/\1/c/" \
  --regex-PHP="/interface\s+([^ ]+)/\1/c/" \
  --regex-PHP="/(public\s+|static\s+|abstract\s+|protected\s+|private\s+)function\s+\&amp;?\s*([^ (]+)/\2/f/"'</code></pre>

<p>Practice and repetition are the best ways to learn shortcuts. If you&#8217;re looking for a concentrated resource, <a href="https://www.shortcutfoo.com/app/tutorial/commandline">ShortcutFoo for the command line</a> is a great one.</p>

<p><a href="https://www.shortcutfoo.com/">ShortcutFoo</a> also has drills for learning how to use the shortcuts for a large number of programs, including a number of editors.</p>

<p>If you&#8217;re a developer, the best thing you can do for efficiency and, well, laziness, is to become proficient in your editor, learning its shortcuts and learning how to write editor macros. If your chosen editor doesn&#8217;t have macros, pick a different editor; no need to handicap yourself with a tool that doesn&#8217;t actively help you be lazy.</p>

<h2>Emmet</h2>

<p>When looking at editors or writing macros, anyone who writes any significant HTML should look at the <a href="http://docs.emmet.io/">Emmet</a> (formerly <a href="http://code.google.com/p/zen-coding/">Zen Coding</a>) plugins.</p>

<p>The easiest example of how powerful Emmet can be is the abbreviation expansion, which takes a abbreviated line like this:</p>

<pre><code>div#banner&gt;div.logo+ul#navigation&gt;li*4&gt;a</code></pre>

<p>And, expands it into this:</p>

<pre><code>&lt;div id="banner"&gt;
 &lt;div class="logo"&gt;&lt;/div&gt;
 &lt;ul id="navigation"&gt;
   &lt;li&gt;&lt;a href=""&gt;&lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;&lt;a href=""&gt;&lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;&lt;a href=""&gt;&lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;&lt;a href=""&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;/ul&gt;
&lt;/div&gt;</code></pre>

<p>Emmet also provides editing shortcuts, tag manipulation (matching, removing, navigating to), and other generators (vendor prefixes, gradients).</p>

<p>There are, of course, thousands of other ways to be more efficient and lazy in a common workday. Being aware of repetition, asking co-workers how they accomplished a task faster than you, and recognizing that laziness can be a virtue are ways to increase that efficiency and leave room for more important things in life.</p>

<p>Like relaxing. Or, doing nothing.</p>
]]></description>
              <link>http://webadvent.org/2012/be-lazy-by-kitt-hodsden</link>
              <guid>http://webadvent.org/2012/be-lazy-by-kitt-hodsden</guid>
              <pubDate>Mon, 24 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>The Long View</title>
              <dc:creator>Lachlan Hardy</dc:creator>
              <description><![CDATA[<p>We who work on the Web, as Noah Stokes <a href="http://webadvent.org/2012/make-a-difference-by-noah-stokes">wrote in an earlier article</a>, have a privileged opportunity to create things that can change the world more easily than most; to make a difference. This concept is inherent to the essence&#8201;&#8212;&#8201;the very nature&#8201;&#8212;&#8201;of the Web. I believe this depends in part on us maintaining and supporting what&#8217;s already been done. I&#8217;ll illustrate.</p>


<h2>How I started</h2>

<p>I&#8217;ll not pretend I was kicking around back when the Web was formed. I was too busy trying to work out where I fit in the high school oligarchy, and how to talk to girls. I spent every other lunch time in the school computer rooms, but I was mostly in IRC chatrooms (talking to girls might be easier if you can&#8217;t see them), not mucking about with HTML. In 2001, five years after high school graduation, I made my first production site. It was the year Netscape, Opera, and Internet Explorer all released 6.x versions, and neither Safari nor Firefox existed. I was part of a small team developing a business around a content management system to help golf professionals run their own web sites. These days, we&#8217;d call it a <em>Software-as-a-Service</em> startup. I was the programmer (at first), and the only technical person, so I did everything.</p>

<p>The business owner, a golf pro himself, came to me with a feature request.</p>

<p>&#8220;We need pros to be able to change the layout themselves from the admin. Put the logo on the right instead of the left. Change the background and text colours. Switch the size of the columns. That sort of thing.&#8221;</p>

<p>&#8220;Uhhh&#8230; Yeah, so that&#8217;s going to be pretty difficult.&#8221;</p>

<p>&#8220;What? I don&#8217;t care. Can you do it or not?&#8221;</p>

<p>&#8220;Give me two weeks, and I&#8217;ll know.&#8221;</p>

<p>This was my first lesson in client-developer relations. He didn&#8217;t know or care what tables were and how they worked. He just wanted the feature he wanted. So, I went looking for answers. That&#8217;s when I discovered <em>CSS-P</em>.</p>


<h2>CSS-P, yeah, you know me</h2>

<p>The <em>P</em> stood for <em>positioning</em>. Until then, we&#8217;d only been using a style element in the head of each document to change the fonts and link colors. I thought I was clever for using a <em>Server Side Include</em>, so I only had one file to change. If you search for CSS-P these days, you&#8217;ll find that most of the old articles and tutorials are gone, but for whatever reason, two remain, unchanged: <a href="http://www.mako4css.com/Tutorial.htm">MaKo 4 CSS</a> and <a href="http://www.projectseven.com/whims/cssp_3box/3boxnoscript.htm">CSS-P 3box</a>.</p>

<p>And I remember these. I&#8217;ve never known who MaKo is, but she or he is responsible for the basis of my entire career.</p>

<p>This <a href="http://validator.w3.org/check?uri=http%3A%2F%2Fwww.mako4css.com%2FTutorial.htm&#38;charset=%28detect+automatically%29&#38;doctype=Inline&#38;group=">almost perfectly valid page</a> from 2001 looks and works exactly the same now (December 2012) as it did in when it was made. We probably no longer need to worry about the Netscape 4 hacks or the browsers that don&#8217;t support CSS. (View Source for fascinating tidbits like that.) This is one of the things the Web gives us. </p>

<h2>Longevity</h2>

<p>Jeremy Keith has <a href="http://adactio.com/journal/tags/preservation/">written far more, and far more eloquently</a>, than I ever will on the importance of preserving digital artifacts and the horror that is linkrot. And, if you haven&#8217;t read Anil Dash&#8217;s retrospective <em><a href="http://dashes.com/anil/2012/12/the-web-we-lost.html">The Web We Lost</a></em>, I strongly recommend it.</p>

<p>Inherent in the nature of the Web is a sense of preservation. The possibility of archive. The Web is pure information, and we have the capacity to store it all. So many of us produce content for our friends, family, colleagues, and peers to share. Beautiful, interesting, informative, dull, hilarious, ugly, fascinating content. Like MaKo&#8217;s article, or the others I&#8217;ve linked in this article, I&#8217;d love to know it will still be available in 10 years or 20. Perhaps not in quite the same format, but still readable, still findable. Still offering benefits and insights years later.</p>

<p>This is what the Web offers us. We need to find ways to hold up our end of the bargain.</p>
]]></description>
              <link>http://webadvent.org/2012/the-long-view-by-lachlan-hardy</link>
              <guid>http://webadvent.org/2012/the-long-view-by-lachlan-hardy</guid>
              <pubDate>Sun, 23 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>Get a Little Uncomfortable</title>
              <dc:creator>Laura Beth Denker</dc:creator>
              <description><![CDATA[<p>It must be a small world after all. Walking through a neighborhood, that I neither live in or work in, in a city of eight million people, I somehow manage to, seemingly randomly, bump into someone I know, nearly every time. If I were to come across this acquaintance in the neighborhood where he lived, I would think nothing of it, but usually this is not the case. Occasionally, this someone is not even a resident of any of the five boroughs of the city. How is it that I can walk through a city so populous with a constant ebb and flow of outsiders, and unwittingly bump into someone I know. Maybe it truly is a small world after all.</p>

<p>It must be a small world after all. Every day I am in communication, over the phone, text message, email, Facebook, Twitter&#8201;&#8212;&#8201;you name it&#8201;&#8212;&#8201;with someone that is in a different city, county, state, country, continent, but somehow not a different planet. I guess it is a small world, but in a huge, sparse universe.</p>

<p>Before the Web, and all these social apps, there was a time when you dictated the number for your phone to dial by diligently typing in every digit, rather than asking your smart phone what to do next. During the time when your parents&#8201;&#8212;&#8201;or maybe grandparents&#8201;&#8212;&#8201;were your age, were they in near constant communication with someone living in another country? The answer to that probably depended on whether they were one of the few to have a friend from grade school through high school, or a more likely reason for knowing someone abroad was participation in the service.</p>

<p>Today, I am posting this article that will likely be read by people from all around the globe. I might collect more Twitter followers, and I will likely learn about new happenings in the web development community from those whom I follow. I will write at least one email to someone not residing in the same country as I do, and I will compose, and reply to, several more e-mails to people I will not talk to in person for at least a month, if ever. The odds of me commenting on or liking a photo or post of someone I have not seen since my tenth high school reunion is not improbable, either. It must be that technology and the Web has shrunk the world, brought us closer together&#8230; but has it really?</p>

<p>Many of us participate in a communication graph encompassing a large geographical region, but has this made us any more worldly?</p>

<p>This past year, I spent a decent amount of time traveling to places I had never been to. My travel was mostly to web development conferences. The developers were excited to meet more people in the community; the conversations were informative, and sometimes became a heated debate. It was difficult to be disinterested. How could anyone electing to attend a web development conference not be excited to participate in a lecture, discussion, or a debate about web development?</p>

<p>The world is not as small as it seems. The Web has just made it easier to create small, niche communities, based on shared interests that cover a large global expanse, as opposed to the past where small, niche communities often times were more or less dictated by geography. Participating in a community spread thin across the globe, but tightly knit by its passion surrounding common interests can create a false sense of worldliness. Within such a group, the world is as small and narrow as the role the common interest plays in the world population.</p>

<p>I am not suggesting that the Web is insignificant. Most would say that the majority of the world&#8217;s population is impacted in some way by the Web. The common interests and shared topics of the web development community, as an example, tend to be far more specific. Is it rarely about the significance of the web? Usually, discussions about which technology to use, which practices to follow, which programming language to use, or something else that is more personal, teach individual members day-to-day. Beyond that, I am talking more generally about all types of self-selecting groups. I am warning against being lulled by the false sense of reality that self-selection bias can breed.</p>

<p>Still using the web development community as an example, the truth is that most people (also known by the dehumanizing term: user) do not care what language your web site is implemented in, which database you used, whether or not you host the site from the cloud or your own bare metal. Most people do not care if you use continuous deployment or how good your test coverage is. Read this last bit to someone who is not a web developer, and you are more likely to discover that he doesn&#8217;t even know what these things are. Some of you reading this may think, &#8220;we should teach everyone.&#8221; That&#8217;s not my point.</p>

<p>My point is that everyone&#8201;&#8212;&#8201;no matter who they are&#8201;&#8212;&#8201;needs to actively put themselves in an uncomfortable position every now and then. It is comforting to surround yourself with people just like you. Next time you are at the company party, rather than spending most of the time talking just your co-workers, take the opportunity to listen to your co-workers&#8217; party guests. It is a great opportunity to ask them about their professions; find out what their interests are. It is an opportunity to be educated, a chance to view the world through the eyes of someone unlike you. Now this is just a starting point because these party guests obviously have something in common with your co-workers who likely have something in common with you, but you can use this as a start.</p>

<p>Another good start is to change the topic in your common interest group, every now and then, to something off-topic. While I was traveling this past year, conference to conference, I decided to ask most people that I met, &#8220;What did you learn in history class?&#8221; It did not matter whether the person grew up in Poland and now resided in Great Britain, or if the person simply lived in the south as opposed to my north-east roots. The question was enough to remove the person from the normal biased answers to the ever reworded common questions. It was also an opportunity for me to glean some notion of how a person&#8217;s view point of the world might be different from the view point I was raised with.</p>

<p>All of this ties into common things we all eventually tackle during our web development experience, like learning that internationalization is more than handling different character sets and translating verbatim to another language. That it is more about a quest for localization, realizing that different cultures exist. Sometimes it is even recognizing that the dividing lines could be education, occupation, or some other basis besides culture. It&#8217;s also like recognizing not to trivialize the world through <em>Big Data</em>. When attempting to find the commonality amongst your user base, remember that those are also individuals. Do not take for granted the opportunity to actually sit down with someone, listen to them, observe them, just because you have data.</p>

<p>For me the goal of all this is to encourage you to get a little uncomfortable, break out of whatever small worlds you have joined, and see the world as vast, huge, uncertain, and as ever-unlimited as a wide-eyed child does. Otherwise, your endeavors to take the world by storm with your web development will be as limited as your outlook.</p>

]]></description>
              <link>http://webadvent.org/2012/get-a-little-uncomfortable-by-laura-beth-denker</link>
              <guid>http://webadvent.org/2012/get-a-little-uncomfortable-by-laura-beth-denker</guid>
              <pubDate>Sat, 22 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>CSS Sliding Panels</title>
              <dc:creator>Bedrich Rios</dc:creator>
              <description><![CDATA[<p>I&#8217;m here to show you how to create <em>sliding panels</em> using CSS and a class name toggle. Why use sliding panels on your app? Because they are awesome, that&#8217;s why. Also, because they allow users to switch between views whithout the need to load another page.</p>

<h2>First things first</h2>

<p>Before we go wild with &#8220;creativity,&#8221; we need a simple HTML structure to work with.</p>

<pre><code>&lt;body class="is-anchored"&gt;
    &lt;div id="navigation"&gt;
        &lt;p&gt;My awesome app&lt;/p&gt;
    &lt;/div&gt;
    &lt;div id="panel-main" class="panel"&gt;
        &lt;h1&gt;Click me to slide panel&lt;/h1&gt;
    &lt;/div&gt;
    &lt;div id="panel-sidebar" class="panel"&gt;
        &lt;h1&gt;Click me to slide panel&lt;/h1&gt;
    &lt;/div&gt;
&lt;/body&gt;</code></pre>

<p>Next, we need to bind our panels (<code>.panel</code>) so they toggle the class name <code>.is-anchored</code> from the <code>body</code> when clicked. For that we are going to use the following jQuery snippet:</p>

<pre><code>$(document).ready(function() {

    // this should be your wrapping element,
    // in this case I use the `body`
    var $body = $(document.body);
    var $panels = $('.panel');
    var dom_classname = 'is-anchored';

    $panels.on('click', function() {
        $body.toggleClass(dom_classname);
    });

});</code></pre>

<h2>Now for the fun part</h2>

<p>Here is where we get crazy with our CSS. First, let&#8217;s add the rules that will be applied to <code>.panel</code> elements when <code>.is-anchored</code> is present. I&#8217;m omitting some styles in order to focus on the <em>sliding panel</em> layout, but I&#8217;ve supplied the <a href="/f/bedrich-rios-sliding-panels.css">complete style sheet</a>.</p>

<pre><code>body {
    /* prevents horizontal scrollbar */
    overflow-x: hidden;
}

.panel {
    /* allows each panel to have its own scrollbar, if needed */
    overflow: auto;
    /* makes the browser window the containing block */
    position: fixed;
    top: 0;
    width: 100%;
    height: 100%;
}

.is-anchored #panel-main {
    left: 0; /* moves this panels into view */
}

.is-anchored #panel-sidebar {
    left: 100%; /* moves this panel off the screen to the right */
}</code></pre>

<p>Next, we add the styles for positioning the panels when <code>.is-anchored</code> is not present. Note that <code>left</code> is the only value which varies based on the presence of <code>.is-anchored</code>. This single property change allows us to create a smooth <em>sliding</em> effect using CSS transitions.</p>

<code><pre>#panel-main {
    left: -100%; /* moves this panel off the screen to the left */
}

#panel-sidebar {
    left: 0; /* moves this panels into view */
}</pre></code>

<p>At this point, clicking anywhere inside <code>.panel</code> should move the hidden <code>div</code> into view. It is time to add some <em>sliding</em> to our sliding panels with a dash of CSS transitions.</p>

<pre><code>.panel {
    /* applies CSS transition to `left` property */
    -webkit-transition: left .5s ease;
    -moz-transition: left .5s ease;
    -o-transition: left .5s ease;
    transition: left .5s ease;

    overflow: auto;
    position: fixed;
    top: 0;
    width: 100%;
    height: 100%;
}</code></pre>

<h2>Slow clap</h2>

<p>Here is the <a href="/f/bedrich-rios-sliding-panels.html">final product</a>. I have used this technique for displaying individual assets on <a href="http://gimmebar.com/">Gimme Bar</a>, a magic little app that relies on infinite scroll for its pagination. Using <em>sliding panels</em> helped me preserve a user&#8217;s browser window position when scrolling, all without using a complex JS solution. Simple!</p>
]]></description>
              <link>http://webadvent.org/2012/css-sliding-panels-by-bedrich-rios</link>
              <guid>http://webadvent.org/2012/css-sliding-panels-by-bedrich-rios</guid>
              <pubDate>Fri, 21 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>Take Time to Make Time</title>
              <dc:creator>Jeff Loiselle</dc:creator>
              <description><![CDATA[<p>I&#8217;m busy. I&#8217;m an American living in the twenty-first century in the Northeast. You can go read the statistics, but I&#8217;m part of a group of hustlers. We get stuff done. I&#8217;m usually busy freaking out about things on my todo list. They usually break down into three categories: things to do at work, things to do for myself, and ways to improve my skills. The ordering is important here, because the same order in which things are ensured to get done, is the reverse in which things will be neglected. We all know that your personal goals can be easily prioritized last and neglected first. There are probably more than a few books written about how to be successful, make friends, get rich, and conquer the world; and likely most of them pivot upon a central principle: time management.</p>

<p>We are living in what I perceive to be an information Big Bang. Our lives are disrupted exponentially more by information and technology than was the case a decade ago. I have to squelch the questions asked by my own brain just to get through the day. Thoughts cross my mind like: which blog should I add to my reader? Who should I follow? Am I missing out on anything important? Is there new technology that I should learn? Are my skills still relevant? Will they be relevant a week from now? What are people saying on Twitter right now? Ahh! What to do&#8253; Unfortunately, I don&#8217;t have the answers for <em>How to Stop Worrying and Love Information Technology Overload</em>.</p>

<p>If you can manage to filter out all the worrying and get to the most important part, self-education, then we can begin to make some progress. It&#8217;s what got me here. I&#8217;m apparently writing this article because I have convinced somebody that I might know something, likely due to something I&#8217;ve taught myself. As web professionals, we have to learn all sorts of skills. Each skill had to be given some portion of your attention, and likely that study made you a better person. As the years go by, people come to know you by your accomplishments, and you get paid to do those things. But what about the things on your self-improvement list? Do you ignore them because you ran out of time?</p>

<p>Every time I approach a new task, my own little mini Big Bang of ideas goes off in my head. The task could be something simple like &#8220;add a notification bubble next to the label whenever something funny happens.&#8221; Unfortunately, I&#8217;ve already thought of 100 associated things that I would like to do to add my personal touch, as well as technologies to help me achieve my goals. Obviously, I have deadlines to meet, and I can&#8217;t just add new tickets at will without discussing it with my team, but I can choose one of them that is important to me, that will help me add value to the project and learn something at the same time.</p>

<p>Lately, I&#8217;ve been interested in automated web application testing. That shit is hard. Real hard. There are so many daunting words just to get started: unit tests, functional tests, integrated tests, acceptance tests, test targets, test-driven development, behavior-driven development&#8230; holy shit! What gives? What approach and technology should I use? Someone might recommend: <a href="http://phpunit.de/">PHPUnit</a>, <a href="http://seleniumhq.org/">Selenium</a>, <a href="http://cukes.info/">Cucumber</a>, <a href="http://behat.org/">Behat</a>, <a href="http://mink.behat.org/">Mink</a>, <a href="http://casperjs.org/">CasperJS</a>, and <a href="http://pivotal.github.com/jasmine/">Jasmine</a>. That&#8217;s a lot of things just to make sure my application works. Dude, I&#8217;m a developer. I&#8217;m always trying to ensure that shit is working with my eyes, and now you&#8217;re throwing all this crap at me? Now I&#8217;m not so sure my shit is working&#8230; aw man&#8230;</p>

<p>Relax. Time out. Yes, there is surely a lot of information out there. There are infinite things to learn. It&#8217;s going to take some time, but you can do it, I keep telling myself. First I tried PHPUnit, then Selenium, then Behat, &#38;c. Did I get to my destination in the 15 minutes I wanted to? No, I did not. Am I learning? Yes, I am. When did I find the time to do this? I made time. I knew I had to work 8 hours today and for 1 of those 8, I changed gears and learned something to further my long term goals.</p>

<p>PHPUnit is for testing small blocks of code. Sure, I can write a test to make sure my function works, but how do I know it works in the larger context of the application? How do I know that when I click on a button, it loads the Ajax request, and then ultimately gets to that small block of code that already has a test. Well, then I would need to use something with a larger test target. In fact, I would love to write tests without using a programming language at all. Selenium IDE is built exactly for this reason. Now I have to learn two technologies just to make sure that I&#8217;m being a good developer and my feature is working. So last week, I set aside some time to learn both of these things, and I know more than I did a week ago. Testing is an incredibly deep topic. It&#8217;s going to take me a long time to learn how to do it right, but I had to start somewhere.</p>

<p>This is the only way to self-educate. You have to take the time to make the time. Knowledge is power, and in the technology field, relevant knowledge is evolving at an extremely fast rate. If you don&#8217;t take the time to keep your skills sharp, you will ultimately be left behind. Devote a small portion of your day for learning, and know that even a little is enough.</p>

]]></description>
              <link>http://webadvent.org/2012/take-time-to-make-time-by-jeff-loiselle</link>
              <guid>http://webadvent.org/2012/take-time-to-make-time-by-jeff-loiselle</guid>
              <pubDate>Thu, 20 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>The Three Ugly Sisters</title>
              <dc:creator>Pádraic Brady</dc:creator>
              <description><![CDATA[<p>The Three Ugly Sisters are three classes of attacks which I&#8217;ve tried to highlight in 2012. You might also know them as Cross-Site Scripting, XML Injection, and Insufficient Server-Side Transport Layer Security (or Peerjacking). These three attacks are particularly ugly for PHP programmers, because each, in its own way, has a common advantage for attackers&#8201;&#8212;&#8201;PHP does not defend against them automatically, and they are poorly documented and poorly understood by programmers. This potent mix of default vulnerabilities, programmer ignorance, and poor reference material culminate in the sort of security vulnerabilities that an attacker can find in the wild without trying very hard.</p>

<p>Let&#8217;s take a brief look at each of them.</p>

<h2>Insufficient server-side Transport Layer Security (Peerjacking)</h2>

<p>The easiest way to fathom the mysteries of Transport Layer Security is to remember that your web app sometimes behaves like a modern browser. It can make <code>GET</code> and <code>POST</code> requests like a browser, over HTTPS. It can act as an intermediary, shuffling a user&#8217;s personal data to and fro between your server and the server of any third party (including within your own network). It can consume masses of information, store it, and display it back to users, over HTTPS.</p>

<p>Browsers and SSL/TLS have a simple relationship. Browsers implement it correctly, strictly, and monitor their implementation and the <abbr title="Certificate Authorities">CAs</abbr> they trust very closely. Any failure on their part would be incredibly embarrassing and harmful to their share of the browser market.</p>

<p>Unfortunately, it is far from unusual to find PHP libraries and applications where SSL/TLS protections have been accidentally or even deliberately disabled. Since SSL/TLS is designed to prevent data interception, request manipulation, request replays, and other attacks that are designed to do harm to users, disabling SSL/TLS or being unaware of how to configure it correctly is not an acceptable behavior in PHP. Yet, it remains ludicrously common. As programmers, we also need to be familiar with the prevailing data privacy legislation, privacy ethics, and corporate guidelines which may apply to user data in the jurisdiction or corporate setting we operate within.</p>

<p>Here are two examples of inappropriate HTTPS usage in PHP followed by their correctly configured variants. There is one each for PHP Streams and the cURL extension. The common factor between them is actually very simple&#8201;&#8212;&#8201;they disable two essential checks in SSL/TLS which we can call <em>peer verification</em> and <em>domain matching</em>. Peer verification guarantees the validity of the SSL certificate offered by the contacted server. Domain matching ensures that the offered SSL certificate is for the host or domain name we connected to. If we fail to verify the peer&#8217;s SSL certificate, then we&#8217;d never notice if was a self-signed fake, or if it was signed by an untrusted Certificate Authority. It might also have expired. If we fail to perform domain matching, then the attacker could use <em>any</em> valid SSL certificate for <em>any</em> domain or host (whether one they purchased or stole the private key for), so long as the certificate used is capable of passing Peer Verification. So, you need both Peer Verification and Domain Matching enabled in order to be completely secure.</p>

<h3>PHP streams (the wrong way)</h3>

<pre><code>$url = 'https://api.twitter.com/1/statuses/public_timeline.json';
$result = file_get_contents($url);</code></pre>

<h3>PHP streams (the right way)</h3>

<pre><code>$url = 'https://api.twitter.com/1/statuses/public_timeline.json';
$contextOptions = array(
    'ssl' =&gt; array(
        'verify_peer'   =&gt; TRUE,
        'cafile'        =&gt; __DIR__ . '/cacert.pem',
        'verify_depth'  =&gt; 5,
        'CN_match'      =&gt; 'api.twitter.com'
    )
);
$sslContext = stream_context_create($contextOptions);
$result = file_get_contents($url, NULL, $sslContext);</code></pre>

<h3>cURL (the wrong way)</h3>

<pre><code>$url = 'https://api.twitter.com/1/statuses/public_timeline.json';
$req = curl_init($url);
curl_setopt($req, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($req, CURLOPT_SSL_VERIFYPEER, FALSE); // Disable Peer Verification
curl_setopt($req, CURLOPT_SSL_VERIFYHOST, 0); // Disable Host Matching
/** OR **/
curl_setopt($req, CURLOPT_SSL_VERIFYHOST, TRUE); // TRUE = 1 when it should be set to 2!
$result = curl_exec($req);</code></pre>

<h3>cURL (the right way)</h3>

<pre><code>$url = 'https://api.twitter.com/1/statuses/public_timeline.json';
$req = curl_init($url);
curl_setopt($req, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($req);

$error = curl_errno($req);
if ($error == CURLE_SSL_PEER_CERTIFICATE || $error == CURLE_SSL_CACERT
|| $error == 77) {
    curl_setopt($req, CURLOPT_CAINFO, __DIR__ . '/cert-bundle.crt');
    $result = curl_exec($req);
}</code></pre>

<p>While cURL on a platform like Ubuntu will be configured with access to a bundle of trusted Certificate Authority certs (e.g., the manually-added <code>cert-bundle</code> or <code>cacert</code> files from above), we should assume that this is probably not the default for many servers (and certainly not when using PHP&#8217;s HTTP stream wrapper). Make sure to configure a path to such a file as necessary and ensure libraries you use are doing the same!</p>

<p>As an exercise in awareness, use some of the configuration names above to run a search on libraries you use (or search on GitHub if feeling brave). The same exercise can apply to the following sections, too&#8201;&#8212;&#8201;these are not only common vulnerabilities, but also easy to locate with <code>grep</code>&#8201;&#8212;&#8201;their existence revealed by the detection, or lack thereof, of the key configuration constants and function names needed to enable or disable them.</p>

<p>For further reading, see <a href="http://phpsecurity.readthedocs.org/en/latest/Transport-Layer-Security-(HTTPS-SSL-and-TLS).html">Insufficient Transport Layer Security (HTTPS, TLS and SSL)</a>.</p>

<h2>XML injection (XMLi)</h2>

<p>This class of attacks revolve around PHP&#8217;s reliance on the <code>libxml2</code> extension used by <a href="http://php.net/dom">DOM</a>, <a href="http://php.net/simplexml">SimpleXML</a>, and <a href="http://php.net/xmlreader">XmlReader</a>. While it is typical to view XML as a simple text format, we should remember that XML can drive an interpreter (via PHP) to perform a number of unexpected actions. One of these is resolving external entity references.</p>

<p>A simple entity like <code>&amp;amp;</code> expands to a lone ampersand when you use DOM to extract the text it&#8217;s included in. Similarly, you can also define your own custom entities in XML. A simple entity defined as a very long string which is then repeated an awful lot of times in an XML document can turn any document with a modest filesize into a rapidly expanding RAM eating monster when the custom entity is resolved into ever larger chunks of text, i.e., a Quadratic Blowup Attack. For example:</p>

<pre><code>&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE results [&lt;!ENTITY long "SOME_SUPER_LONG_STRING"&gt;]&gt;
&lt;results&gt;
    &lt;result&gt;Now include &amp;long; lots of times to expand
    the in-memory size of this XML structure&lt;/result&gt;
    &lt;result&gt;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;
    &amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;
    &amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;
    &amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;
    Keep it going...
    &amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;&amp;long;...&lt;/result&gt;
&lt;/results&gt;</code></pre>

<p>This raises a serious risk&#8201;&#8212;&#8201;we can get XML from third-party services, from users via the browser (e.g., Ajax), and even from our own local filesystem in configuration files both written by us and distributed with third-party libraries and applications. That&#8217;s a lot of exposure to XML&#8201;&#8212;&#8201;a lot of potential targets for an attacker.</p>

<p>Custom entities can also refer to external XML resources, i.e., an external entity. Such external resources can be retrieved by using a PHP stream reference like a file path, a URL, or a PHP filter wrapper URI (to base64 encode non-XML content retrieved). This feature, which is enabled in PHP by default, means that any interpreted XML can potentially access such resources, have them inserted into the textual context of any XML element, and then potentially displayed back to the attacker. This therefore leaves local files readable by PHP and local URLs subject to localhost style access controls subject to Information Disclosure. It may also facilitate making the victim an unwilling participant in a DDoS attack on themselves or a third party.</p>

<pre><code>&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE results [
    &lt;!ENTITY harmless SYSTEM
    "php://filter/read=convert.base64-encode/resource=/etc/secretfile"
    &gt;
]&gt;
&lt;results&gt;
    &lt;result&gt;I am &amp;harmless; - honest!&lt;/result&gt;
&lt;/results&gt;</code></pre>

<p>The defense to XML Injection is simply to disable custom entities wherever possible. Luckily, <code>libxml2</code> has an innate defense against other exponential attacks such as the Billion Laughs attack where deeply nested entities (all referring to each other) can be packed into an even smaller XML file.</p>

<pre><code>libxml_disable_entity_loader(true);</code></pre>

<p>And, optionally, as a sanity check before accepting any XML for processing:</p>

<pre><code>$dom = new DOMDocument;
$dom-&gt;loadXML($xml);
foreach ($dom-&gt;childNodes as $child) {
    if ($child-&gt;nodeType === XML_DOCUMENT_TYPE_NODE) {
        throw new \InvalidArgumentException(
            'Invalid XML: Detected use of illegal DOCTYPE'
        );
    }
}</code></pre>

<p>For further reading, see <a href="http://phpsecurity.readthedocs.org/en/latest/Injection-Attacks.html#xml-injection">XML Injection Attacks</a>.</p>

<h2>Cross Site Scripting (XSS)</h2>

<p>XSS is never too far from the minds of a PHP developer. One area that still needs improvement is weaning PHP developers away from the concept of <code>htmlspecialchars()</code> being the sole defense required. In reality, XSS can target not only HTML, but also JavaScript, URIs, and CSS. Outside of the HTML context, our obsession with <code>htmlspecialchars()</code> is utterly useless and borders on misinformation, since articles and books on the topic frequently omit anything beyond HTML escaping. We need other escaping methods suited to these other contexts. This is referred to as <em>context-based escaping</em>.</p>

<p>Aside from context-based escaping, there is the continual need to be wary of allowing users to submit textual data as HTML. The two usual methods for allowing users to use HTML securely is to employ something like <a href="http://www.htmlpurifier.org/">HTML Purifier</a> (the only solution of this type I recommend) or a simpler intermediary syntax such as BBCode or Markdown. Markdown has gained popularity among programmers&#8201;&#8212;&#8201;it&#8217;s the primary format used by GitHub. The problem with intermediary languages is that they are converted into HTML, so you still need to use HTMLPurifier on their output! It&#8217;s a subtle misunderstanding, but intermediary languages are for the benefit of the users not the security of your application. Markdown actually includes all of HTML (including script tags) as valid Markdown syntax.</p>

<p>In terms of context-based escaping, your best choice is to use an established solution that can be peer reviewed and rapidly tested. Zend Framework 2 offers the reusable <code>\Zend\Escaper</code> class as a starting point. If you use Symfony 2, the <code>Twig</code> library includes <code>\Zend\Escaper</code> compatible escaping methods for HTML, HTML attributes, JavaScript, and CSS.</p>

<p>Outside of this approach, you should be wary of custom JavaScript escaping. A recent recommendation emerging online is to use the <code>json_encode()</code> function for escaping JavaScript string literals and integers. These recommendations usually neglect to mention that JSON encoding and JavaScript encoding are not the same thing. If using <code>json_encode()</code>, you should be aware that it only supports <code>UTF-8</code>, and you <em>must</em> use many of its allowed flags from PHP 5.3. Avoid it altogether for PHP 5.2&#8201;&#8212;&#8201;it doesn&#8217;t even escape the ampersand, which can be used to construct HTML entities interpretable in XML-serialised HTML5 or any other HTML where a <code>DOCTYPE</code> has not been defined for the document (i.e., what you expect to be <code>CDATA</code> data may end up being <code>PCDATA</code> in some circumstances).</p>

<p>For further reading, see <a href="https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet">XSS (Cross Site Scripting) Prevention Cheat Sheet</a> and <a href="https://wiki.php.net/rfc/escaper">Escaping RFC for PHP Core</a>.</p>
]]></description>
              <link>http://webadvent.org/2012/the-three-ugly-sisters-by-p%C3%A1draic-brady</link>
              <guid>http://webadvent.org/2012/the-three-ugly-sisters-by-p%C3%A1draic-brady</guid>
              <pubDate>Wed, 19 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>Node.js with Express.js in Business</title>
              <dc:creator>Andreas Birkebæk</dc:creator>
              <description><![CDATA[<p>The fundamental processes behind business and software development are very different, and it&#8217;s often the reason why getting the two working together can be challenging.</p>

<p>In business, you&#8217;re often able to test ideas quickly and without major costs, which means that an experimental approach to development is common. In software development, you aren&#8217;t able to test your ideas as quickly, because you need things to be stable and that costs time and money. This means that software development depends on well-specified needs that business people have a hard time articulating, because they are not used to doing that.</p>

<p>There are many ways to go about improving this. One option is prototyping, and another option is for the business people to acquire a better understanding of how software development works, thereby improving the foundation for good communication.</p>

<p>I think learning <a href="http://nodejs.org/">Node.js</a> with <a href="http://expressjs.com/">Express.js</a> can be a great way for business people to gain an understanding of how software development works that lets them improve the relationship in two different ways: by building prototypes that can help them explain what they want, and by being better at speaking the language of developers.</p>

<h2>Node.js</h2>

<p>Node.js is JavaScript, and the very expressive nature of the language makes the code relatively easy to understand. This lets you learn as you go with a very limited understanding of the language. That might not be the optimal way to go about it, but it builds motivation that keeps you going.</p>

<p>It has a big and active community that builds awesome frameworks and modules, so when obstacles arise, chances are good that you can find a module or a fellow developer that can help you out. This keeps you moving forward.</p>

<p>Node can be used to a lot of other things too, like building a web or chat server, and that encourages you to try and understand how it all works together, and it makes you feel very empowered by just learning one language.</p>

<h2>Express.js</h2>

<p>Building web apps with Node lets you iterate and change the structure of your app very easily, because it is JavaScript on both the server side and the client side. Express.js is one of the most popular web app frameworks for Node, and it takes care of a lot of things while remaining light and flexible. This fits an experimental and iterative approach very well.</p>

<p>It&#8217;s super easy to install, and it&#8217;s amazing how quickly you can get an app running. The only steps you need to go through are<a href="#footnote-1" id="footnote-1-return" class="footnote">1</a>:</p>

<ul>
    <li>Install Express.js: <code>npm install express</code></li>
    <li>Generate the app: <code>express myapp</code></li>
    <li>Install dependencies: <code>cd myapp &amp;&amp; npm install</code></li>
    <li>Run the app: <code>node app</code></li>
    <li>Access the app at: <code>localhost:3000</code></li>
</ul>

<p>Express defaults to using <a href="http://jade-lang.com/">Jade</a>, which is a template engine (in other words, a different way to write HTML and insert data into it) for Node. But, if you prefer using HTML and <a href="http://handlebarsjs.com/">Handlebars.js</a>, you can do that. First, install a few packages:</p>

<pre><code>npm install html
npm install hbs</code></pre>

<p>Next, change some settings. In the <code>app.js</code> file, change <code>app.set('view engine', 'jade')</code> to <code>app.set('view engine', 'html')</code>.</p>

<p>Then, configure the app to use <code>hbs</code> by adding this line:</p>

<pre><code>app.engine('html', require('hbs').__express);</code></pre>

<p>Now, rename <code>index.jade</code> to <code>index.html</code> and have it print the title with HTML and Handlebars.js:</p>

<pre><code>&lt;h1&gt;{{title}}&lt;/h1&gt;</code></pre>

<p>Relaunch<a href="#footnote-2" id="footnote-2-return" class="footnote">2</a> the app, go to <code>localhost:3000</code>, and it should display the title that is set in the route.</p>

<h2>Development</h2>

<p>The framework doesn&#8217;t make any assumptions in terms of how you want to structure your code, so you&#8217;re free to do what makes sense to you for the current project. That can be a bit confusing at first, so let&#8217;s look at an example of how you&#8217;d begin the development of an app.</p>

<p>Let&#8217;s say that you want to have a page that shows some numbers about your business. To handle that, you&#8217;ll need a new route and a view, and you&#8217;ll have to tell the app where you want the page to be.</p>

<ol>
    <li>Add a <code>numbers.js</code> file to the routes directory, and paste in the code from the index route. Configure it to render the numbers view instead of the index view.</li>
    <li>Add a <code>numbers.html</code> file to the views directory.</li>
    <li>Add this line to your <code>app.js</code> file: <code>app.get('/numbers', routes.numbers);</code></li>
</ol>

<p>By adding this line of code, the numbers route will be called when <code>/numbers</code> is requested, and the route will then grab the data and render the view.</p>

<p>You can now start adding logic to the route that gets the data you need, but you&#8217;ll soon need a model that can take care of pulling in data from other services such as a database. Express doesn&#8217;t suggest a place to keep the models, but as long as you only have a few, just put them in the root directory. As you app grows, and you get more routes, views, and models, you can adjust the structure to your liking, and by that time, you&#8217;ll know exactly what that is.</p>

<h2>Conclusion</h2>

<p>In summary, Node.js with Express.js is great for business people, because it&#8217;s easy to learn, it can be used to do a lot of different things, and it encourages you to understand how the Web works. It empowers you to build things quickly and iterate until you&#8217;re happy, which is a great way to prototype and demonstrate your ideas.</p>

<p>So, if you&#8217;re a business person (we all are), and you have ideas that you&#8217;d love to see brought to life (we all do), consider Node.js with Express.js. It&#8217;s awesome.</p>

<h2 id="footnotes">Footnotes</h2>
<ol class="footnotes">
    <li id="footnote-1"><p>Assuming that you&#8217;re on a Mac and have Node.js and NPM installed. If you don&#8217;t already have Node.js installed, head over to <a href="http://nodejs.org/">nodejs.org</a>. <a href="#footnote-1-return" class="footnote-return"><span>Return to footnote 1 source.</span>&#8593;</a></p></li>
    <li id="footnote-2"><p><a href="https://github.com/remy/nodemon">Nodemon</a> is a great tool that automatically relaunches the app when you save. So, if you don&#8217;t like to constantly relaunch it, this will be your friend. <a href="#footnote-2-return" class="footnote-return"><span>Return to footnote 2 source.</span>&#8593;</a></p></li>
</ol>]]></description>
              <link>http://webadvent.org/2012/node-js-with-express-js-in-business-by-andreas-birkeb%C3%A6k</link>
              <guid>http://webadvent.org/2012/node-js-with-express-js-in-business-by-andreas-birkeb%C3%A6k</guid>
              <pubDate>Tue, 18 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>Retina Ready</title>
              <dc:creator>Jackie Balzer</dc:creator>
              <description><![CDATA[<p>When you get your shiny new retina device this holiday season, will the Internet be ready for you to see all its content in twice the pixel density glory? Probably not. But, this handy guide will help get your site &#8220;retina ready&#8221; in no time.</p>

<h2>Pixel density? Retina ready? Say what?</h2>

<p>Many new mobile devices are built using special display panels that are capable of displaying more pixels per inch than the standard display you&#8217;re probably used to. For Apple products (iPhones, iPads, &#38;c.), the density is twice as many pixels as usual. Android device pixel density can range from 1.3 to 2 times as many. When you view an image on a high pixel density device, it is doubled in width and height to compensate for the smaller pixels, meaning your image only has 1 pixel to fill for every 2 (or so) on the screen. This is why &#8220;1x&#8221; images look blocky on high pixel density displays. One of the fastest and easiest ways to improve the look of a website on retina displays is to offer a &#8220;2x&#8221; version of every image, so the pixels fill up natively and without up-sampling.</p>

<p>Here&#8217;s an example showing a 1x image (left) and the 2x version (right):</p>

<img src="http://webadvent.org/i/jackie-balzer-example.png" />

<h2>How do I make my web site retina ready?</h2>

<p><a href="http://compass-style.org/">Compass</a>, a framework for the CSS pre-processor <a href="http://sass-lang.com/">Sass</a>, has built-in image functions that will build 1x and 2x assets for your web site with just a couple lines of code. By specifying the location of a folder full of images, Compass can stitch them together into a single sprite and provide you with all the CSS classes, background positions, and pixel dimensions you need to start using your sprite right away.</p>

<p>The first step is getting all the individual images. To be &#8220;retina ready&#8221;, you&#8217;ll need the regular versions of all your images as well as one twice as big as the original (the 2x version). The method works by displaying the 2x sprite only on retina devices and CSS-resizing it back down to its 1x dimensions. That way your image fits into your design the same way it did originally, but all the extra pixels are there for your device to use to display a sharp picture. A tool like <a href="http://macrabbit.com/slicy/">Slicy</a> will make exporting multiple images from Photoshop a snap, and even automatically generate 2x versions of vectors and layer styles for you.</p>

<p>Once you&#8217;ve got all your images, just split them into two folders, one for the standard 1x images and a second for the 2x images:</p>

<pre><code>images/
    icons/
        star.png
        heart.png
    icons-2x/
        star.png
        heart.png</code></pre>

<p>Next, you&#8217;re ready to start coding. Just a few lines of Sass will get you everything you need:</p>

<pre><code>$icons-layout: smart;
$icons-2x-layout: smart;

$icons-sprite-dimensions: true;

@import "icons/*.png";
@import "icons-2x/*.png";

@include all-icons-sprites;</code></pre>

<p>Let&#8217;s break this code down:</p>

<ol>
    <li>Lines 1 and 2 tell Compass how to lay out the images in both the 1x (icons) and 2x (icons-2x) sprite. &#8220;Smart&#8221; mode arranges the images in the least amount of space possible. We want both sprites to use the same layout mode.</li>
    <li>Line 3 line tells Compass that we are going to want the generated CSS to include the dimensions of each image.</li>
    <li>Lines 4 and 5 tell Compass to build a sprite using the PNG files in the imported directory.</li>
    <li>Line 6 tells Compass to generate the CSS for the 1x sprite.</li>
</ol>

<p>Once you compile your Sass file, you should see two new images appear (your sprite files) and one new CSS file containing all the class names (based off the image file names), background positions, and dimensions of each image in the sprite. Your sprite is 100% ready to go; just apply one of the class names to an element in your markup, and your image will appear. How easy was that&#8253;</p>

<p>Here are the 1x and 2x sprites:</p>

<img src="http://webadvent.org/i/jackie-balzer-icons.png"  style="display: inline-block; vertical-align: middle; " />

<img src="http://webadvent.org/i/jackie-balzer-icons-2x.png" style="display: inline-block;  vertical-align: middle;" />

<p style="clear: left;">If you&#8217;re wondering why we didn&#8217;t also generate CSS for the 2x sprite, think back to how we said we would CSS resize it down to fit into its original 1x dimensions: because both sprites are laid out identically, we can let the CSS-downsized 2x sprite rely on the background-positions and dimensions of the 1x sprite. The last step is to simply add CSS to swap out the file path and CSS downsize the sprite when on a retina display:</p>

<pre><code>@media (min--moz-device-pixel-ratio: 1.3),
       (-o-min-device-pixel-ratio: 2.6/2),
       (-webkit-min-device-pixel-ratio: 1.3),
       (min-device-pixel-ratio: 1.3) {
    .icon {
        background-image: sprite-path($icons-2x-sprites);
        background-size: image-width(sprite-path($icons-sprites)) image-height(sprite-path($icons-sprites));
    }
}</code></pre>

<p>That&#8217;s it! The browser will now serve up the 2x sprite in place of the 1x on high pixel density devices, and your web site will look sharper than ever when you view it on your new iPad 4 (or iPhone 5, or Galaxy Note II, or Nexus 10, or&#8230;) this holiday season. Happy browsing!</p>
]]></description>
              <link>http://webadvent.org/2012/retina-ready-by-jackie-balzer</link>
              <guid>http://webadvent.org/2012/retina-ready-by-jackie-balzer</guid>
              <pubDate>Mon, 17 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>Security in the Round</title>
              <dc:creator>Chris Cornutt</dc:creator>
              <description><![CDATA[<p>As a developer, I know it&#8217;s easy to get tunnel vision when it comes to security. You look through the lines of code in your app and try to think like an attacker. You try to break things, perform injection attacks, and escape your output appropriately, but you&#8217;re missing something. Stick with me, and you&#8217;ll see what I mean.</p>

<p>There has always been theater of one sort or another. As long as there&#8217;ve been stories to tell, there&#8217;ve been people sitting in a group enjoying them. Theater troupes were formed to bring a more professional kind of presentation to crowds in the area, traveling around and sharing their stories with the masses. If you have attended any kind of play in recent times, though, you know that the audience is always in the front, facing the stage and enjoying a one-sided look into the lives of the characters on stage. They laugh, cry, and suspend their disbelief for a while, losing themselves in the story unfolding on stage.</p>

<p>It wasn&#8217;t always like this. Sure, you can do some great things when the audience can&#8217;t see certain parts of the stage&#8201;&#8212;&#8201;amazing sets, quick costume changes, and special effects that wow audiences. There&#8217;s another kind of theater that wows the crowd in a completely different way, though. The <a href="http://en.wikipedia.org/wiki/Theatre_in_the_round">theater in the round</a> format, where the audience surrounds the actors and sees them from all angles, brings a certain openness and engagement to the experience. Audience members are no longer just spectators; they feel involved in the play. The actors have to work harder to bring audience members into their world&#8201;&#8212;&#8201;no elaborate sets, no hidden tools for special effects, just actors doing what they do best.</p>

<p>The key to the theater in the round format is that the audience can see all sides at once. Nothing is hidden, and the actors have to try even harder to make things work.</p>

<p>On the security stage, we&#8217;re the actors, and it&#8217;s essential that no matter how we go about implementing the security of our apps, we consider more than just the code.</p>

<p>A &#8220;security in the round&#8221; view, much like the audience&#8217;s perspective at a performance, allows for visibility into all parts of the environment. Depending on the company (and the environment), this can either be as easy as opening a document and checking out a schema, or it can be as difficult as herding cats into getting their knowledge out of their heads and down on paper. Fortunately, most development groups have a pretty good overall understanding of where their app lives, what kinds of systems they connect to, and what technologies they use.</p>

<p>&#8220;But, I&#8217;m just a developer,&#8221; you exclaim! &#8220;Other than making sure there are no exploits in my code, what else can I do?&#8221; This is a <em>dangerous</em> mindset to get into and can lead to some big issues down the line. Much like the actors in the theater in the round, you can&#8217;t ignore the other parts of your environment. You have to take the whole app into account, making sure to view it from the perspective of everyone in the audience. Without a good overall view of the app, you can&#8217;t possibly create an effective security plan to keep your users and their data safe (sometimes even from themselves).</p>

<p>A holistic view of your app&#8217;s environment lets you not only look at the possible issues that could come up as a result of some of the most common exploits (like cross-site scripting and SQL injection), but also lets you assess other threats like data corruption or code injected from other malicious sources.</p>

<p>Here are a few questions you can use to map out this overview:</p>

<ol>
    <li>What kind of storage does my app use? Where is it?</li>
    <li>Are there any firewall or network restrictions in place?</li>
    <li>Do I have anything extra installed on my server(s) that I don&#8217;t need?</li>
    <li>Is my deployment method secure? Could bad code get into the live site without me knowing?</li>
    <li>Is my data protected if my app has an exploit that allows access?</li>
</ol>

<p>These five are just a start to the long list of questions you might need to answer. (Be sure to check the list twice.) The answers can be very revealing, especially if you&#8217;re dealing with a dreaded legacy app.</p>

<p>So, get your head out of the code and take a look around at the entire environment surrounding it. Take out a piece of paper (or something <a href="http://en.wikipedia.org/wiki/Comparison_of_network_diagram_software">more high tech</a> if you prefer), and diagram how things are set up; figure out what points will connect to your app. This gives you a much better picture of what parts you&#8217;ll need to protect and how you can best keep your users safe as they use your service. Keep this diagram close are you progress through the life of the app. Map out the new sections and features similarly, and figure out where their connections are and what risks might be associated with them.</p>

<p>With this in hand you can then <a href="http://www.binomial.com/security_plan/why_you_need.php">create a security plan</a> tailored to your app, helping you and your users have even more silent nights knowing your data is safe.</p>
]]></description>
              <link>http://webadvent.org/2012/security-in-the-round-by-chris-cornutt</link>
              <guid>http://webadvent.org/2012/security-in-the-round-by-chris-cornutt</guid>
              <pubDate>Sun, 16 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>More Than a Dot</title>
              <dc:creator>James Duncan</dc:creator>
              <description><![CDATA[<p>No one knows if it was a man, or a woman, or a child that first did it, but we do know that about 40,000 years ago, someone put a faint red dot on the wall of a cave in Spain.</p>

<p>Humankind has always felt a burning desire to record information and transmit it into the future. What that dot meant, no one really knows. Perhaps it was the first expression of binary?</p>

<p>Perhaps it was just a dot.</p>

<p>7,000 years later, and our ancestors were expressing themselves in the form of horses, panthers, cave bears, mammoths, and much more inside different caves, this time in the south of France. It&#8217;s the first example of recorded history, the first transmission into the future.</p>

<p>It took many thousands more years until we discovered writing. The Sumerians started scraping sigils into clay tablets and baking them&#8201;&#8212;&#8201;an act which preserved them almost forever, and because of it we, know so much about their society and the way it worked.</p>

<p>Now, of course, we have the Web, and the world has been transformed. So much information is available that our biggest problems are sorting, classifying, filtering, and absorbing, and the rate at which information is growing is staggering. In 2010, we broke the zettabyte barrier, and in 2011, nearly 1.8 zettabytes of information was created, stored, and replicated. Numbers aren&#8217;t available for 2012 yet, but we can safely assume that it will have been greater, and that 2013 will be greater still.</p>

<p>The scale is phenomenal. If a penny represented every gigabyte of storage that was consumed, you could use nothing but pennies to construct a 1:1 replica of the Empire State Building in New York and still have some change left over for a cup of coffee when you were done with your labors.</p>

<p>As we are creating all this information, the way in which we are realizing we can use it is changing. We&#8217;re structuring the unstructured, and turning the unknowable into knowledge. We&#8217;re making tools for navigating the data more effectively, and we&#8217;re learning that sometimes raw information is knowledge&#8201;&#8212;&#8201;you just have to know to ask the right questions.</p>

<p>Improvements in the browser technology available is allowing web developers to push the boundaries of what was thought possible. Our interfaces are richer, and the interactivity is far greater than it ever has been before.</p>

<p>It&#8217;s not just the browser&#8201;&#8212;&#8201;far from it. As our processing spills out of our homes and offices and onto our smart phones and smart devices, the Web has ceased to be just about the browser. The Web has become a message bus. A conduit by which information is ferried back and forth, not just from server to client, but from client to client as well. I can share my thoughts and feelings with friends on the other side of the world instantly, and to the extent that sometimes it doesn&#8217;t feel as though there is any distance at all.</p>

<p>Each development spurs a rush of new apps and new ways of looking at older data, which creates new data that pushes us forward again. It&#8217;s not that our time to market is shrinking, it&#8217;s that our time to market has become instantaneous, and our tools and techniques are adapting to cope with that.</p>

<p>However, as the end of the year approaches, I get reflective, and I find myself looking at the Web and worrying about one thing. 40,000 years from now, when our descendants cast their gaze back on the Web, will they understand what we were saying?</p>

<p>Have we preserved the knowledge we&#8217;re creating for future generations, or are we just doing the best we can to keep up with the rate that we&#8217;re creating it? Can we be sure that we&#8217;re doing the equivalent of writing on clay tablets, baked in the sun and made to last forever?</p>

<p>And, once we are sure of that, will our children&#8217;s children&#8217;s children still be able to make sense of what we have to say, or have we become so myopic that we no longer care about transmissions further into the future than our own lifetimes? Will our apps still serve them as they have served us? Are we the architects of a library, or of Babylon?</p>

<p>I&#8217;d certainly like to think we&#8217;re creating more than just a dot.</p>
]]></description>
              <link>http://webadvent.org/2012/more-than-a-dot-by-james-duncan</link>
              <guid>http://webadvent.org/2012/more-than-a-dot-by-james-duncan</guid>
              <pubDate>Sat, 15 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>Persistent Terminal Sessions</title>
              <dc:creator>Remy Sharp</dc:creator>
              <description><![CDATA[<p>Have you ever had a remote terminal session running, only to have your connection drop out half way through a large task? Then, you reconnect, not knowing anything about its progress (if any) and current status.</p>

<p><a href="http://www.gnu.org/software/screen/manual/screen.html">Screen</a> is the solution to this problem. Screen allows you to start terminal sessions that you can disconnect from and resume at any time.</p>

<p>I personally use screen a lot with <a href="http://nodejs.org/">Node.js</a> web servers, so I can kick off the process, and resume my terminal session to check logs or errors, or restart the process if it died.</p>

<p>This article is an introduction to Screen for the average developer, including a few tips and tricks.</p>

<h2>Installing</h2>

<p>Screen is a Unix tool, so with Ubuntu, you can use <code>apt-get</code> to install it:</p>

<pre><code>sudo apt-get install screen</code></pre>

<p>It&#8217;s also possible it&#8217;s pre-installed; just type <code>screen</code> to find out.</p>

<h2>Instant win with Screen</h2>

<p>When I remote in to a server, I run <code>screen</code>, and it starts a new session (and a window, but more about these later). There&#8217;s a blurb about what Screen is, I hit return, and the session is ready.</p>

<p>From here, I might start my process. Let&#8217;s say I&#8217;m doing a large database export.</p>

<p>Now, I need to <em>detach</em>, so I can cleanly close the remote session or do something else while the export is happening. To do this, I type Ctrl+A, followed by D.</p>

<p>This will leave the session running and detach from Screen, so you&#8217;re back to your original terminal prompt.</p>

<p>To resume your Screen session:</p>

<pre><code>screen -r</code></pre>

<p>But, what if my connection drops and closes while I&#8217;m inside Screen? When I resume my SSH session, the screen <em>could</em> still be attached, so when I type <code>screen -r</code>, it won&#8217;t resume. This is simple to get around; you can detach from <em>outside</em> of the Screen session (and, in our case, immediately resume using <code>-r</code>):

<pre><code>screen -dr</code></pre>

<p>Now that you have a basic understanding of Screen, how about using some of its features? Multiple Screen sessions, multiple windows, naming Screen sessions &#38; windows, setting defaults like scrollback, &#38;c.</p>
<h2>Screen commands</h2>

<p>When you run Screen more than once, you&#8217;ll have multiple active Screen sessions. To list the available sessions:</p>

<pre><code>screen -ls</code></pre>

<p>If you have more than one, you&#8217;ll need to indicate the session you want to resume:</p>

<pre><code>$ screen -ls
There are screens on:
    17566.ttys001.remys-mba (Detached)
    18778.ttys001.remys-mba (Detached)
    19014.ttys001.remys-mba (Detached)

$ screen -r 18778</code></pre>

<p>This will resume the second session (identified by its process ID). You can also resume the last session using <code>screen -RR</code>. But, resuming using PIDs is ugly, so let&#8217;s name the sessions as we create them using the <code>-S</code> argument:</p>

<pre><code>$ screen -S database-dump
[Ctrl+A D]
$ screen -ls
There are screens on:
    17566.ttys001.remys-mba (Detached)
    18778.ttys001.remys-mba (Detached)
    19014.ttys001.remys-mba (Detached)
    18898.database-dump (Detached)

$ screen -r database-dump</code></pre>

<p>Now that you know how to have multiple (named) Screen sessions, let&#8217;s look at multiple windows per session.</p>

<h2>Windows</h2>

<p>Screen supports having multiple <em>windows</em> inside a Screen session, so you can have one screen and multiple windows, each dealing with specific jobs.</p>

<p>To create a new window inside a Screen session, type Ctrl+A, followed by C.</p>

<p>The initial window is 0, the second is 1, and so on. There are a number of ways to switch windows:</p>

<pre><code>Ctrl+A [n]     // where [n] is the window number
Ctrl+A Ctrl+A  // switch to the last used window
Ctrl+A "       // show a list of all the windows
Ctrl+A A       // change the title of this window</code></pre>

<p>There are <a href="http://linux.about.com/od/Bash_Scripting_Solutions/a/The-Linux-Screen-Terminal-Window-Manager-Key-Bindings.htm">lots more key bindings</a> you can use to navigate windows, but they&#8217;re beyond the scope of this article.</p>

<h2>Tricks</h2>

<p>Even if you use Screen in its simplest form (as I usually do), I wanted to share a few tricks I&#8217;ve discovered.</p>

<h2>Multi-user sessions</h2>

<p>To connect two (or more) users to an existing screen session:</p>

<pre><code>screen -rx</code></pre>

<p>Instead of detaching any users attached to the session (which is what would happen if we just used <code>-r</code>), this lets me join the session, and anything I type in my window is echoed to any other users connected to the screen.</p>

<p>Maybe this could be useful for remote support, or perhaps training. I&#8217;ve not used this in the wild yet, but it&#8217;s certainly a fun idea!</p>

<h2>Keeping history</h2>

<p>One problem with Screen is the scrollback. If you try to scroll up inside a session, instead of doing what you&#8217;d expect, the session itself just scrolls away. To scroll back inside a session, you have to use `<code>Ctrl+a [</code>. Now, you can use your keyboard to navigate up and down (this is actually in <em>copy mode</em>). You can hit escape to return back to the prompt.</p>

<p>What might be more useful than a scrollback is a log of the Screen session, which can be toggled on using <code>Ctrl+A H</code>. This can be enabled by default with a <code>.screenrc</code>.</p>

<h2>Screen Defaults</h2>

<p>Finally, I&#8217;ll leave you with my own <code>.screenrc</code>. Create this file in your home directory to set your own defaults for Screen:</p>

<pre><code># Always show a status line in the window footer.
hardstatus on
hardstatus alwayslastline
hardstatus string "%{.bW}%-w%{.rW}%n %t%{-}%+w %=%{..G} %H %{..Y} %m/%d %C%a "
            
# Auto-detach session on hangup instead of terminating Screen.
autodetach on 
    
# Turn off the splash intro.
startup_message off

# Enable log on all windows.
deflog on</code></pre>
]]></description>
              <link>http://webadvent.org/2012/persistent-terminal-sessions-by-remy-sharp</link>
              <guid>http://webadvent.org/2012/persistent-terminal-sessions-by-remy-sharp</guid>
              <pubDate>Fri, 14 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>Continuous Deployment Practices</title>
              <dc:creator>Laura Thomson</dc:creator>
              <description><![CDATA[<p>I may be a pedant, but I&#8217;m here to tell you that continuous deployment is a total misnomer. It&#8217;s discrete. A true continuous process would have code flowing naturally from your brain, through your fingers, keystroke by keystroke, to production, through some sort of bizarre stream of consciousness pipeline.</p>

<p>Now that I&#8217;ve got that out of the way, I&#8217;ll give you the common definition, which is that you ship changes on a commit-by-commit basis, or alternatively, as frequently as you desire. What most people think of is push-per-change, which is often not actually the case.</p>

<p>In practice, most <abbr title="continuous deployment">CD</abbr> setups are automated, not automatic. What this means is that although every step from code commmit to ready-to-push may be automated, at the end of the day there&#8217;s some kind of Big Red Button or one-line script or <abbr title="Internet Relay Chat">IRC</abbr> bot that you activate in order to deploy.</p>

<h2>Why would I want to do CD?</h2>

<p>Hipster cred. Seriously, though, the goal is to minimize the amount of work needed between finishing an idea and making it real. That&#8217;s a worthy goal.</p>

<p>A side benefit is that building the tools, processes, and skills needed for CD will make your working life better. </p>

<h2>Good practices for CD</h2>

<p>I put up a list of practices in a talk and called them &#8220;requirements.&#8221; <a href="http://elblinkin.info/">Laura Beth Denker</a> called me on it. She said these things are not true requirements for doing CD, because people do it with none of these requirements satisfied. She&#8217;s right. Let me suggest instead that it would be <em>a good idea</em> to do some, if not all, of these things before adopting CD. Most of these practices are a good idea in any case.</p>

<p>The practices in the following sections are not all-encompassing, and I&#8217;m sure there are great practices of which I am totally unaware.</p>

<h3>Continuous integration</h3>

<p>This is the practice of having developer changes land on a shared version control system as they are completed. (The original version, in Extreme Programming, says &#8220;several times a day&#8221; but velocity is irrelevant in my view.) <abbr title="Continuous Integration">CI</abbr> presumes you are using a <abbr title="version control system">VCS</abbr>. You are, right? Since <a href="http://github.com/">GitHub</a> made version control a commodity, there is no longer any excuse to not have a source repopository.</p>

<h3>Build-on-commit</h3>

<p>&#8220;<em>But, I&#8217;m writing code in PHP/Python/Ruby, and I don&#8217;t need to build anything. That&#8217;s for compiled languages.</em>&#8221; It may be true that, in your environment, the build part of the process is a <abbr title="No Operation">NOOP</abbr>, however, it may involve steps like:</p>

<ul>
    <li>Minification of CSS and JS</li>
    <li>Running a localization script to combine templates with string files</li>
    <li>Converting your dynamic code to some kind of intermediate format</li>
</ul>

<p>The net result of a build process like this is to spit out at the other end a build artifact which will be deployed.</p>

<h3>Test-on-commit</h3>

<p>This is where you take that build and run your tests on it. Tests. Yep, I said it. I sincerely hope this part of your process isn&#8217;t a NOOP. There are great tools for this now. My team uses <a href="http://jenkins-ci.org/">Jenkins</a>, and lots of people like <a href="http://travis-ci.org/">Travis CI</a>.</p>

<p>Recently, we&#8217;ve been automatically running tests on pull requests using <a href="https://github.com/litl/leeroy">Leeroy</a>. Travis CI does this, too. It&#8217;s so nice to avoid a code review, because I can see that your pull request doesn&#8217;t pass tests!</p>

<h3>Good test coverage</h3>

<p>Having 100% unit test coverage is nice, but it can make developers over-confident. Full test coverage doesn&#8217;t cover integration testing, or performance testing, and in an ideal world, your automation would do both of those things. The most important thing is to know what your tests cover and have a realistic assessment of what the holes are, and the level of risk.</p>

<h3>A staging environment that reflects production</h3>

<p>The developer&#8217;s own machine is a horrible staging environment. Get a real one. Make it as close to production as possible. The biggest issue I see in staging environments is what I call the &#8220;single box of fail.&#8221; In staging, you have one machine. In prod you have, say, ten web heads, one DB master, three DB slaves, some Redis or Memcache machines, and a queue, all running on different servers. In this environment, you will have failures.</p>

<p>I have been bitten by this a hundred times, and it still bites me. It bit me last Wednesday, in fact, when it turned out our PostgreSQL puppet manifests were ever-so-slightly different in staging and production. Don&#8217;t be me. Make your own novel mistakes.</p>

<h3>Managed configuration</h3>

<p>Speaking of Puppet, you should use something to manage configuration of your machines. Puppet, Chef, CFEngine&#8201;&#8212;&#8201;pick something.</p>

<h3>Single-button deployment</h3>

<p>You should have scripted, single-button deployment to all of the machines in your infrastructure. (You should also be able to deploy to individuals or groups.) Again, there are a ton of tools that will do this for you. Pick one, or roll your own.</p>

<h3>Failure plan</h3>

<p>You need a plan for what you&#8217;re going to do if things go horribly wrong. In practice, there are two basic approaches:</p>

<dl>
    <dt>Rollback plan</dt>
    <dd>This can be as simple as being able to deploy a previous build. Remember, you need reverse data migrations.</dd>
    <dt>Feature flagging</dt>
    <dd>Build your code so that you can turn features off and on, or turn them on for sub-groups of users (beta testers, or employees, or a random 10% of the user population). This requires more forethought, but it&#8217;s like writing tests&#8201;&#8212;&#8201;an investment.</dd>
</dl>

<h3>Track, trend, monitor</h3>

<p>Measurement is key to process improvement. From page load times, to conversions, to TCP sockets, every measurement gives you insight into something. And, remember, if you don&#8217;t have good visualization tools for your information, it&#8217;s only data.</p>

<h3>Excellent source code management</h3>

<p>Know thy tools, craftsman. At least one person on your team should know your <abbr title="source code management">SCM</abbr> tool inside and out.</p>

<h3>High levels of trust</h3>

<p>If you have separate development and operations teams, or even if you have an awesome devops team, you won&#8217;t get far without trust. It doesn&#8217;t matter when things are going well; it&#8217;s when everything turns to crap and you&#8217;re firefighting when the finger pointing starts. So, start from the premise that people are trustworthy. Trust them to do their jobs. (And, if they can&#8217;t, coach them or sack them. It&#8217;s that simple.) It doesn&#8217;t matter what your job title is. You&#8217;re all on the same team. You all want the same thing.</p>

<h3>Realistic risk assessment and tolerance</h3>

<p>Know what your risks are, and have an appropriate level of tolerance. If you are trying to build something with <a href="http://en.wikipedia.org/wiki/High_availability">five nines</a> of uptime, you will want more assurance before deployment, and it may be that CD is not for you. Know what parts of your site are acceptable to break, and what parts need to be up, and act accordingly. Availability requirements are not the same across all components of a system. Managing this is key to resilient systems.</p>

<h3>Excellent code review</h3>

<p>Code review has its place; on many projects I work on, every line of code is reviewed. On things that are less mission critical, or have very experienced teams, this is less the case. Code review is useful as both developmental (&#8220;I know a better way to do that&#8221;) and copy editing (&#8220;You made a critical typo here&#8221;).</p>

<h2>Finally</h2>

<p>If there are only two things you remember after you read this article, I would like them to be these:</p>
<ol>
    <li>You should build the capability for continuous deployment, even if you never intend to do continuous deployment.</li>
    <li>As with everything else in life, the only true way to get good at deployment is to deploy a lot.</li>
</ol>

<p>I&#8217;d be interested to hear about your thoughts and practices for CD&#8201;&#8212;&#8201;get in touch!</p>]]></description>
              <link>http://webadvent.org/2012/continuous-deployment-practices-by-laura-thomson</link>
              <guid>http://webadvent.org/2012/continuous-deployment-practices-by-laura-thomson</guid>
              <pubDate>Thu, 13 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>Light It Up with Markup</title>
              <dc:creator>Patrick Haney</dc:creator>
              <description><![CDATA[<p>When I started designing for the Web years ago, before the dot-com bubble burst, the term <em>interaction design</em> quite often referred to the use of Flash when it came to the Web. If you wanted to make your web site interactive in any way, that&#8217;s what you used.</p>

<p>While we&#8217;ve mostly done away with Flash, the trade-off is that static web sites are still the majority. Pages on the Web are full of text, images, and links. Sometimes a video, too, although it&#8217;s almost always stuck in a rectangular box, slapped in the middle of a page, waiting for a click of the play button to come alive.</p>

<h2>Shake the humbugs</h2>

<p>Things don&#8217;t have to be this way. The Web is naturally interactive, with users clicking around from page to page and site to site, discovering all sorts of things along the way. The Web is flexible; it flows from one device to another, regardless of screen sizes or browser functionality. Pages and elements have states, positions, and layout that can be manipulated through code and through input from users.</p>

<p>With all of its potential, why does the Web feel so stiff? We should be taking advantage of its interactive nature and flexibility. Design details shouldn&#8217;t end in a Photoshop mockup; they should continue on to the code. Interaction design for the Web extends beyond hover states and animated GIFs.</p>

<p>CSS is more powerful than ever. Designers and developers alike should take advantage of these advancements in code and browser support. Good design and good code only take the Web so far. It&#8217;s the layer between, the one that makes your design come alive, that can take the us to the next level.</p>

<h2>Add some tinsel to the (DOM) tree</h2>

<p>One of the least attractive things you can offer on your web site is a form. If I can paraphrase <a href="http://lukew.com/">Luke Wroblewski</a> for a moment, &#8220;No one wants to use your form; they just want what&#8217;s on the other side of it.&#8221; That said, forms are a necessary evil in some cases, so why not make them more interactive and less painful?</p>

<p>Have a look at <a href="http://45royale.com/project_planner">45royale&#8217;s project planner</a>. Not only does it clearly communicate the number of steps involved and provide helpful tooltips for each input, but those same tooltips are highlighted along with the text input as you move through the form. Placeholder text appears in each field to improve the quality of the input, and each step appears without a new page load, thanks to JavaScript.</p>

<p>Not all enhancements need to be so functional, though. <a href="http://canvas.is/#clients">Canvas&#8217;s client list</a>, for example, features your typical grid of company logos that the agency has worked with. But, move the slider from &#8220;Day&#8221; to &#8220;Night&#8221;, and watch as the heading, icons, and logos themselves light up in a bright neon as the background fades to black.</p>

<p>And, it&#8217;s not just about buttons, inputs, and links. Other elements of the page can be given just a little touch of interactivity. Scroll down <a href="http://heymosaic.com/">Mosaic&#8217;s single-page site</a> and watch as the calendar rocks into place. Transparent clouds move past the blimp on <a href="https://gethelium.com/">Helium&#8217;s site</a>. A looping video element fills the background of <a href="https://www.sevenly.org/team">Sevenly&#8217;s team page</a>.</p>

<h2>Keep Delivering Gifts</h2>

<p>Remember, the Web isn&#8217;t static; your design shouldn&#8217;t be, either. And, as browser support for CSS improves, so too does your ability to enhance the user experience of the Web. Use design and markup to deliver your best content to users, then delight them with the joy of interaction.</p>
]]></description>
              <link>http://webadvent.org/2012/light-it-up-with-markup-by-patrick-haney</link>
              <guid>http://webadvent.org/2012/light-it-up-with-markup-by-patrick-haney</guid>
              <pubDate>Wed, 12 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>Landing on Your Feet</title>
              <dc:creator>Emily Davis</dc:creator>
              <description><![CDATA[<p>I recently served as an instructor for an online course teaching the fundamentals of the Web. Before class started, we polled the students in order to learn, among other things, what kinds of skills they hoped to learn by the end of class. More than one student responded with &#8220;confidence.&#8221; I found this to be incredibly charming, but it gave me pause: teaching tech skills I could do, but confidence? It&#8217;s not easy to convince someone to have faith in their abilities when they are just beginning.</p>

<p><img src="http://webadvent.org/i/emily-davis-cat-vs-dog.jpg" alt="A tan cat giving a small orange dog a mean left hook." /><br /><cite>The definition of confidence.</cite></p>

<p>But as I thought about it more, I realized how important confidence is for new and veteran developers, alike. The following are the values and practices that I use to keep up my confidence. I hope that they can be encouraging to anyone just starting out, or considering starting a journey into the Web, as well as good reminders for those up to their elbows in code.</p>

<h2>You will never know everything about everything</h2>

<p>The world of the Web is huge, and it&#8217;s changing all the time. If you start out wanting to learn it all right away, you will feel overwhelmed pretty quickly.</p>

<p>I wrote my first &#8220;Hello, world!&#8221; in early 2009. When I was first learning the fundamentals and came across something new, I immediately wanted to know everything there was to know about it, and would get frustrated that I didn&#8217;t. Allowing myself access to this kind of impatience and frustration hindered my ability to think clearly and logically, and made it hard to let things sink in.</p>

<p>Even though it&#8217;s been almost four years since the beginning, I still consider myself relatively new to development. I&#8217;ve learned a lot of things along the way, and it&#8217;s fun to look back even just a year or two and realize what I didn&#8217;t know. Yet, I <em>still</em> experience many of the frustrations that come along with being a new developer.</p>

<p>One of the things I&#8217;ve learned is that there is a huge difference between learning how to write code and learning how to implement code. When it comes to implementing code, there is so much to learn, from security to debugging to caching and optimization, and they all involve understanding how to architect your code and applications. They go way past the fundamentals, and even now I feel like I&#8217;m only just beginning to really feel confident in these areas.</p>

<p>Secondly, I&#8217;m still getting the hang of how to pace myself as I learn. It&#8217;s easy to fall into my old way of thinking and to expect myself to know everything right away. The best approach is not to take on too many challenging things at once, but also not to shy away from things that are just out of reach. It takes a lot of dedication, time and practice to become fluent in all of the different areas of the Web. Don&#8217;t expect to gain all this knowledge in the first few years.</p>

<h2>Stay out of your comfort zone, and learn to love the pain</h2>

<p>Don&#8217;t overwhelm yourself, but it&#8217;s critical to also stay out of your comfort zone. It&#8217;s really easy to keep doing what you know, because it makes you feel great about your ability. While I agree that this is a good confidence-building approach, it prevents you from learning new things. &#8220;Stay out of your comfort zone&#8221; implies being in a state of discomfort, and sometimes it&#8217;s true! This pain is a path toward gaining new knowledge and confidence.</p>

<h2>Practice, practice, practice</h2>

<p>The best way to get better at writing code is to write it&#8201;&#8212;&#8201;lots of it! Find examples online, ask your colleagues if they need help with their projects, even try to recreate your favorite web sites. Take a look at some of your old code, because you&#8217;ll most likely see errors and will be able to refactor it based on new knowledge. Practice is progress, and every bit of progress counts.</p>

<h2>Some days are good, and some days are bad</h2>

<p>Every developer has a story about an embarrassingly awful and impactful error they&#8217;ve made.</p>

<p>Mine was a few years ago, when I was rushing to implement a new feature, and I forgot a really important bit of code to check whether or not a save was successful, which essentially broke validation. <em>Oopsies.</em></p>

<p><img src="http://webadvent.org/i/emily-davis-kitten-facepalm.jpg" alt="An orange kitten with his paw over his forehead." /><br /><cite>Me, after I realized what I had done.</cite></p>

<p>Luckily, my teammates and I noticed right away, and it only created 80 botched records. But it could have been much, much worse. The it-was-me pill was a hard one to swallow&#8201;&#8212;&#8201;I had to admit to 80 users, never mind my managers, that I had made a mistake. The only thing I could do was own up to it, fix it, and move on. As a developer at any skill level, you are going to make mistakes, and sometimes you might make really bad ones. This is OK.</p>

<p>It&#8217;s easy to remember the bad days and easy to forget the good ones. When you feel a sense of accomplishment, take a moment to pat yourself on the back. You&#8217;ve earned it. These feelings are the ones that will keep you going when you make those mistakes.</p>

<h2>Know when to ask for help</h2>

<p>My mentor used to tell me to &#8220;stop staring at the code waiting for Jesus.&#8221; If I ran across a problem I couldn&#8217;t figure out, I would stare at the code, thinking that if I were a developer worth my salt, I&#8217;d be able to discover the solution. It took me a long time to accept that sometimes I needed help, and that admitting that was not admitting defeat, but instead was the smartest, most efficient way to solve the problem.</p>

<p>When it finally was time to ask for help, I always felt a bit embarrassed to show people my code. What if I&#8217;d made a silly mistake? What if I&#8217;m doing it all wrong? I had a hard time accepting the fact that I was new, and other people were not. This self-consciousness inhibits progress. Time spent worrying about someone judging you or your code leads to missed opportunities to learn.</p>

<h2>Teach other people</h2>

<p>You don&#8217;t need to be an expert on the Web to teach someone else about it. Teaching someone what you know, no matter how little it is, will reinforce those skills in your own mind. Your student, mentee, whoever it may be, will most likely ask you lots of questions, and you&#8217;ll learn new things in the process of answering them.</p>

<p><img src="http://webadvent.org/i/emily-davis-science-cat.jpg" alt="A white cat with glasses and a bowtie, standing at a desk with lab equipment." /><br /><cite>Science cat wants to teach you things.</cite></p>

<p><a href="/2012/the-gift-of-sharing-what-you-know-by-heather-payne">Heather Payne</a> of <a href="http://ladieslearningcode.com/">Ladies Learning Code</a> says that sharing your knowledge, &#8220;means a lot to the people you help.&#8221; I can say this is true in my own experience as a new developer and as an instructor. The inspiration that comes from teaching goes both ways. Students feel confident and excited, and teachers feel great about helping others to feel that excitement. This pay-it-forward approach is also one of the main reasons why the tech industry is so healthy and strong. If you learned through mentors, user groups, and friends who spent the time to teach you, you should give back!</p>

<h2>At the end of the day&#8230;</h2>

<p>Remember that learning how to be a web developer, above all else, should be fun. Don&#8217;t do it for the money, don&#8217;t do it so you can impress people with your mad programming skills, and don&#8217;t do it because you can&#8217;t think of anything else to do. Do it because you love it and it makes you happy. I love being a web developer because I know that the possibilities are endless. I can make any web site, application, or game I want, and there are countless ways to create them. Who wouldn&#8217;t love that?</p>

]]></description>
              <link>http://webadvent.org/2012/landing-on-your-feet-by-emily-davis</link>
              <guid>http://webadvent.org/2012/landing-on-your-feet-by-emily-davis</guid>
              <pubDate>Tue, 11 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>More Code, More Problems</title>
              <dc:creator>Ed Finkler</dc:creator>
              <description><![CDATA[<p>About a year ago, I wrote out some principles for web programming in PHP. I called it the <a href="http://funkatron.com/posts/the-microphp-manifesto.html">MicroPHP Manifesto</a>. The thing is, what I talked about wasn&#8217;t really specific to PHP. So, I&#8217;ve decided to explore the concepts again in the context of the other languages I work with.</p>

<p>What follows are some principles I try to keep in mind.</p>

<h2>Learn languages, not frameworks</h2>

<p>I like PHP, Python, and JavaScript, and I like making things in PHP, Python, and JavaScript. I&#8217;m not a Symfony developer, or a Django developer, or a jQuery developer.</p>

<p>I think this is an important distinction. It&#8217;s entirely possible to be a jQuery developer, but not a JavaScript developer. It&#8217;s possible to be a Django developer, but not a Python developer. Those are all certainly valuable and useful tools, but if I only know how to use one framework, my options for using <em>the right tool for the job</em> get pretty limited, and in my experience, large, full-stack frameworks are often not the <em>right tool</em>, particularly if flexibilty and performance are major concerns.</p>

<p>My experience has been that I become a better, more versatile developer when I focus on learning a language first. Diving head-first into a full-stack, complex framework when I&#8217;m starting out has allowed me to build finished products more quickly, but it also becomes a detriment when I need solutions outside of the framework&#8217;s scope. I often end up with a &#8220;plug and pray&#8221; approach to development, where I find a library or plugin that sounds like it will meet my needs, cross my fingers, and shove it in. That might get my app launched faster, but it makes stuff a lot harder down the road.</p>

<p>Additionally, learning a full-stack framework can be as complex as learning a new programming language. They often have complex architectures and nomenclatures&#8201;&#8212;&#8201;parts that don&#8217;t carry over to other frameworks and tools. I&#8217;d rather spend my time learning more about the language itself, knowing the skills that I learn will apply to anything I build in the language, no matter which libraries I use.</p>

<h2>Build small things</h2>

<p>Small units of code are good. The smaller it is, the easier it is to understand. It&#8217;s harder to screw it up&#8201;&#8212;&#8201;and I screw stuff up a lot, so limiting that is <em>really</em> important.</p>

<p>So, I strive to build small modules of code with a single purpose, or at most a few closely-related purposes. They should be self-contained pieces that solve individual problems. These pieces then work together to solve larger, more complex problems.</p>

<p>With simpler, modular code, fixing bugs is easier, because I can look at an individual piece and see clearly what it&#8217;s doing. And, if the modules are self-contained, testing my code is <em>much</em> easier.</p>

<h2>Less code is better than more</h2>

<p>To paraphrase Biggie Smalls, &#8220;more code, more problems.&#8221;</p>

<p>I want to <em>manage</em> less code. Larger codebases get harder to manage. Searching across the codebase takes longer. Navigating through complex file structures takes longer. Tracing execution through dozens of files is hard. Keeping it all straight in my brain gets challenging.</p>

<p>Bigger libraries and longer code seem to overflow my brain buffer. I have trouble keeping track of code flow when the source gets too long, or when execution is jumping between several source files, and visual noise really affects me, too. This is why I love syntax coloring so much, and consistent whitespace really helps. I use the code folding feature in my editor a lot, just to hide things, so I can focus better on the task at hand.</p>

<p>I also want to <em>support</em> less code. I&#8217;m responsible for <em>all</em> of the code that my app uses, not just the stuff I wrote&#8201;&#8212;&#8201;every single line of it. This means that bugs and security holes are <em>my</em> responsibility. How often do we see a WordPress or Drupal plugin get abandoned after a year or so? Am I <em>sure</em> I want to use a piece of code I don&#8217;t really understand, when a year down the road I may have to fix an exploit in it?</p>

<p>This is not to say that I would never use code that I didn&#8217;t write&#8201;&#8212;&#8201;I&#8217;d be hard-pressed to get much done that way, and frankly there are better programmers out there than me&#8201;&#8212;&#8201;but every line of code in my app matters, so I need to justify each one.</p>

<h2>Create and use simple, readable code</h2>

<p>I want code that is <em>easy to understand</em>. Understanding things quickly means getting stuff done faster. My time to productivity is shortened. My time to fix bugs is shortened.</p>

<p>I also want code that is easy to <em>verify</em>. My code should be testable, whether or not I get around to actually writing those tests, and I&#8217;ve consistently found that simpler, more modular code is more testable.</p>

<p>Readability should be a feature. Code should be simple and terse, but clear. Value clarity over cleverness. When I&#8217;m writing code, I try to consider how quickly another developer will be able to understand it at first glance. Alternately, will <em>I</em> be able to understand it when I come back to it in two months? The less time I waste trying to figure out how things work, the more there will be for getting things done.</p>

<p>I&#8217;d be lying if I said I always follow these principles. Sometimes, I just get lazy. Sometimes, time constraints mean I write hacky, complex code as fast as possible to get something working, or I pull in a library without reviewing it carefully, and hope it works. In the short term, writing simple, clear code is harder&#8201;&#8212;&#8201;it requires more discipline and frequent reassessment of technique. Particularly with time-sensitive projects, it&#8217;s hard to ever feel like I ever am entirely happy with the results.</p>

<p>But, when I make the time and put the effort in, it always pays off down the road&#8201;&#8212;&#8201;not just for myself, but for the other members of my team and people who use the code I&#8217;ve written, and that&#8217;s a really good feeling.</p>
]]></description>
              <link>http://webadvent.org/2012/more-code-more-problems-by-ed-finkler</link>
              <guid>http://webadvent.org/2012/more-code-more-problems-by-ed-finkler</guid>
              <pubDate>Mon, 10 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>Dealing with Email Image Blocking</title>
              <dc:creator>Chesley Andrews</dc:creator>
              <description><![CDATA[<p>You probably get a lot of email and even more newsletters. My HTML email newsletters are all mixed in with my plain-text emails, and when I&#8217;m going through my inbox, it&#8217;s a quick and efficient process. I want to be able to get the point of each email quickly. When I open an HTML email and see rows of blank outlined boxes, I immediately think, &#8220;this isn&#8217;t relevant or necessary to me; moving on.&#8221; I very rarely decide to turn the images on. <a href="http://www.mobilizemail.com/2006/11/24/30-of-your-recipients-dont-even-know-your-images-are-missing/">One alarming statistic</a> found that 30% of recipients are unaware that images are even disabled in the first place!</p>

<p>Email clients disable embedded images to protect you from spam. Spammers will use an image as a beacon; when downloaded, it signals that you have an active and valid address. Spam protection is a good thing, but automatically-disabled images make designing a compelling marketing email tricky. Fortunately, there are a few things you can do.</p>

<h2>Style the image&#8217;s <code>alt</code> text</h2>

<p>Many email designers are hip to adding an <code>alt</code> attribute to all important images, ensuring that&#8201;&#8212;&#8201;at the very least&#8201;&#8212;&#8201;text will show up when the image does not. Instead of just a straight description of the image, a savvy email designer uses the <code>alt</code> attribute to place an offer or call-to-action. An even savvier email designer takes it one step further and styles the <code>alt</code> text.</p>

<p>One very simple way we do this at <a href="http://etsy.com/">Etsy</a> is with our logo. Instead of showing a box with <code>alt</code> text that just says &#8220;Etsy&#8221;, we style the <code>alt</code> text to look as much like our wordmark as possible. The result is that when viewing the email with images off, you see something very close to what our logo looks like.</p>

<p><img src="http://webadvent.org/i/chesley-andrews-etsy-alt.jpg" alt="Etsy styled alt text" /></p>

<p>The code looks like this:</p>

<pre><code>&lt;img src="etsy_logo.png" width="47" height="24" alt="Etsy"
  style="color:#d15600; font-family:georgia,times,serif;
    font-weight:normal;text-decoration:none; border:0" /&gt;</code></pre>

<p>Not every logo lends itself so easily to this technique, but there are plenty of other ways to use it. For example, if your email makes use of image-based buttons, you can style the <code>alt</code> text to come up with a pretty convincingly clickable fallback.</p>

<p>Of course, like any feature of HTML email, <code>alt</code> text doesn&#8217;t display consistently across all clients. Campaign Monitor has a <a href="http://www.campaignmonitor.com/blog/post/3280/displaying-and-optimizing-alt-text-in-popular-email-clients/">handy breakdown</a> that shows how <code>alt</code> text displays across different clients.</p>

<h2>Make your image into pixel art</h2>

<p>Take that would-be empty image block one step further and make a lo-fi fallback version of your image using tables and background colors. <a href="http://litmus.com/blog/pizzaexpress-inspires-with-images-off-email-optimization">Pizza Express uses this technique</a> in a variety of ways.</p>

<p><img src="http://webadvent.org/i/chesley-andrews-pixel-art.jpg" alt="Pizza Express as pixel art" /></p>

<p>Hand-coding a custom pixel art table for each email is a time-consuming task, but there are a few apps on the scene that are making this easier.</p>

<p>Style Campaign created a <a href="http://stylecampaign.com/blog/2009/12/bypass-image-blocking-by-converting-images-to-html/">free app that pixelates your image</a> while keeping email-friendly compression in mind. Here&#8217;s how it works:

<blockquote><p>&#8220;The application [...] can be run with multiple parameters to allow HTML output in a variety of formats,&#160;from standard HTML table layout to full CSS. The application utilizes a simple run length style compression system, using table cell <code>colspan</code> to create rows of contiguous color. This saves significantly on file size and client processing time. A background color can also be passed as a parameter, so that cells containing the specified color do not have to have their color defined in the table cell, further saving file size.&#8221;</p></blockquote>

<p>They readily admit that compression for large images continues to be an issue, and they recommend that the tool be used for smaller items like logos and icons.</p>

<p>Email on Acid offers a very consumer-friendly app called <a href="http://www.emailonacid.com/email-preview/mozify">Mozify</a> that does the same thing. Among other features, Mozify lets you control how pixelated your image will be be, letting you experiment with larger feature images while saving on file size. Watch the <a href="http://vimeo.com/48542363">Mozify intro video</a> to see it in action.</p>

<p><img src="http://webadvent.org/i/chesley-andrews-mozify.jpg" alt="Guess, mozified" /></p>

<p>Designing for the inbox is rife with challenges. There&#8217;s a dizzying variety of clients, devices, and browsers to contend with, along with more emails being sent than ever before. Inboxes are a special mix of a personal and practical space. Once you get them to open the email, it&#8217;s worth taking the time to greet them with more than a blank screen.</p>
]]></description>
              <link>http://webadvent.org/2012/dealing-with-email-image-blocking-by-chesley-andrews</link>
              <guid>http://webadvent.org/2012/dealing-with-email-image-blocking-by-chesley-andrews</guid>
              <pubDate>Sun, 09 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>Make a Difference</title>
              <dc:creator>Noah Stokes</dc:creator>
              <description><![CDATA[<p>I remember that particular day, driving home from my job at Apple Computer, talking to a friend on a cell phone the size of small brick. I asked him how to get files onto a server so they show up at a given domain. I was looking for a new career path and web development seemed really interesting, but admittedly I had no idea how any of it worked. He told me about something called <abbr title="File Transfer Protocol">FTP</abbr> and, while sitting quietly in the parking lot that the 237 had become, my tiny mind went <em>poof</em>. Black magic.</p>

<p>It&#8217;s hard for those of us in this field to consider our daily chores of pixels, markup, and databases to be anything more than a job. A great job, but a job nonetheless. We are multi-lingual experts skillfully constructing experiences that are responsibly responsive. We bring skeuomorphic interfaces to life with little more than photo editing software that we then plug into a machine that responds to our touches and gestures. I ask it a question, it tells me an answer. In some places throughout the world, it would probably seem like witchcraft. In fact, more often than not, we find ourselves bemoaning one feature or another that doesn&#8217;t live up to our astronomical standards. I think it was Louis C.K. who said &#8220;<em>It&#8217;s going to space! Can you give it a second to get back from space&#8253;</em>&#8221;</p>

<p>My friend Joshua Blankenship put it this way: <em>we are wizards</em>. I agree. We have the ability to do things that most folks find too complex to bother with. We create the worlds they engage in on their computers and their phones. To us it&#8217;s no big deal, but to the users, it&#8217;s straight-up magic.</p>

<p>Building for the Web is the future, of this I am convinced. Software and hardware do more with greater efficiency than ever before. What we do with smart phones today once took a semi-truck-sized pile of hardware. The future is here and we are the architects.</p>

<p>So with that said, I have to ask&#8201;&#8212;&#8201;why do we spend so much of our time, effort and money on building useless junk?</p>

<p>Don&#8217;t get me wrong, your disruptive-social-mashup-startup sounds awesome but is it solving any problems? Yes, yes, it may be solving the age old dilemma of how to take a 30 second video of me eating breakfast while staring at my shoes and share it with &#8220;friends&#8221; (friends I wouldn&#8217;t recognize if we crossed paths on the street), sans audio. But what real problems are you solving? Researchers of chronic diseases who could benefit from a worldwide sample of patients, educators unable to accommodate the various learning styles of children in their overloaded classrooms, or unemployed people in desperate need of training for a chance at an interview&#8201;&#8212;&#8201;what are we doing to help them solve their problems?</p>

<p>Some of us are <em>ideators</em>, some of us are <em>doers</em>, others are a bit of both and, while the solution may not come from you, the ability to execute a viable solution can. Write an algorithm to detect patterns in patients, customize an online course to teach lessons based on a student&#8217;s previous answers, or build a simple tool to allow others to share their knowledge with those willing to learn. We do this stuff every day&#8201;&#8212;&#8201;maybe not in the context of solving real problems, but we do it nevertheless.</p>

<p>You don&#8217;t have to work at a non-profit to solve these problems. You don&#8217;t even have to quit your job. Our tools of creation have improved so much that we&#8217;re able to build in hours what used to take days. Frameworks, auto-magically-scaling-distributed servers, one click this and that&#8230; it&#8217;s getting faster and easier to do what we do. A few hours in the evenings or on the weekends is all it may take to breathe life into a new idea.</p>

<p>When you dream up your next big idea, or you find yourself looking for a side project to take on, consider your magical powers and wield them for something good, something that makes a difference and solves real problems.</p>

]]></description>
              <link>http://webadvent.org/2012/make-a-difference-by-noah-stokes</link>
              <guid>http://webadvent.org/2012/make-a-difference-by-noah-stokes</guid>
              <pubDate>Sat, 08 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>The Anti-Spec Movement Is Going Too Far</title>
              <dc:creator>Tracy Osborn</dc:creator>
              <description><![CDATA[<p>As a designer, I have nothing against the <a href="http://antispec.com/">anti-spec movement</a>. Created in response to speculative work (i.e., work commissioned with the possibility of payment but no guarantee) and crowd-sourcing (e.g., design contests which reward only one winner), the anti-spec community has been protecting designers&#8217; right to be paid for the work that they do.</p>
<p>However, the movement has been going too far&#8201;&#8212;&#8201;expanding to cover every kind of design contest and groups where design and art are created for fun, not just profit. Anti-spec is detrimental to community and social good projects, and it hurts more designers and artists than it saves by going too far.</p>

<h2>Anti-spec is hurting pro bono design</h2>

<p>At <a href="https://brooklynbeta.org/2011">Brooklyn Beta 2011</a>, Todd Park of the US Department of Health and Human Services <a href="http://www.slideshare.net/amanbhandari/todd-park-brooklyn-beta-make-something-you-love-102011">spoke passionately about the need for designers to work for the public good</a>, to spend their free time building and experimenting on current public issues. He called for designers to take the massive amount of health data released by the government and use it to build public solutions, and he specifically mentioned that, yes, the government could pay one individual or studio a massive amount of money to find one solution, but that the most amount of innovation and creativity comes from the community.</p>

<p>Recently, <a href="http://thedesignerfund.com/">The Designer Fund</a> and the White House presented the <a href="http://blue-button.github.com/challenge/">Health Design Challenge</a> dedicated to redesigning the electronic medical record. <a href="http://techcrunch.com/2012/11/13/redesign-electronic-medical-record/">On the TechCrunch coverage</a>, The Designer Fund co-director says, &#8220;There are so many meaningful problems in the world. Healthcare, clean energy, environmental issues, city design. We feel like we&#8217;d be able to make a much bigger dent in these problems if designers went at them.&#8221; Of course, there were anti-spec responses such as this:</p>

<p><img src="http://webadvent.org/i/tracy-osborn-anti-spec-fb.png" alt="The US Government crowdsourcing designs? I can't wait to work for free! &#8212;Razmig Getzoyan on Facebook" /></p>

<p>The Designer Fund and the White House could pay a consulting firm to create a solution for the electronic medical record, but like Todd Park mentioned, the greatest amount of innovation and creatively comes from a massive amount of designers working together&#8201;&#8212;&#8201;more innovative, cost-effective, and interesting solutions will always come from a community project such as this rather than one paid consulting firm.</p>

<h2>Anti-spec is hurting open source, design collaboration, and education</h2>

<p>Being a designer jumping into development, I would have been completely lost if it wasn&#8217;t for sites like <a href="http://stackoverflow.com/">Stack Overflow</a>, where people can post problems they&#8217;re having with development and get answers and help for free. The free advice and help from Stack Overflow made it easy to jump into development. So many people are looking to jump into design, but huge communities for design help like Stack Overflow are lacking&#8201;&#8212;&#8201;<a href="http://graphicdesign.stackexchange.com/">Stack Overflow for design</a> isn&#8217;t big enough and <a href="http://dribbble.com">Dribbble</a> exists more for sharing small details. Large communities don&#8217;t exist due to the stigma against asking for design help for free.</p>

<p>For developers, open source development has lead to innovation on the Internet and online products. I was able to build <a href="http://weddinglovely.com/">my startup</a> using a programming language called <a href="http://python.org/">Python</a> and a framework called <a href="https://djangoproject.com/">Django</a>, both of which are available online for free, even though they represent thousands of hours of work. The developers worked for free, in their spare time, to build something to help others. It&#8217;s worth noting that it would be odd to have anything but free programming frameworks and plugins&#8201;&#8212;&#8201;developers in the open source community embrace working for free in order to build free resources for the benefit of others.</p>

<p>What if designers were more open with their free time? What if we embraced opening up to others, embracing community? A huge issue in the open source community is the lack of design help&#8201;&#8212;&#8201;poor UX and UI design on open source projects which hinders adoption and understanding by non-developers. Designers should work with developers to further promote and aid adoption of great open source projects, which, in turn, helps nearly everything we use on the Internet today.</p>

<h2>Anti-spec is hurting community</h2>

<p><a href="http://www.moleskine.com/us/">Moleskine</a>, the popular retailer of artist notebooks and sketch pads, decided to hold a design contest for their online blog, the <a href="http://www.moleskinerie.com/">Moleskinerie</a>. The Moleskinerie is dedicated to sharing art and stories around the Moleskine brand, so it probably seemed natural to use their current community to help design the logo for the Moleskinerie. <a href="http://mumbrella.com.au/moleskine-logo-contest-dubbed-molescheme-by-angry-designers-62342">The anti-spec work comments poured in</a>:</p>

<blockquote><p>&#8220;I am shocked and dismayed that Moleskine is running an unethical contest like this. You are expecting thousands of artists to work for free.&#8221;</p></blockquote>

<blockquote><p>&#8220;Like a lot of professional creatives, I am very disappointed by the fact that Moleskine actually helps devalue our profession and potentially tries to get rid of a lucrative part of its user demographic, instead of making a fist against crowd-sourcing or any initiative involving speculative work for that matter. I&#39;m quite sure that I&#39;m not the only one who won&#39;t buy Moleskine products anymore.&#8221;</p></blockquote>

<p>Moleskine had already built a community through design and was just further developing that community by having the headline piece of the community (the logo) built by the community. Moleskine wasn&#8217;t redesigning their brand or any piece of their company that is distinctly for-profit. We shouldn&#8217;t discourage designers using their talents for fun to help and build upon something they love.</p>

<h2>The anti-spec movement needs to embrace pro bono pursuits</h2>

<p>The anti-spec movement can be productive, since bad spec work still exists&#8201;&#8212;&#8201;there are still employers making potential employees work for free with the possibility of a job (bad), and there are still companies running spec contests for logos and branding (very bad&#8201;&#8212;&#8201;I&#8217;m looking at you, <a href="http://99designs.com/">99Designs</a> and <a href="http://crowdspring.com/">Crowdspring</a>).</p>

<p>However, we should never discourage designers and artists from using their art and design skills for fun and public good. These pursuits don&#8217;t deny designers jobs, nor do they lower our wages. As designers, we should contribute to open source projects, donate our skills to important public projects such as the Health Design Challenge, and embrace art for fun&#8201;&#8212;&#8201;not just profit.</p>
]]></description>
              <link>http://webadvent.org/2012/the-anti-spec-movement-is-going-too-far-by-tracy-osborn</link>
              <guid>http://webadvent.org/2012/the-anti-spec-movement-is-going-too-far-by-tracy-osborn</guid>
              <pubDate>Fri, 07 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>PhantomJS</title>
              <dc:creator>Paul Reinheimer</dc:creator>
              <description><![CDATA[<p>My, that&#8217;s a pretty web browser you&#8217;re using, concurrently making requests to various servers, interpreting and rendering the nearly indecipherable HTML and CSS. It&#8217;s a fantastic piece of technology, yet for developers it has a fatal flaw. You. Browsers need users, and when it comes to testing, this is a major drawback when working on today&#8217;s complex web apps.</p>

<p><a href="http://phantomjs.org/">PhantomJS</a> is a rather new kid on the block. It&#8217;s a headless <a href="http://webkit.org/">WebKit</a>-based browser. It&#8217;s statically built against <a href="http://en.wikipedia.org/wiki/Qt_%28framework%29">QT</a>, so it works across platforms (Windows, Linux, and Mac OS X downloads available), and it has minimal dependencies. The great part about it being headless is that you don&#8217;t need <a href="http://en.wikipedia.org/wiki/X_Window_System">X</a> installed to use it, so it&#8217;s suitable to install on your servers. In fact, I&#8217;ve already installed it on 80 of our servers powering <a href="http://wheresitfast.com/">Where&#8217;s It Fast</a>.</p>

<p>Once you&#8217;ve got everything installed, it&#8217;s time to give the examples a whirl. Load speed is easy and interesting: <code>./bin/phantomjs ./examples/loadspeed.js http://webadvent.org/</code> yields:</p>

<pre><code>SyntaxError: Parse error

Page title is Web Advent 2012
Loading time 610 msec</code></pre>

<p>It takes 610 msec for PhantomJS to load the page inside its headless browser. Note that this isn&#8217;t a basic request with cURL to simply grab the index document; it&#8217;s &#8220;rendering&#8221; the HTML, grabbing the style sheets, images, &#38;c. The &#8220;Parse Error&#8221; we&#8217;re seeing is the output of the JavaScript engine erroring out as it grabs a misconfigured resource. Whether you prefer the JavaScript or CoffeeScript source, the code involved is almost <a href="https://github.com/ariya/phantomjs/blob/master/examples/loadspeed.js">disappointingly trivial</a>. Record the current time, attempt to open the page, on success subtract then from now and print. If there&#8217;s an error, print the appropriate message. That so few lines of code were required to return such a useful monitoring metric really pushed me to look harder into PhantomJS.</p>

<p>For a more in-depth look at the resources it&#8217;s grabbing, the <a href="https://github.com/ariya/phantomjs/blob/master/examples/netsniff.js">netsniff.js</a> example is perfect. It similarly retrieves the requested page, but it also returns detailed information on each resource that it requests in <a href="/f/paul-reinheimer-netlogoutput.json">its log from requesting <code>webadvent.org</code></a>.

<p>Here, we get some basic app info, followed by the details on the page, including the <code>pageTimings</code> variable&#8201;&#8212;&#8201;it took only <code>393ms</code> for the browser to hit <code>onLoad</code> (the Wi-Fi must have improved). What follows is an entry for each resource requested, including both request and response, as well as various timing details. This far more granular view of the page allows us to not only ensure that it loads quickly, but also determine which resources took the longest. Using <code>startedDateTime</code> as well as the timing information, it&#8217;s possible to replicate the detailed page load waterfall you&#8217;d receive from <a href="http://getfirebug.com/">Firebug</a> or similar tools.</p>

<p>I find these figures tremendously interesting and exciting. An incredibly large pool of research has shown that the speed at which your page loads and becomes usable is tremendously important. Faster pages equals more sales. Being able to automate monitoring of these full page statistics provides an additional layer of assurance that pages are working the way their provider expects. These are often values that are easily hidden if it&#8217;s your static JavaScript server slowing things down, rather than your main dynamic server, or your database.</p>

<h2>But wait, there&#8217;s more!</h2>

<p>PhantomJS is also capable of rasterizing your page, and spitting out a PDF for your viewing pleasure. This site uses a second (and appropriate) CSS file for printing, so I&#8217;ll use my own site for comparison here. The <a href="/f/paul-reinheimer-wondernetwork.pdf">PDF that PhantomJS generates</a> (with <code>/bin/phantomjs ./examples/rasterize.js http://wondernetwork.com/ wondernetwork.pdf letter</code>) can be compared directly with <a href="http://wondernetwork.com/">wondernetwork.com</a>. Apart from needing to do some work to better support narrow browsers (my bad) I&#8217;m incredibly impressed with how well that worked. Generating thumbnails of pages was cutting-edge stuff very recently (and let&#8217;s be honest, generating PDFs programmatically is almost always a pain).</p>

<h2>Further reading</h2>

<p>Beyond these examples (and the clear, though unspoken, implication that you can edit the rather clear code to do more), there&#8217;s also been a few things built on top of PhantomJS to further utilize this headless web browser. In particular, I&#8217;d like to call your attention to the friendly <a href="http://casperjs.org/">CasperJS</a>, which eases scripting and testing with PhantomJS. Their site documents a simple way to iterate over some Google search results, possibly to ensure your continued ranking, but I&#8217;m more interested in the <a href="http://casperjs.org/testing.html">testing aspect</a>. I&#8217;ve explored using <a href="http://nodejs.org/">Node.js</a> for testing my JavaScript in the past, but was never really happy with how it required me to change how I was handling things (since I wasn&#8217;t deploying with Node.js). With CasperJS, I&#8217;m able to test my pages the way I&#8217;ve written them, without any modifications or other chicanery.</p>

<p>All in all, I think PhantomJS is a fantastic tool to add to your toolkit. Monitoring, imaging, and testing, all in one package.</p>
]]></description>
              <link>http://webadvent.org/2012/phantomjs-by-paul-reinheimer</link>
              <guid>http://webadvent.org/2012/phantomjs-by-paul-reinheimer</guid>
              <pubDate>Thu, 06 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>SSH Tips</title>
              <dc:creator>Lorna Mitchell</dc:creator>
              <description><![CDATA[<p><abbr title="Secure Shell">SSH</abbr> is a way to access remote servers via the command line. It is a really fabulous secure communications channel that you can use for all kinds of things! Today, I thought I&#8217;d share some of my favorite SSH tips, from starting out, to using multiple SSH keys easily, to using SSH as a tunnel for something else entirely.</p>

<p>To SSH to a remote server, simply take a terminal program (Windows users should grab <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html">PuTTY</a>) and type:</p>

<pre><code>ssh username@server</code></pre>

<p>You&#8217;ll be prompted for your password (or passphrase for your key; more on those in a tick), and then&#8201;&#8212;&#8201;presto!&#8201;&#8212;&#8201;you&#8217;re in. If you don&#8217;t supply the username, you&#8217;ll be prompted for that first, and the server can take either a domain name like <code>lornajane.net</code> or an IP address.</p>

<h2>SSH keys</h2>

<p>While it&#8217;s fine to use a username and password for SSH access, it&#8217;s quicker and more secure to access using an SSH key. SSH keys are made of two parts: a public key and a private key. You generate the keys with the command <code>ssh-keygen</code> (Windows users, download <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html">PuTTYGen</a>).</p>

<p><a href="http://www.flickr.com/photos/laureenp/6141822934/"><img src="http://farm7.staticflickr.com/6157/6141822934_1334aca9c9.jpg" width="500" height="500" alt="Keys 395" /></a></p>

<p>You will be prompted to answer some questions when creating the key, and, in general, the defaults are fine. One of the questions will ask you to create a <em>passphrase</em>. The passphrase is a password that must be used with the key when accessing a server. In general, it is recommended to have passphrases, but you might choose to omit them if, for example, this key will be used by an unsupervised automated user account.</p>

<p>There&#8217;s an <a href="https://help.github.com/articles/generating-ssh-keys">excellent GitHub resource on generating SSH keys</a> that gives you more information, and it also provides a clue to some of the other things we can do with SSH!</p>

<h2>Sharing SSH keys</h2>

<p>Once you have your keys, you will need to send the public half (the filename will end with <code>.pub</code>) to anyone who needs to give you access to their server or other app. It is safe to email public keys and to share them, but keep your private keys safe, protected, and backed up. These are the real keys to the kingdom!</p>

<p>GitHub uses SSH keys to grant access to your GitHub account. You paste the contents of your public key into their site (look under &#8220;SSH Keys&#8221; on your account page), and then you can access your repositories using the key.</p>

<h2>Many keys</h2>

<p>Some people only have one key, but I find it more helpful to have many keys&#8201;&#8212;&#8201;perhaps one for work use, and one for personal use, or one created for a specific project or system. This approach means that I can revoke an individual key if I need to, without needing to change all of my keys.</p>

<p>To SSH with a specific key is very simple. You can supply the information on which key to use with the <code>-i</code> switch to the <code>ssh</code> command. For example, I have a separate SSH key to use with GitHub:</p>

<pre><code>ssh -i ~/.ssh./github_rsa git@github.com</code></pre>

<p>Using multiple keys in this way is great for accessing servers, but many of the programs which rely on SSH, such as <code>scp</code> and <code>git</code> don&#8217;t have an option to specify which key to use. For this situation (and many others), you can use the SSH config file.</p>

<h2>SSH configuration file</h2>

<p>The config file for SSH is the source of many very useful little tricks! (On Unix systems, it lives in <code>~/.ssh/config</code>.) For example, you might set up an alias so that you can refer to a server by a shorter name:</p>

<pre><code>Host lyra
  User=lorna
  Hostname=lyra.lornajane.net</code></pre>

<p>Now, I can simply SSH to the alias, and it will pick up the hostname and username accordingly:</p>

<pre><code>$ ssh lyra
lorna@lyra.lornajane.net's password:</code></pre>

<p>Using the config file, you can also tell SSH which key to use when accessing a different server. Here&#8217;s the entry I use for accessing GitHub:</p>

<pre><code>Host GitHub
  Hostname=github.com
  IdentityFile=~/.ssh/github_rsa</code></pre>

<p>This does mean that I edit all the URLs I use to be <code>GitHub</code>, where normally there would be <code>github.com</code>. It reminds me that there&#8217;s some magic somewhere!</p>

<h2>SSH tunnels</h2>

<p>Earlier, I mentioned that it&#8217;s possible to use SSH connections as a transport for other protocols. I use this mostly to get around the issue that some clients&#8217; tools are locked down to my home static IP address. There&#8217;s a server in the house that does a bunch of handy things, but also accepts SSH connections, so I can <em>tunnel</em> through it to make my traffic look like it came from there.</p>

<p>To achieve this, I use the <code>-L</code> switch to bind a specific port on my local machine (such as <code>8080</code>) to a specfic port on the server that I actually want to access. This will only work if the connection is made through my static IP address, so the house becomes the target of the SSH command. It looks something like this:</p>

<pre><code>ssh -L 8080:client-tool.example.com:80 home-server.lornajane.net</code></pre>

<p>I am prompted for my SSH credentials for <code>home-server.lornajane.net</code>, and the connection is created. Anything I send to <code>8080</code> on my local machine will be forwarded over an SSH tunnel via the house to port <code>80</code> at <code>client-tool.example.com</code>. So, I open <code>http://localhost:8080/</code>, and by SSH magic, I have access to the client tool that&#8217;s only available from the whitelisted IP address!</p>

<p>This is an invaluable trick and one that I use when I&#8217;m on the road most of all. It can be used to send all kinds of traffic, not just HTTP. I&#8217;ve used it for <code>rsync</code>, <code>telnet</code>, other file transfers, and who knows what else. I&#8217;ve also used it to route my web traffic through a proxy as a way of working around restrictive firewalls.</p>

<h2>The power of SSH</h2>

<p>SSH is such a key skill in working with remote commands, but it&#8217;s one of those awkward things that isn&#8217;t usually taught; you don&#8217;t learn SSH when you perfect your technical craft, yet you need it to be able to share what you create. Hopefully this post has given you a useful snippet or two to make sharing a little bit easier.</p>
]]></description>
              <link>http://webadvent.org/2012/ssh-tips-by-lorna-mitchell</link>
              <guid>http://webadvent.org/2012/ssh-tips-by-lorna-mitchell</guid>
              <pubDate>Wed, 05 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>Better Forms for Mobile Users</title>
              <dc:creator>James Socol</dc:creator>
              <description><![CDATA[<p>Mobile is a special, fun place to be a web developer. On one hand, pretty much all of the browsers are new and support cool things. On the other, processors, graphics, and network are all slow, and you should care about battery life. Additionally, input on even the best phones is still unpleasant and error-prone.</p>

<p>But, because the browsers are new, we can make things a lot better.</p>

<h2>Validation</h2>

<p>Since you&#8217;re doing server-side input validation anyway (right?), client-side validation is just to make the user experience better. But, loading a bunch of JavaScript to do this is going to slow down the site.</p>

<p>Fortunately, you can bake a lot of the validation into the form itself and let the browser do it for you. </p>

<p>There are <a href="https://developer.mozilla.org/en-US/docs/HTML/Element/Input">a ton</a> of new input types in HTML5, and for common types, there is good support on mobile browsers.</p>

<p>First, let&#8217;s look at the <code>pattern</code> attribute. The value should be a regular expression that matches allowed values. This works on <code>text</code>, <code>search</code>, <code>tel</code>, <code>url</code>, and <code>email</code> fields. For example:</p>

<pre><code>&lt;input type="text" pattern="\d+ \w+"&gt;</code></pre>

<p>When a user enters text that doesn&#8217;t match the pattern, the browser will apply the <code>:invalid</code> pseudoclass to the element, which you can style with CSS however you&#8217;d like. Here, I set the background to pink.</p>

<p><img width="650" src="http://webadvent.org/i/james-socol-01-pattern-attribute-sm.png" alt="Invalid and valid fields" /></p>

<p>There&#8217;s also a <code>:valid</code> pseudoclass that you can use.</p>

<p>Browsers apply the pseudoclass immediately, so if you want to let the user finish entering the text before calling them out, you can use a selector like this: <code>input:invalid:not(:focus)</code>. (This worked for me on iOS but not on FirefoxOS.)</p>

<p>Or, use specificity to reset the change:</p>

<pre><code>input:invalid {
    /* Set something here. */
}

input:focus {
    /* Undo the something from above. */
}</code></pre>

<p>There&#8217;s one particularly special value for patterns, which is matching numbers only:</p>

<pre><code>\d*
[0-9]*</code></pre>

<p>iOS, in particular, will react to this pattern.</p>

<h2>Entering data</h2>

<p>Now you can skip the big JS download to validate your forms. Do it in HTML and CSS and let the browser handle it.</p>

<p>The other part of forms that is hard on mobile is entering data. Keyboards are small, and typing a lot is a pain. Here&#8217;s where the input types really become valuable.</p>

<p>Mobile browsers will change their keyboard in response to certain input types. Here&#8217;s how it looks with a regular <code>&lt;input type="text" /&gt;</code>:</p>

<p><img width="650" src="http://webadvent.org/i/james-socol-02-input-type-text-sm.png" alt="Normal text inputs" /></p>

<p>Here&#8217;s how it looks with <code>&lt;input type="email" /&gt;</code>:</p>

<p><img width="650" src="http://webadvent.org/i/james-socol-03-input-type-email-sm.png" alt="Email inputs" /></p>

<p>The difference is subtle, but both keyboards have made the <code>@</code> symbol easier to get to. Now here&#8217;s <code>&lt;input type="url" /&gt;</code>:</p>

<p><img width="650" src="http://webadvent.org/i/james-socol-04-input-type-url-sm.png" alt="URL inputs" /></p>

<p>Gone are the space bars, now we have <code>.</code>, <code>/</code>, and <code>.com</code> readily available.</p>

<p><code>&lt;input type="number" /&gt;</code> is an interesting case. We need to add the digits-only pattern (<code>pattern="\d*"</code> or <code>pattern="[0-9]*"</code>) for iOS to recognize it, but then we get:</p>

<p><img width="650" src="http://webadvent.org/i/james-socol-05-input-type-number-sm.png" alt="Number inputs" /></p>

<p>A nice, big, numeric keypad.</p>

<p>Some browsers support even more. Here are <code>&lt;input type="range" /&gt;</code> (obviously this one needs some additional visual feedback) and <code>&lt;input type="datetime-local" /&gt;</code>:</p>

<p><img width="650" src="http://webadvent.org/i/james-socol-06-datetime-range-sm.png" alt="Datetime and range inputs" /></p>

<h2>Use it today</h2>

<p>This all works today, right now, in the browser on my real phone.</p>

<p>If a browser doesn&#8217;t know what to do with a <code>type</code> value, it defaults to <code>type="text"</code>, so it still works fine&#8201;&#8212;&#8201;so you may want to load a script in that case to do client-side validation.</p>

<p>If you&#8217;re already using all the tools available, get your friends and coworkers to do it, too. Peer pressure is a good thing. I have seen some of this in the wild, but it&#8217;s not everywhere yet.</p>

<p><img width="650" src="http://webadvent.org/i/james-socol-07-live-sites-sm.png" alt="HTML5 forms in the wild" /></p></article>

]]></description>
              <link>http://webadvent.org/2012/better-forms-for-mobile-users-by-james-socol</link>
              <guid>http://webadvent.org/2012/better-forms-for-mobile-users-by-james-socol</guid>
              <pubDate>Tue, 04 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>The Gift of Sharing What You Know</title>
              <dc:creator>Heather Payne</dc:creator>
              <description><![CDATA[<p>The first time I saw a line of code was probably mid-2009. I had just graduated from university with a business degree, and it occurred to me that I should have a personal web site. At the time, I don&#8217;t think I had a single friend who knew how to build web sites, but that didn&#8217;t matter, because I moved to China in 2009, and a friend with HTML and CSS skills probably wouldn&#8217;t have helped much, anyway. Like a lot of people do when they&#8217;re first learning about how the Web works, I found my way around using Google and brute force. After a few months, and countless hours of research and hacking (in the truest sense of the word), I launched my first web site. Knowing that I&#8217;d done it all myself with only Google as a tool felt amazing.</p>

<p>The most surprising thing was how much I enjoyed myself. I loved figuring out every piece of that first project. It was frustrating at times, of course. But, most days, I could spend hours and hours researching things and making tweaks to the site. Soon, I started thinking about my next one, and about what I should learn next.</p>

<p>Fast forward a few years. Now, I get to watch beginners experience the joy of web making or programming all the time. My personal experience with learning how to code, plus a healthy dose of inspiration from <a href="http://www.pyladies.com/">PyLadies</a> in Los Angeles, lead to the founding of <a href="http://ladieslearningcode.com/">Ladies Learning Code</a>, a not-for-profit organization that runs workshops for women (and men) who want to learn beginner-friendly computer programming and other technical skills in a social and collaborative way. We now have chapters in Vancouver and Ottawa, a permanent 1,100+ square foot workshop space in downtown Toronto, and a thriving girls&#8217; program, called <a href="http://girlslearningcode.com/">Girls Learning Code</a>. Over 2,500 women, men, and girls have participated in a Ladies Learning Code or Girls Learning Code workshop since we started in August 2011. In Toronto alone, over 400 individual developers and designers have volunteered their time to help beginners at Ladies Learning Code workshops. That number might be the most staggering of all. We&#8217;re constantly amazed by the support we&#8217;ve received from the tech communities in Toronto, Vancouver, and Ottawa, as well as in other cities where we don&#8217;t have chapters yet. The fact that so many amazing developers and designers are willing to volunteer their time to help beginners get started with developing technical skills still blows me away.</p>

<p>What I&#8217;ve learned through Ladies Learning Code is that there is a huge group of people in our society who are ready to become creators&#8201;&#8212;&#8201;not just consumers&#8201;&#8212;&#8201;of technology and the Web. They want to build web sites, they want to prototype app ideas, they want to design and print things in 3D, they want to understand how computers and the Web work, and they want to be able to better use technology to improve their personal and professional lives. Not all of these people are comfortable venturing into the space on their own, though. It&#8217;s intimidating, and when you start, you don&#8217;t know what you don&#8217;t know. If we can get this group of people to the point where they have the knowledge and confidence to begin exploring the world of making&#8201;&#8212;&#8201;well, it would be a big deal. Because they want that. They want to know what all of you know.</p>

<p>So, enjoy the holidays and take some well-deserved time off. But, when you get back to work in January, I want to encourage all of you&#8201;&#8212;&#8201;every single person who has some sort of technical knowledge&#8201;&#8212;&#8201;to share it with someone else. It means a lot to the people you help (believe me!), and if you&#8217;re anything like the group of developers and designers I work with in Toronto, you&#8217;ll have a lot of fun, too.</p>

<p>Here are some ideas for those of you who are interested in sharing what you know:</p>

<ul>
	<li>Do a quick search for a group like Ladies Learning Code or Girls Learning Code in your area. If you can&#8217;t find one, email me at <code>heather [at] ladieslearningcode.com</code>. I might be able to point you in the right direction. Ladies Learning Code will also be expanding to new cities in 2013, so if you think your community would be a good fit, let me know!</li>
	<li>Check out <a href="http://coderdojo.com/">CoderDojo</a> and <a href="http://zen.coderdojo.com/dojo">Dojo Directory</a> to see if they have a group in your area. If they don&#8217;t, why not start one?</li>
	<li>Reach out to your local elementary or high school and see if they have a computer-related after-school program that you can help out with. If they don&#8217;t have one, maybe you can partner with a teacher to make it reality.</li>
	<li>Boy Scout and Girl Guide Leaders are always looking for fun activities and experiences for their groups to try. Maybe you could meet at the local library and take them through an introductory HTML and CSS lesson. Need slides? Try Jon Buckley and Kate Hudson&#8217;s <a href="https://github.com/jbuck/SCP-HTML-CSS">slides from an event we ran together in September</a>.</li>
	<li>If you&#8217;d like to start small, try hosting a &#8220;Kitchen Table&#8221; event (a term coined by Mozilla earlier this year). They&#8217;ve published <a href="https://webmaker.org/en-US/events/guides/kitchen-table/">a great how-to</a>.</li>
	<li>Speaking of Mozilla, have you tested out <a href="https://thimble.webmaker.org/en-US/">Thimble</a> or <a href="https://popcorn.webmaker.org/">Popcorn</a> yet? These are great tools for teaching kids about the Web.</li>
</ul>]]></description>
              <link>http://webadvent.org/2012/the-gift-of-sharing-what-you-know-by-heather-payne</link>
              <guid>http://webadvent.org/2012/the-gift-of-sharing-what-you-know-by-heather-payne</guid>
              <pubDate>Mon, 03 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>Going from One to a Million Users</title>
              <dc:creator>Joël Perras</dc:creator>
              <description><![CDATA[<p>Web development is a profession that has one of the lowest barriers to entry that I can think of. It requires a computer, an Internet connection, and time. While some may consider these prerequisites too high for many people on the planet less fortunate than us (and indeed, they would be right), programs such as <abbr title="One Laptop Per Child"><a href="http://one.laptop.org/">OLPC</a></abbr> are attempting to bridge this gap.</p>

<p>In addition to a low barrier to entry, a somewhat unfortunate side-effect of the current ecosystem is that many people (especially those new to web development) are at a loss when it comes to scaling their app to accommodate an influx of traffic and users. Often, these problems are relegated to people with fancy titles such as Systems Architect or Senior Architect, and with good reason; this stuff is difficult. Very difficult. It takes quite a bit of blood, sweat, and sleepless nights to understand just how hard of a problem this can be.</p>

<p>Nonetheless, a superficial understanding of the challenges in scaling a web app can be useful to developers who wish to progress further in their career and to better understand the trade-offs that are made during the lifetime of an app.</p>

<p>Let&#8217;s look at a broad and general overview of how a typical app might grow, what problems might arise, and some general-purpose solutions to these problems.</p>

<h2>Money does solve problems</h2>

<p>You might think that there&#8217;s something inherently cool or fun about maintaining all of the disparate servers and services that your app requires&#8201;&#8212;&#8201;and you might actually enjoy it, at least for a little while. After the initial honeymoon phase wears off, however, the hard facts start to set in. Every minute that you spend fiddling and maintaining your architecture is a minute that could be spent improving some facet of your app that could benefit your users in a much more direct way.</p>

<p>As is often the case, the simplest (and sometimes most cost-effective) solution is to simply throw money at the problem. With the recent affluence of general platforms as a service (PaaS) such as <a href="http://heroku.com/">Heroku</a>, <a href="http://engineyard.com/">Engine Yard</a>, and even language-specific ones like <a href="https://gondor.io/">Gondor.io</a>, the need for a full-time operations person on staff for a small- to mid-sized web app has decreased dramatically.</p>

<p>Take it from someone that has been paged at two o&#8217;clock in the morning in a foreign country when servers go down due to network issues, and your Internet connection amounts to a hotel using an AOL CD they found in the trash; if you can pay someone else to have that problem, do it.</p>

<p>Every problem you pay someone else to have is time that you can use to focus on what makes your app special.</p>

<h2>Starting Small</h2>

<p>If you&#8217;re like 99% of the web sites in the wild, you most likely started with a single server for running your app. Or, you might even have started on some form of shared hosting. There&#8217;s nothing wrong with that; we&#8217;ve all been there.</p>

<p>There comes a time when that single host isn&#8217;t able to keep up with the demands of your app&#8201;&#8212;&#8201;your database grows too big, you become memory or IO bound (depending on your app and your service stack), or you&#8217;re not able to attain whatever response time or throughput goals that you&#8217;ve set for yourself. This might be stressful, but remember, problems of scale are generally good problems to have. Most apps struggle to hold on to a few hundred users, let alone have the privilege of needing architectural changes to scale upwards.</p>

<p>Your go-to solution at this point should be one that minimizes the changes in your procedures, development time, and complexity of the system and app architecture. For most situations, this means getting a more powerful machine. If you&#8217;re on some sort of virtualized hardware like <a href="http://linode.com/">Linode</a> or <a href="http://aws.amazon.com/">Amazon Web Services</a>, then this is simply a matter of a few clicks in their respsective web consoles, and a few minutes of downtime. While the latter might not be desirable, generally, it is tolerable for your users if handled correctly.</p>

<p>Considering the various memory, processor, and disk configurations available from virtualized or bare-metal providers, this very simplistic approach of making your servers more powerful (also known as <em>vertically scaling</em>) can get you quite far.</p>

<h2>Necessary complexity</h2>

<p>If your user base continues to grow, vertical scaling will only get you so far. The next step is to separate out your system architecture by broad components and services.</p>

<p>The obvious choice for most is to separate the web server from the database. In doing so, an additional layer of complexity and an inherent network overhead is introduced. However, you suddenly gain the ability to independently scale both major components with respect to their own performance characteristics and requirements for your app as a whole.</p>

<p>Once the database and web server have been separated, the next phase is to add some high-availability to the mix. It&#8217;s great that you can now serve more users, but if your web server node goes down for whatever reason, no one cares about your mean response time or throughput. What matters is that your app remains up and functioning for as many minutes during the year as is possible.</p>

<p>Begin by performing an analysis of the <a href="http://en.wikipedia.org/wiki/Single_point_of_failure"><abbr title="single points of failure">SPOFs</abbr></a> in the current architecture. A simple heuristic is this: if any particular server were to become unavailable, would the app continue to function? If the answer is <em>no</em>, then you&#8217;ve found a SPOF.</p>

<p>In our current architecture, we have two very obvious (and separate) SPOFs: the database server and the web server. If either is disconnected, our app is no longer able to operate normally.</p>

<p>At this point, anyone not familiar with the concept of a <a href="http://en.wikipedia.org/wiki/Shared_nothing_architecture">shared-nothing architecture</a> has some reading to do. Go on. I&#8217;ll wait.</p>

<p>Now, the easiest SPOF to address in this situation is the web server. As long as you aren&#8217;t storing any stateful information pertinent to a particular user on the web server node (file-based sessions being a typical offender), then adding additional web servers is feasible.</p>

<p>Now you run into yet another SPOF: your DNS A record, which ties your host (example.com) to an IP address.</p>

<p>(I assume you aren&#8217;t managing your own DNS for the sake of simplicity. If this is not the case, then you probably don&#8217;t need this overview.)</p>

<p>One solution is an HTTP-capable <a href="http://en.wikipedia.org/wiki/Load_balancing_(computing)">load balancer</a> such as <a href="http://haproxy.1wt.eu/">HAProxy</a>, <a href="http://nginx.org/">nginx</a>, the <a href="http://aws.amazon.com/elasticloadbalancing/">Amazon Web Services Elastic Load Balancer</a>, or one of many other similar products. A properly configured load balancer will let you distribute incoming requests according to a set of rules or heuristics, thus eliminating a SPOF. You can then add or remove web servers from this pool at will; you need only ensure that there are enough active servers in said pool to ensure that your app is able to process requests in a timely manner.</p>

<p>Now you&#8217;ve managed to remove the web server as a SPOF. If one or more web servers go offline, our app will continue to respond and serve requests as long as the number of remaining web servers is enough to satisfy our normal performance requirements.</p>

<p>The next obvious SPOF, your database, is a tricky one. If you&#8217;re smart and can afford it, this is something that you might want to make someone else&#8217;s problem. Products such as <a href="http://aws.amazon.com/rds/">Amazon&#8217;s Relational Database Service</a> can take a huge chunk of pain out of managing a relational database yourself. If you&#8217;re more adventurous and willing to try new things, there are also a plethora of non-relational technologies such as <a href="http://mongodb.org/">MongoDB</a>, <a href="http://wiki.basho.com/">Riak</a> and <a href="http://couchdb.apache.org/">CouchDB</a> that make various trade-offs in an attempt to better tolerate network partitions and provide better availability.</p>

<h3>The little things that make a big difference</h3>

<p>Open up your favorite web app in your browser. Now open the network traffic inspector panel (or whatever the equivalent is for your preferred browser). Chances are good that there are several dozen (if not hundreds) of requests for external stylesheets, Javascript, images, and fonts, not to mention any asynchronous <abbr title="XMLHttpRequest">XHR</abbr> requests to load dynamic content after the page has loaded.</p>

<p>Assuming all of these files have been properly minified and compressed, and you use all the best HTTP headers for caching, your web server still needs to respond to every request. A very simple and effective way to reduce the load on your web server is to move these assets somewhere else, either to a dedicated pool of static content servers, or to an external service such as <a href="s3.amazonaws.com">Amazon S3</a>. There are a few caveats to this, but it&#8217;s generally a good idea and can save you quite a few CPU cycles that could be put to use elsewhere.</p>

<h3>Going even further</h3>

<p>As with most things worth doing, your job is far from done. You might have a
    solid, mostly-available foundation for your web app, but
    there&#8217;s always more work. Here are some additional things to consider:</p>

<ol>
    <li>If your app lets users search through content on the site, moving search-related querying and storage to a separate tier is highly advisable. Products such as <a href="http://lucene.apache.org/solr/">Solr</a> and <a href="http://elasticsearch.org/">Elasticsearch</a> are well worth your time to investigate.</li>
    <li>Caching content that is expensive to generate is sometimes a necessary evil, and it&#8217;s always a double-edged sword. Familiarize yourself with common read and write <a href="http://en.wikipedia.org/wiki/Cache_(computing)#Writing_policies">cache policies</a> before adding something like <a href="http://memcached.org/">Memcached</a> or <a href="http://redis.io/">Redis</a>.</li>
    <li>Often, there are expensive requests that you are unable to cache, such as requests to third parties like Twitter or Facebook for lists of friends or other volatile and personal information. In these cases, an asynchronous job queue is your friend. Anything that does not need to be immediately computed, calculated, or queried to serve a request to a user should (at some point) be moved to an asynchronous task. There are good solutions, including <a href="http://celeryproject.org/">Celery</a>, an abstraction for several adapter-based brokers and result stores ranging from <a href="http://aws.amazon.com/sqs/">Amazon Simple Queue Service</a> to <a href="http://rabbitmq.com/">RabbitMQ</a> and even <a href="http://redis.io/">Redis</a> and <a href="http://mongodb.org/">MongoDB</a>.</li>
</ol>

<h3>Not quite there yet</h3>

<p>This article didn&#8217;t begin to scratch the surface of what&#8217;s possible for a modern web app. Many things were omitted, caveats were left out, and naive simplifications were made. Fear not! One of the great advantages of web apps over desktop apps is that it is possible (and advisable) to make incremental changes to both functionality and performance while remaining relatively transparent to the end user. All of the above strategies do <em>not</em> have to be implemented all at once. Thankfully.</p>

<p>Many skills and intuition are learned through trial and error, and can take years before becoming part of your natural tech vocabulary. For all you new and aspiring developers and devops out there, don&#8217;t give up! Systems and app architecture are not only challenging topics, but also incredibly rewarding.</p>]]></description>
              <link>http://webadvent.org/2012/going-from-one-to-a-million-users-by-jo%C3%ABl-perras</link>
              <guid>http://webadvent.org/2012/going-from-one-to-a-million-users-by-jo%C3%ABl-perras</guid>
              <pubDate>Sun, 02 Dec 2012 23:59:59 -0500</pubDate>
            </item>
                        <item>
              <title>Debugging Zen</title>
              <dc:creator>Ben Ramsey</dc:creator>
              <description><![CDATA[<p>Debugging is perhaps the skill that I find programmers have the hardest time exercising. It is also the most difficult to teach. Debugging, to me, is both a scientific discipline and an art. It often requires you to reach beyond analytical thinking to rely upon your own intuition in order to solve a problem.</p>

<p>Many developers use empirical approaches, systematically addressing each possible problem branch. <em>If A, then B. If B, then C. If C, then D.</em> This analytical approach works well and is easy to teach. The problem I find, though, is that many focus on identifying solutions before fully <a href="http://en.wikipedia.org/wiki/Grok">grokking</a> the problem. This leads to approaches that begin with D and work their way backwards to A, resulting in wild goose chases and wasted time.</p>

<p>That&#8217;s not usually how I approach debugging. For me, an approach based on intuition is key. But intuition is a tricky thing, isn&#8217;t it? After all, having a <em>gut feeling</em> about something seems mystical and a little paranormal. I don&#8217;t think it is, though. <a href="http://www.wiktionary.org/">Wiktionary</a> defines intuition as &#8220;immediate cognition without the use of conscious rational processes.&#8221; Here&#8217;s how I think it works. Your brain is constantly making computations, much like a Frank Herbert <a href="http://en.wikipedia.org/wiki/Mentat">mentat</a>. It has the data it needs, makes the calculation faster than you can blink your eyes, draws conclusions, and gives you the response in the form of a short-but-sweet gut instinct. That&#8217;s immediate cognition, and you weren&#8217;t conscious of any rational process being used.</p>

<p>This constant computation is something everyone does, but in Western civilization, we have suppressed it in favor of the rational approach. We can learn to develop it, listen to it, and, along with analytical thinking, make it a part of our standard thought processes. Here are some ways to make intuition a part of your debugging habits.</p>

<h2>Slow down</h2>

<p>As developers, when we encounter problems that require intense debugging, we&#8217;re often in a rush, especially if it&#8217;s something that affects a production environment. This rushed mindset creates the worst possible conditions for allowing you to effectively target the problem and identify a solution. When rushed, you don&#8217;t think clearly about where to begin, much less how to solve the problem. To think clearly, you must slow down.</p>

<p>When you find yourself rushing to fix a bug, it&#8217;s best to stop what you&#8217;re doing, close your eyes, take a deep breath, and let it out slowly. I know it sounds hokey, but this isn&#8217;t transcendental meditation. It&#8217;s perspective. It&#8217;s focus. When you take the time to slow down and focus, you can tap into your intuition, using it to discover where to begin and how to solve the problem.</p>

<p>In his biography of Steve Jobs, Walter Isaacson quotes Jobs as saying this about intuition and slowing down your mind:</p>

<blockquote><p>&#8220;If you just sit and observe, you will see how restless your mind is. If you try to calm it, it only makes it worse, but over time it does calm, and when it does, there&#8217;s room to hear more subtle things&#8201;&#8212;&#8201;that&#8217;s when your intution starts to blossom and you start to see things more clearly and be in the present more. Your mind just slows down, and you see a tremendous expanse in the moment. You see so much more than you could see before. It&#8217;s a discipline; you have to practice it.&#8221;</p></blockquote>

<h2>Stop saying &#8220;I don&#8217;t know&#8221;</h2>

<p>As developers, we like to focus on constraints. Software construction is all about finding the constraints of a problem domain and programming a solution to fit within those constraints. It&#8217;s no wonder our lives and jobs revolve around constraints, and we like it that way. But constraints can hold us back and squelch our intuition. When we assume we don&#8217;t know the answer to a problem, we impose a constraint upon ourselves that makes it more difficult for us to find the answer.</p>

<p>In her book, <em>Grow Your Intuition: 6 Simple Steps</em>, <a href="http://www.suzanbond.com/">Suzan Bond</a> says that we shut off our intuition when we answer questions with, &#8220;I don&#8217;t know.&#8221; She goes on to say, &#8220;When you stop using this phrase as much, you will open up your intuition. You&#8217;ll be able to see more possibilities, rather than limitations.&#8221;</p>

<p>It&#8217;s not wrong to admit lack of knowledge in an area, and I&#8217;m not advocating that you make up answers, but the truth is that you may already know the solution. Your brain already has the data it needs. Slow down. Take a breath. Ponder on it. Let your intuition speak to you. If you have trouble finding a solution, ask yourself what may be blocking you from seeing it. Don&#8217;t accept that you don&#8217;t know the answer. Accept that you must discover the answer.</p>

<h2>The problem is in <em>your</em> code</h2>

<p>Here&#8217;s a humbling but crucial notion. It&#8217;s never fun to accept the blame for something, so it&#8217;s easiest to point fingers at someone or something else. <em>This third-party library or framework is terrible! John wrote this spaghetti code three years ago, and it&#8217;s awful! This programming language is a nightmare!</em> Let&#8217;s face it, developers are proud folks and masters of hyperbole. I have learned, though, that the problem is most often found right in your own code, so it&#8217;s best to begin with that assumption.</p>

<p>Very early in my career, I worked with a developer&#8201;&#8212;&#8201;we&#8217;ll call him John&#8201;&#8212;&#8201;who always blamed someone else&#8217;s code when he found a bug. He loved doing this so much that he would leap from his desk, giggling, and run into my office to boast about finding a bug in some third-party library or even in the programming language we were using. John loved being able to say that the language was faulty and that he was responsible for finding it out. On more than one occasion, he had the programming language&#8217;s bug report form open and filled out before I was able to catch him and force him to readdress the issue by carefully looking at his own code. Every time, his code was at fault.</p>

<p>When you start with the assumption that it&#8217;s someone else&#8217;s code that has the problem, then you&#8217;re hurting yourself in several ways. First of all, you&#8217;re impeding your own ability to find the real problem because you start by looking in the wrong place. This costs you time. Secondly, you&#8217;re setting yourself up to look like an buffoon when it turns out your code was the problem all along, and you wasted time, energy, and resources trying to blame something else. Lastly, you hurt your reputation as a problem solver by <a href="http://en.wikipedia.org/wiki/Buck_passing">passing the buck</a>.</p>

<p>When you start with the assumption that the problem is in <em>your</em> code, then you display humility and leadership by accepting the responsibility to solve the problem. If it turns out the problem was, in fact, in someone else&#8217;s code, then you have instilled in others a great deal of trust in your ability to actively pursue solutions to problems.</p>

<h2>Focus on the problem, not a solution</h2>

<p>When you focus on identifying a solution before fully grokking the problem, then you&#8217;ve put the cart before the horse. Start at the beginning; start with the problem. I think this is difficult for many developers, because we like to jump to conclusions. <em>I see both A and B, so it must be C, therefore D!</em> Finding and implementing solutions is thrilling and satisfying for us. Finding problems? Not so much.</p>

<p>Keep in mind that the symptoms may not indicate the real problem. We know what they are, so we fix the problem by testing for and addressing the symptoms. Once the symptoms no longer appear, the problem is solved, right? Nope, now you&#8217;ve buried the problem deeper, and it&#8217;ll be harder to find next time.</p>

<p>A specific story from my career comes to mind where multiple, identical records were added to a database table for a specific action that should have added only one record each time. This resulted in the customer generating reports that contained multiple, identical records. That was the symptom. In an effort to appease the customer, a solution was devised to combine the records at the point in which the report was generated. This made the customer happy, but it didn&#8217;t solve the problem. In fact, now that the problem was buried, it was more difficult to see, and the database continued to fill up with bogus records.</p>

<p>Always get to the heart of the problem. Don&#8217;t just look at the surface symptoms and assume they are what needs resolving. Focusing on the solution won&#8217;t get you there. You need to focus on the problem. I find once I understand the problem&#8201;&#8212;&#8201;once I fully grok it&#8201;&#8212;&#8201;my intuition kicks in with a handy solution.</p>

<h2Debugging intuition</h2>

<p>In his book, <em>The Universe in a Single Atom</em>, the <a href="http://dalailama.com/">Dalai Lama</a> writes:</p>

<blockquote><p>&#8220;The difference between science as it stands now and the Buddhist investigative tradition lies in the dominance of the third-person, objective method in science and the refinement and utilization of first-person, introspective methods in Buddhist contemplation. In my view, the combination of the first-person method with the third-person method offers the promise of a real advance in the scientific study of consciousness.&#8221;</p></blockquote>

<p>While the Dalai Lama refers to the study of consciousness in this statement, the central argument of his book is that the empirical scientific method can benefit from first-hand experiential intuition and must benefit from it, if we are to make ethical advances in the sciences and understanding of our universe. I agree, and I believe that intuition can benefit even computer science and software engineering.</p>

<p>I can&#8217;t pretend to understand all the mysteries of the mind, nor can I purport to teach you all about intuition. I&#8217;m learning these things myself. However, I do know that intuition is something everyone can take advantage of. I rely on it daily. I&#8217;ve noticed how it has saved the day in countless debugging sessions throughout my career, and while I&#8217;ve known of the role it plays all along, I feel it is time to accept it and share my experiences using it.</p>

<p>So, be a better problem solver and debugger by tapping into your intuition. Learn how to slow yourself down. Be confident that you already know the answer. Show humility by first assuming the problem lies within your own code. Focus on identifying the problem; once identified, the solution will come to you. Combine the use of intuition with standard analytical processes.</p>

<p>You will be a better developer.</p>
]]></description>
              <link>http://webadvent.org/2012/debugging-zen-by-ben-ramsey</link>
              <guid>http://webadvent.org/2012/debugging-zen-by-ben-ramsey</guid>
              <pubDate>Sat, 01 Dec 2012 23:59:59 -0500</pubDate>
            </item>
              </channel>
</rss>
