<?xml version="1.0" encoding="utf-8"?>


<rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  xmlns:admin="http://webns.net/mvcb/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">

      <channel>
    
    <title><![CDATA[Working Concept Blog]]></title>
    <link>http://workingconcept.com/blog</link>
    <description>A spontaneously updated source of tips and random thoughts.</description>
    <dc:language></dc:language>
    <dc:creator>hello@workingconcept.com</dc:creator>
    <dc:rights>Copyright 2013</dc:rights>
    <dc:date>2013-05-23T07:02:10-05:00</dc:date>
    <admin:generatorAgent rdf:resource="http://statamic.com/" />
    
        <item>
      <title><![CDATA[Return to Seattle]]></title>
      <link>http://workingconcept.com/blog/return-to-seattle</link>
      <guid>http://workingconcept.com/blog/return-to-seattle</guid>
      <content:encoded><![CDATA[<p><img src="/assets/img/blog/long-drive.jpg" alt="Lake Mary to Seattle" /></p>

<p>Working Concept is now officially back in Seattle! I&#8217;m excited to be setting up a studio space in the historic and really cool <a href="http://inscapearts.org/">Inscape Building</a> with <a href="http://www.linkedin.com/in/bryanwilsonseattle">Bryan Wilson</a> and <a href="http://sccottt.com/">Scott Thiessen</a>.</p>

<p>It&#8217;s exhilarating to be in good company and back on the west coast.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2013-03-21T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[SmartStart WordPress Theme Fix]]></title>
      <link>http://workingconcept.com/blog/smartstart-wordpress-theme-fix</link>
      <guid>http://workingconcept.com/blog/smartstart-wordpress-theme-fix</guid>
      <content:encoded><![CDATA[<p><em>This is an oddly-specific post that I&#8217;m leaving here just in case my blog can better focus on the issue than ThemeForest&#8217;s flat comments<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>.</em></p>

<p>A rather common problem with the <a href="http://themeforest.net/item/smartstart-wp-responsive-html5-theme/2067920">SmartStart Responsive HTML5 WordPress theme</a> is that upon upgrading to WordPress 3.5, the site will suddenly start throwing an error on portfolio pages:</p>

<pre>
Warning: array_count_values() [function.array-count-values]: Can only count STRING and INTEGER values! in (...)/themes/smartstart/functions/custom-functions.php on line 640
</pre>

<p>A quick fix that drops the error and seems to leave everything in good order is to wipe out a line that tries to count something that&#8217;s not there. You can do this by opening <strong>smartstart/functions/custom-functions.php</strong> in a text editor (it&#8217;s okay if PHP seems scary) and finding <strong>line 640</strong>. You&#8217;re looking for this part:</p>

<p><code>$slide_types = array_count_values( $project_slider[0][0] );</code></p>

<p>And you&#8217;ll want to change it to look like this&#8230;</p>

<pre>
//$slide_types = array_count_values( $project_slider[0][0] );
$slide_types = 0;
</pre>

<p>Don&#8217;t forget to save your file! By adding two forward slashes in front of the original line you&#8217;re just commenting it out and telling WordPress to ignore it, so if you have any problems you can easily undo your change.</p>

<p>I hope this helps if anybody finds it! My original post is on <a href="http://themeforest.net/item/smartstart-wp-responsive-html5-theme/discussion/2067920?page=87#comment_2969553">page 87 of the theme&#8217;s discussion thread</a>.</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>Flat comments seem pretty lame since the discussion areas often act like support forums, and many helpful bug reports and solutions get buried.&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2013-01-31T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Glasses]]></title>
      <link>http://workingconcept.com/blog/glasses</link>
      <guid>http://workingconcept.com/blog/glasses</guid>
      <content:encoded><![CDATA[<p><em>Warning: I usually save personal posts for my private journal, but I feel like I should share this reflection at the risk of boring both my readers more than usual.</em></p>

<p>I got my first pair of glasses this week and I&#8217;m amazed at the literal change in perspective. My unaided vision isn&#8217;t horrible, but years in front of glowing rectangles have started to bear noticeable effect. On top of this, my eyes apparently have varying astigmatisms – meaning the wacky curvature of my eyeballs results in distortion. I had no idea, of course, because I&#8217;ve had my life thus far to adjust. Adding corrective lenses, however, is a headache: my &#8220;corrected&#8221; field of vision falls off more sharply and artificially to the left, so everything on my monitor is warped by a bizarre, horizontal gravity. Every close, flat surface tapers to follow a new and uncomfortable perspective. My world is suddenly crisp, richly detailed, and disturbingly shifted.</p>

<p>Here&#8217;s the cool part though: this is temporary because my brain will adjust. I&#8217;m already less distracted by the frames on my face, and after a few days my brain should adapt to signals that are different from those it&#8217;s been interpreting my whole life. How cool is that?</p>

<p>By positioning some shaped polycarbonate in front of my eyes, my quality of life improves. The hardware update does not require any software change. Sometimes I&#8217;m frustrated with the limitations of my own brain, and I forget that it&#8217;s a marvelous and powerful thing whether I appreciate it or not.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2013-01-13T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Page Layers]]></title>
      <link>http://workingconcept.com/blog/page-layers</link>
      <guid>http://workingconcept.com/blog/page-layers</guid>
      <content:encoded><![CDATA[<p>One discovery this week needn&#8217;t be a secret: it&#8217;s an app called <a href="http://www.pagelayers.com/">Page Layers</a>, and it&#8217;s already making my life easier.</p>

<p>Often I&#8217;ll need to put together mockups of an existing web page, and I&#8217;ll start by taking screenshots and breaking them up in Photoshop. This can take a significant chunk of time, and gets excessively annoying should the site&#8217;s content change during the Photoshop spree.</p>

<p>Page Layers solves both problems quickly and simply: feed it a URL and it&#8217;ll capture a screenshot like <a href="http://derailer.org/paparazzi/">Paparazzi</a> and similar programs. The critical difference is that it&#8217;ll allow you to save a layered PSD file, whose folder names and hierarchy come directly from the page markup. All text gets flattened, and if a particular element needs to be further separated it&#8217;s as simple as adding a <code>span</code> element before running through Page Layers. It&#8217;s, simple, smart, and surprisingly fast even on my mid-2009 MacBook Pro.</p>

<p><img src="http://workingconcept.com/assets/img/blog/page-layers.jpg" alt="" /></p>

<p>While there may already be a less primitive way to jump-start Photoshop mockups of existing pages, Page Layers has already been a helpful addition to my workflow. It fits a niche role, but works its reliable magic just as well as I&#8217;d hoped.</p>

<p>It&#8217;s available on the <a href="https://itunes.apple.com/us/app/page-layers/id437835477?mt=12">Mac App Store for $33.99</a>, which I&#8217;d call pricey if the time saved didn&#8217;t more than justify the price.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2013-01-08T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[[link] Design is Not Veneer]]></title>
      <link>http://workingconcept.com/blog/link-design-is-not-veneer</link>
      <guid>http://workingconcept.com/blog/link-design-is-not-veneer</guid>
      <content:encoded><![CDATA[<p>I&#8217;ve been moved by this article I came across today, which passionately clarifies the vast difference between design and decorating with enviable brevity and resolve. The implications are beyond design or any particular commercial endeavor, though the focus is on web design.</p>

<p>In other words, please read this. <a href="http://aralbalkan.com/notes/design-is-not-veneer/">Aral Balkan: Design is not veneer.</a></p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2012-12-29T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Script: Copy Harvest Timesheet]]></title>
      <link>http://workingconcept.com/blog/script-copy-harvest-timesheet</link>
      <guid>http://workingconcept.com/blog/script-copy-harvest-timesheet</guid>
      <content:encoded><![CDATA[<p>In March of this year, I left <a href="http://www.marketcircle.com/billings/">Billings</a> for the more cloud-friendly <a href="http://www.getharvest.com/">Harvest</a> time tracking and invoicing service. It was an excellent choice, and the only complaint I&#8217;ve had is that recently I&#8217;ll have to log in every day to duplicate the previous day&#8217;s Timesheet, making my usual billable buckets available and ready to go.</p>

<p>Since this is an annoying and painfully redundant task, I decided to cut it down to a script I can run with Alfred. For this, I&#8217;m using some simple PHP to execute commands via the <a href="http://www.getharvest.com/api">Harvest API</a>. I simply choose my new &#8220;Harvest - Duplicate Timesheet&#8221; command, a few seconds pass, and then the browser opens to my current Timesheet to confirm that all went well.</p>

<h3>What This Does</h3>

<ol>
<li>Searches a day at a time into the past (from today) to find the last-used Timesheet. I&#8217;ve limited the search to 10 days so we don&#8217;t get an infinite loop – you may need to adjust if you rarely work or take long vacations.</li>
<li>Duplicates each item from the last sheet onto today&#8217;s, with 0 hours.</li>
<li>Toggles the last timer. By default, the last timer will start out running. By toggling it, our new Timesheet will be ready to go with no items running.</li>
</ol>

<h3>What This Doesn&#8217;t Do</h3>

<p>Anything else. I made it for myself, and you&#8217;re free to improve it – it won&#8217;t be friendly warning you about invalid credentials or telling you that it can&#8217;t find a last-used Timesheet within the search period.</p>

<p>On the plus side, it would also have a hard time screwing anything up. It doesn&#8217;t modify existing data, it doesn&#8217;t delete anything, and it doesn&#8217;t change any timers. It&#8217;s pretty simple.</p>

<p>I guess I have to remind you that I offer no warranty, and should you ruin everything and blow up the planet while playing with my humble PHP, it&#8217;s not my fault.</p>

<h3>Making It Go (Three Steps)</h3>

<h4>1. Grab the Script</h4>

<p>Clone or save <a href="https://github.com/mattstein/duplicate-harvest-timesheet/blob/master/harvest-duplicate-timesheet.php">this PHP</a>, add your account credentials, and put it somewhere that it can be called upon. (I have a Google Drive folder of scripts, for example, which I can conveniently run with the same path on any machine.)</p>

<h4>2. Create an Alfred Trigger</h4>

<p>You could do this with cron so it&#8217;d be totally automated, but for some reason I still prefer Alfred.</p>

<ol>
<li>Open Alfred&#8217;s <strong>Extensions</strong> preference pane.</li>
<li>Click the little &#8220;+&#8221; (bottom left) to create a new <strong>Shell Script</strong>.</li>
<li>Add some basic information, a title, description, and choose a keyword that you like. I run this silently, but this is your choice of course.</li>
<li>In the Command box, add… <code style="display: block; clear: both; width: 100%; margin-bottom: 0.5em;">php ~/path/to/your/harvest-duplicate-timesheet.php
<br>open https://shortname.harvestapp.com/time</code> Change the path and account shortname to reflect your own details.</li>
<li>Save.</li>
</ol>

<h4>3. Run it!</h4>

<p>Use your new trigger, and if all goes well you&#8217;ll just wait a few seconds and your freshly-copied Timesheet will be staring right back at you from the browser.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2012-12-11T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Amazon Reviewer Widget]]></title>
      <link>http://workingconcept.com/blog/amazon-reviewer-widget</link>
      <guid>http://workingconcept.com/blog/amazon-reviewer-widget</guid>
      <content:encoded><![CDATA[<p><img src="/assets/img/blog/amazon-reviewer-widget.png" alt="Amazon Reviewer Widget" style="float: left; padding: 0 15px 15px 0;" /> I often waste time checking to see whether any of my Amazon.com reviews have landed more helpful votes. For that reason, I hacked together a quick OSX Dashboard Widget that lets me watch obsessively without getting a browser involved. Enjoy<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>!</p>

<p><a href="/assets/downloads/Amazon%20Reviewer%20Profile.wdgt.zip">Amazon Reviewer Profile.wdgt.zip</a> (23KB)</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>This could be a bit too rough around the edges for you; there&#8217;s no icon, it could break if Amazon updates the profile page markup, and a long name or wildly different ranking might even be enough to make it ugly. You get no warranty, but I&#8217;d also be happy to clean it up if enough others actually use it.&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2012-12-03T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Devot:ee Pride]]></title>
      <link>http://workingconcept.com/blog/devot-ee-pride</link>
      <guid>http://workingconcept.com/blog/devot-ee-pride</guid>
      <content:encoded><![CDATA[<p>You&#8217;ve dealt with that person before, the one who gets way too excited over his infinitesimal achievement. Yesterday, dear reader, that person was me! Two goals accomplished:</p>

<ol>
<li>Post something useful, anything, even <a href="http://devot-ee.com/add-ons/dollars-fieldtype">a simple fieldtype</a>, to Devot:ee.</li>
<li>Experience the thrill of having a friendly stranger improve something I made. This was at the hands of <a href="http://elivz.com">Mr. Eli Van Zoeren</a>, who kindly made said fieldtype available for <a href="http://pixelandtonic.com/matrix">Matrix</a> and shared the result.</li>
</ol>

<p>Thanks again, Eli! And of course <a href="http://devot-ee.com/members/profile/ryan-masuga">Ryan Masuga</a>, whose hard work makes Devot:ee an essential resource.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2012-11-29T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[EllisLab and the Future of EE]]></title>
      <link>http://workingconcept.com/blog/ellislab-and-the-future-of-expressionengine</link>
      <guid>http://workingconcept.com/blog/ellislab-and-the-future-of-expressionengine</guid>
      <content:encoded><![CDATA[<p>EllisLab recently made announcements that mark the beginning &#8230; something. A redesigned site (with <a href="http://ellislab.com/expressionengine">significant reorganization</a>, <a href="http://ellislab.com/blog/entry/new-ceo-chief-maker-and-ellislab-focus">new CEO</a>, and the <a href="http://ellislab.com/blog/entry/introducing-a-new-ellislab-support-experience">move to paid official support</a> were among changes publicized on the company blog. The pro network ended abruptly, and <a href="http://eeinsider.com/blog/the-new-ellislab.com-you-want-my-opinion/">thoughtful</a> <a href="http://www.hopstudios.com/blog/ten_reactions_to_ellislabs_major_policy_shifts_eecms">reactions</a> are making their way to the interweb.</p>

<p>People (myself included) can be resistent to change, and having to pay for something that&#8217;s always been free<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> is a bummer if not worse. I also understand that change can be good, even essential, and I&#8217;m happy to pay for something that&#8217;s valuable to me.</p>

<p>While I truly hope that EllisLab has refocused itself to vigorously evolve and support excellent software, I&#8217;m pessimistic about what the changes could mean for its community and how that will shape ExpressionEngine&#8217;s future.</p>

<p>When I started using ExpressionEngine in 2007, it was an exciting endeavor. The control panel was one of very few that looked modern and visually considered, the documentation made it easy to start using powerful templating features, and the forums were already bustling with other users and EllisLab staff. I felt like I was just getting into something that did more than I needed, and where everybody was strangely friendly and had my back if I could ask good questions. (And in some cases, patient souls helped me understand how to ask better questions.)</p>

<p>ExpressionEngine became easier to recommend as I got more familiar with it. It worked for small clients and larger clients. I heard someone from the Huffington Post talk about caching and optimization for high-traffic sites, then helped build larger sites in the studio I worked at. It seems like the momentum just kept building, and ExpressionEngine and I kept changing at a steady pace. And it was good.</p>

<p>Now 2012. I rarely build an EE site anymore that <em>doesn&#8217;t</em> use <a href="http://buildwithstructure.com/">Structure</a>. Very often <a href="http://pixelandtonic.com/matrix">Matrix</a>, <a href="http://pixelandtonic.com/playa">Playa</a>, <a href="http://pixelandtonic.com/wygwam">Wygwam</a>, and maybe a dozen addons are part of a project. The ExpressionEngine forums have seemed less active and less frequented by EllisLab staff. <a href="http://devot-ee.com/">Devot-ee</a> is where I go to hunt for an add-on will save me hours of work. I get occasional contacts through <a href="http://director-ee.com/">Director-ee</a>. The Stack Exchange initiative seems to be gaining momentum and is now in <a href="http://expressionengine.stackexchange.com">public beta</a>. More and more of my meaningful time in the ExpressionEngine universe is outside of any official sites or support channels.</p>

<p>It seems like EllisLab knows this, and would like to get out of the business of facilitating community altogether, to get back to improving the quality and support of its software. It knows that it&#8217;s great for large sites, and that it can thrive where budgets are big enough to include ongoing support costs. It knows that it doesn&#8217;t need to appeal to the little guy anymore, that he&#8217;ll look elsewhere and find <a href="http://blockscms.com/">Blocks</a>, <a href="https://www.pyrocms.com/">PyroCMS</a>, <a href="http://laravel.com/">Laravel</a>, <a href="http://statamic.com/">Statamic</a>, and others. It seems smart.</p>

<p>The EE community wouldn&#8217;t exist without ExpressionEngine. I&#8217;ve benefitted from it, as have clients of mine large and small. What I&#8217;ll be interested to see is how ExpressionEngine changes with a less diverse and centralized user base.</p>

<p>I&#8217;m still just as confident that ExpressionEngine is an excellent choice for large projects, though I think it&#8217;s also a good time to be get to know other products that will fill the growing gap.</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>ExpressionEngine support has never been free, it&#8217;s just been included in that one-time license fee. This apparently hasn&#8217;t worked out well for EllisLab.&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2012-11-28T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Sublime Text 2 Orientation]]></title>
      <link>http://workingconcept.com/blog/sublime-text-2-orientation</link>
      <guid>http://workingconcept.com/blog/sublime-text-2-orientation</guid>
      <content:encoded><![CDATA[<p>I started using <a href="http://www.sublimetext.com/2">Sublime Text 2</a> in March after getting excited about its speed, easy package control, and good reputation. I spent some time this week going through the entire <a href="https://tutsplus.com/course/improve-workflow-in-sublime-text-2/">Tuts+ &#8220;Perfect Workflow in Sublime Text 2&#8221;</a> course by Jeffrey Way and realized how much I&#8217;ve been missing. I would strongly recommend this free course whether you&#8217;re interested in Sublime Text 2 or are using it with the nagging feeling that you should level up.</p>

<p>I&#8217;ll sum up my favorites (old and new), but it&#8217;s seriously worth your time having Jeffrey <em>show</em> you each in more detail.</p>

<h3>It&#8217;s all text</h3>

<p>The preferences are stored and edited in JSON files. The packages are uncompressed folders that simply live neatly in Sublime&#8217;s Application Support folder. (Both of these things, by the way, make it very handy to sync everything with Dropbox.) The project-wide search returns results as a flat text file in a new tab. Sublime is all about text and the keyboard, with very little UI that requires or uses anything else. You can rely on the mouse less as you get more comfortable, without the frustration or slowdown of jumping right into the terminal for text editing.</p>

<h3>Ditch the sidebar forever with ⌘+P</h3>

<p>Never hunt through files and folders again, just type the name of what you&#8217;re looking for whether it&#8217;s a path, a method, or &#8230; well anything. Tack on an @ symbol to a filename and all methods will be listed so you can jump in exactly where you&#8217;d like.</p>

<h3>Do (almost) anything with the Command Palette ⌘+⇧+P</h3>

<p>Anything Sublime can do will be accessible here so you can stay off the mouse even if you don&#8217;t have all the shortcuts down. Change syntax on the current file, install or remove a package, access snippets or build options – really just anything. It&#8217;s <a href="http://www.alfredapp.com">Alfred</a>, but in a text editor.</p>

<h3>Multiple Cursors &amp; Incremental Search</h3>

<p>I shouldn&#8217;t admit to you, dear reader, that I was happily working away in Sublime Text 2 completely oblivious to its multiple cursors. Sure, you can <code>⌘+click</code> several things manually and get a new cursor for each one. But that&#8217;s little beans.</p>

<p>You&#8217;ve already noticed that every time you select a word, every instance of that exact same thing is highlighted. Hit <code>⌘+D</code> and the next occurrence of that word will be selected with its own cursor. Repeat until you&#8217;ve got enough of them selected, then just type to change them all at once.</p>

<p>But it gets better: say you want to select <em>every</em> occurrence of that word instead of hitting <code>⌘+D</code> repeatedly. Let&#8217;s do that. Start by placing your cursor inside any given word, then hit <code>⌘+D</code> once to select the word. Now hit <code>Control+⌘+G</code> and every occurrence will be selected with its own cursor. Simple and extremely useful.</p>

<h3>Snippets</h3>

<p>We all know that snippets are essential time-savers, and you probably already know that Tools → New Snippet will give you a (simple) template to edit and save as a .sublime-snippet file in your User folder. Jeffrey gets into setting up GitHub Gist integration and a few other helpful pointers.</p>

<h3>Package: Package Control</h3>

<p>Install <a href="http://wbond.net/sublime_packages/package_control">Will Bond&#8217;s Package Manager</a> first, and install it now if you haven&#8217;t already. Most Sublime packages are current and available through this channel, making it an absolute must if you want package discovery/installation/update/removal to take only a few keystrokes and a few seconds.</p>

<h3>Package: Zen Coding</h3>

<p>Use a simple, logical shorthand to quickly generate HTML structure. It&#8217;s more compelling to see this in action, but the idea is that you can write something like <code>div#nav&gt;ul&gt;li*5&gt;a</code> to hit tab and get&#8230;</p>

<pre><code>&lt;div id="nav"&gt;
    &lt;ul&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;li&gt;&lt;a href=""&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;
</code></pre>

<p>Obviously you can do quite more than this, and it applies to CSS authoring as well.</p>

<h3>Package: Fetch Files and Packages</h3>

<p>Commissioned by Tuts+, this package lets you define preset file and package shortcuts so you can get a project running quickly. Simply put, it takes a predefined URL and downloads it (extracting, if necessary) to whatever directory you specify from within Sublime. I added shortcuts for jQuery, variations of the Twitter Bootstrap, the HTML5 Boilerplate, and CodeIgniter.</p>

<h3>Package: Fast Folder &amp; File Creation</h3>

<p>I&#8217;m not sure why this wasn&#8217;t built into Sublime in the first place, but the AdvancedNewFile package lets you use <code>⌘+⌥+N</code> to type a folder/file path and hit return to create it. This saves having to use the standard OS GUI to save a newly-created file.</p>

<h3>Package: Sidebar Enhancements</h3>

<p>I started using this a while ago, but in light of my newer discoveries it&#8217;ll certainly become more trivial. Anyway, use Sidebar Enhancements to get more right-click options in your sidebar.</p>

<h3>Package: Sublime Linter</h3>

<p>A great package that&#8217;ll check your syntax as you write, or as you save depending on how you set it up. You may have to do a little bit more work setting up linters depending on what languages you use, but the workflow improvement is surely going to be worth it. Unless you never make typos or mistakes. In that case, please contact me because I would like to talk about hiring you for everything I ever do.</p>

<h3>Package: Sublime + Marked</h3>

<p>I tend to use <a href="http://bywordapp.com">Byword</a> for writing posts like this in Markdown, but this part of Jeffrey&#8217;s course led me to better appreciate the build system. To me, &#8220;build&#8221; always meant compile source code into a binary executable of some kind, be it a Cocoa app or a Flash/Air program. Here, Jeffrey demonstrates how you can author your Markdown and then set up a custom build, effectively launching <a href="http://markedapp.com">Marked</a> (an inexpensive Markdown viewer) with <code>⌘+B</code> to view your work in HTML.</p>

<h3>Bonus Package: Less Compiler</h3>

<p>After seeing Jeffrey&#8217;s Markdown+Marked screencast, it dawned on me that I should be compiling Less from Sublime. (Wipe that look off your face, it just never occurred to me okay?) Sure enough, there was a package for that: <a href="https://github.com/berfarah/LESS-build-sublime">LESS-build-sublime</a>. Do some work, <code>⌘+B</code>, and compile that .less into .css. Easy.</p>

<p>Much of this may be review, or overly simplistic for those wizards who have mastered Sublime Text 2. This is one of those posts I&#8217;ll probably be referring back to myself, and hopefully you&#8217;ve gotten something out of it as well!</p>

<p>Is there something you&#8217;ve stumbled on that you can&#8217;t live without? Let me know!</p>

<p><strong>Update:</strong> I forgot to mention in my original post that it was <a href="http://www.mutuallyhuman.com/blog/2012/10/18/configuring-sublime-text-2/">Ross Hunter&#8217;s post</a> that kicked off my latest quest to improve my Sublime workflow, and it&#8217;s probably to his credit that I ended up spending a few hours with the Tuts+ series. Thanks Ross!</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2012-11-23T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Design & Human Experience]]></title>
      <link>http://workingconcept.com/blog/design-human-experience</link>
      <guid>http://workingconcept.com/blog/design-human-experience</guid>
      <content:encoded><![CDATA[<blockquote>
  <p>&#8220;To design something really well you have to get it. You have to really grok what it’s all about. It takes a passionate commitment to thoroughly understand something – chew it up, not just quickly swallow it. Most people don’t take the time to do that. Creativity is just connecting things.</p>
  
  <p>When you ask a creative person how they did something, they may feel a little guilty because they didn’t really do it, they just saw something. It seemed obvious to them after awhile. That’s because they were able to connect experiences they’ve had and synthesize new things. And the reason they were able to do that was that they’ve had more experiences or have thought more about their experiences than other people have. Unfortunately, that’s too rare a commodity. A lot of people in our industry haven’t had very diverse experiences. They don’t have enough dots to connect, and they end up with very linear solutions, without a broad perspective on the problem. The broader one’s understanding of the human experience, the better designs we will have.&#8221;</p>
</blockquote>

<p>– Steve Jobs</p>

<p><em>via <a href="https://vanschneider.squarespace.com/journal/r6g1aie5v9e7xwzwrilkd7d1d6g17k">vanSchneider Blog</a></em></p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2012-11-18T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[The Challenge of Structure Previews]]></title>
      <link>http://workingconcept.com/blog/the-challenge-of-structure-previews</link>
      <guid>http://workingconcept.com/blog/the-challenge-of-structure-previews</guid>
      <content:encoded><![CDATA[<p>It happened again today. Every time I introduce a client to the ExpressionEngine admin panel, the same question comes up: &#8220;how do I preview my changes before I make them live?&#8221; It&#8217;s a natural question for someone who wants to be sure their edits look right before putting them in front of a vast, faceless audience. And I&#8217;m still not sure how to answer.</p>

<p>Sure, there are plenty of ways to preview new posts. You can find articles, add-ons, and various methods for showing draft entries to the requisite few. That&#8217;s great.</p>

<p>But the elephant in the room is the Structure page, an existing and very live entry to which the client wants to make <em>and preview</em> edits. Our options are as follows:</p>

<h4>1. Upgrade to <a href="http://betterworkflow.electricputty.co.uk/">Better Workflow</a>.</h4>

<p>It&#8217;s a brilliant $65 add-on that, among other things, clones entries and takes over the task of managing their statuses. In other words, those edits take the form of a separate draft entry that can be fine-tuned and previewed without even a whiff of change on the public website. Drafted content can then be published, replacing the current live entry&#8217;s content. No copying and pasting, no changing entry IDs, all very smooth.</p>

<p>Better Workflow does not, however, fully support more exotic add-ons. This prevented us from using it, for example, on a large site that benefits from Pixel &amp; Tonic&#8217;s <a href="http://pixelandtonic.com/assets">Assets</a>. And we were really, really bummed to part with Better Workflow – though hopefully Assets will be supported someday.</p>

<h4>2. Tinker with live updates at 4am, making iterations while the audience is hopefully sleeping.</h4>

<p>I&#8217;m sure lots of us do this, but that doesn&#8217;t make it any more attractive to a client who bothers to get decent sleep.</p>

<h4>3. Clone the page to a different URL, edit, then copy successful changes back to the original.</h4>

<p><a href="http://devot-ee.com/add-ons/mx-cloner">MX Cloner</a> can take the pain out of cloning entries. Using that, we can get a reasonable little workflow:</p>

<ul>
<li>Clone the page you&#8217;d like to edit, changing the URL and &#8220;Hide from nav?&#8221; to &#8220;Yes&#8221; if that&#8217;s relevant.</li>
<li>Submit changes to your heart&#8217;s content, previewing at your secret, public URL. (You could also change the status and restrict preview privileges to logged-in users if need be.)</li>
<li>Either scramble to simultaneously retire the old entry and replace it with the new one (URL + status changes), or copy and paste your changes one field at a time to the existing entry. For the latter, you&#8217;ll be angry if you used Matrix, Playa, or really anything other than a textarea of some sort.</li>
</ul>

<p>It&#8217;s that last part that makes this method feel a bit silly.</p>

<h4>4. Use a staging environment for managing changes, then push to the production environment when it&#8217;s time.</h4>

<p>This seems like a pretty clean way to do it in theory, but what about those things that pull the two environments out of sync? There could be Freeform submissions, template tracking updates, etc. A straightforward database + filesystem transfer could wipe out important information on the production side.</p>

<h4>Conclusion: there&#8217;s still no perfect way to preview Structure page edits.</h4>

<p>After all this time, Better Workflow seems like the only option that doesn&#8217;t require the client to jump through hoops. (Assuming the additional $65 and more limited add-on support isn&#8217;t a hoop.)</p>

<p>It&#8217;s tough to ask smaller clients to invest in a flexible, modern CMS where a pretty basic (and fair, I think) expectation of previewing content can&#8217;t be met.</p>

<p>Am I alone thinking this? Am I missing something? Is this just a sign that I&#8217;ve identified the add-on I need to make? Let me know what you think in the comments!</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2012-10-31T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Into the Woods with Statamic]]></title>
      <link>http://workingconcept.com/blog/into-the-woods-with-statamic</link>
      <guid>http://workingconcept.com/blog/into-the-woods-with-statamic</guid>
      <content:encoded><![CDATA[<p><img src="http://workingconcept.com/assets/img/blog/into-the-woods.jpg" alt="" /></p>

<p>A post from <a href="http://alpha.app.net/typaulhus">@typaulhus</a> on ADN was the first I heard of this &#8220;<a href="http://statamic.com">Statamic</a>,&#8221; and after a brief period of skepticism I&#8217;m head-over-heals for it. Statamic has officially replaced ExpressionEngine as CMS of choice for this humble little site. Why is it so exciting?</p>

<ul>
<li>No database. Fast, easy to deploy, and I can keep <em>everything</em> in Git without doing anything clever.</li>
<li>Content is stored in Markdown files. This is a huge plus because I write just about everything longer than a paragraph in Markdown and then I have to figure out how to get it into that other thing. I can skip that step.</li>
<li>Very clever design. It&#8217;s very clear that Jack and Mubashar wanted to get away from EE&#8217;s bloat while taking advantage of its templating convenience and &#8230; well &#8230; Structure. It feels perfectly focused as a CMS for small sites and blogs, while being flexible enough to work for web creators that have ideas beyond a WordPress theme.</li>
<li>Gorgeous admin panel. Blazing fast and perfect on an iPad? Yes and yes. If you think that&#8217;s shallow, log in to EE&#8217;s admin panel on your iPad. I&#8217;ll wait.</li>
</ul>

<p>The migration from EE went smoothly and happened more or less in one evening. Here&#8217;s how I did it&#8230;</p>

<h3>Step 1: move comments to Disqus.</h3>

<p>I was using native EE comments, and the easiest path here was to create a Disqus account for the site and import my previous comments. Ryan Battles posted <a href="http://ee-spotlight.com/tutorials/importing_expressionengine_comments_into_disqus">a template tutorial for exporting</a> a <a href="http://help.disqus.com/customer/portal/articles/472150">WXR file for Disqus</a>. It&#8217;s as easy as creating two templates with just a little bit of required consideration.</p>

<p>I foolishly waited quite a while and even opened a support ticket before finding <a href="http://import.disqus.com/">import.disqus.com</a>, which barfed on a syntax error in my XML. I waited another 24 hours and got an import error with no message, and then frustratedly hacked my way through two ExpressionEngine addons and two more Disqus test accounts before I got everything straightened out. For the record, I&#8217;d recommend going with <a href="http://devot-ee.com/add-ons/cx-disqus-comments">CX Disqus Comments</a> if you also run into problems.</p>

<h3>Step 2: get EE posts into Markdown files.</h3>

<p>Once again, somebody else did most of the work for me. This time it was Derek Jones with the <a href="https://github.com/EllisLab/download-content">Download Content</a> plugin for ExpressionEngine. I created a template that listed all my posts, each with a link that would download that post in a Markdown format I specified. I just command-clicked on each item (silly and effective) and ended up with a folder of posts ready for Statamic.</p>

<p><strong>post-list (template)</strong></p>

<pre>
{if member_group == 1}
{exp:channel:entries channel="blog" limit="999"}
<a href="/post-downloader/{entry_id}">{title}</a><br/>
{/exp:channel:entries}
{/if}
</pre>

<p><strong>post-downloader (template)<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup></strong></p>

<pre>
{if member_group == 1}
{exp:channel:entries channel="blog" limit="1" entry_id="{segment_2}"}
{exp:download_content filename="{entry_date format='%Y-%m-%d'}-{url_title}.md" parse="inward"}
---
title: "{title}"
featured: no
---

{blog-summary}
{blog-body}

{/exp:download_content}
{/exp:channel:entries}
{/if}
</pre>

<h3>Step 3: make that new theme.</h3>

<p>I copied &#8220;london-wild&#8221; and went to town with it. As you can guess from my site, half my work was just deleting things I didn&#8217;t use. Coming from EE, the theming process felt very familiar. Imagine ExpressionEngine with native Structure bits, but <a href="http://mustache.github.com/">mustachey</a>-looking.</p>

<p>The only sacrifices I had to make were dropping an email contact form (for now) and doing without numbered pagination.</p>

<h3>Step 4: consider the URLs.</h3>

<p>My blog posts went from /blog/entry/title to /blog/title, so I added a line to .htaccess for redirects:</p>

<pre>
Redirect 301 /blog/entry/ /blog/
</pre>

<p>Since I had only six pages of blog posts, I added quick-and-dirty redirects for EE&#8217;s pagination links too:</p>

<pre>
Redirect 301 /blog/P6 /blog?page=2
Redirect 301 /blog/P12 /blog?page=3
Redirect 301 /blog/P18 /blog?page=4
Redirect 301 /blog/P24 /blog?page=5
Redirect 301 /blog/P30 /blog?page=6
</pre>

<h3>Step 5: launch.</h3>

<p>The easiest part. Moved all the EE stuff into a doomed folder, dropped all my files right into the doc root via Git. And then I &#8230; here&#8217;s the thing &#8230; and then I was done. I hope you have a rocking time with Statamic too!</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>Note that my blog posts were previously split into two fields, <code>blog-summary</code> and <code>blog-body</code>. Yours will almost certainly be different.&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2012-10-12T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Retina Images]]></title>
      <link>http://workingconcept.com/blog/retina-images</link>
      <guid>http://workingconcept.com/blog/retina-images</guid>
      <content:encoded><![CDATA[<p>I noticed how poor the internet seemed to look on Apple&#8217;s retina iPad, and for whatever reason this new retina MacBook Pro seems to have more people focused on the issue of retina graphics and the internet. I happened upon two nice-looking solutions (<a href="http://retina-images.complexcompulsions.com/" target="_blank">Retina Images</a> and <a href="http://retinajs.com/" target="_blank">retina.js</a>) and implemented Retina Images on this site. I chose it over the latter because it serves the desired image once and works with CSS background images.</p>

<p>Retina Images gets the device pixel ratio and stores it in a cookie. Every image request is routed through a PHP file, which evaluates the cookie and whether a 2x image equivalent exists in the filesystem. The correct image is then returned. If any part of the process breaks (no cookies, for example), the original image is served. Pretty clever! The Retina Images site has <a href="http://retina-images.complexcompulsions.com/#setupserver" target="_blank">instructions for setup</a>, so all I have left are a few tips:</p>

<ol>
<li>Make sure your &#8220;@2x&#8221; images are exactly double the pixel dimensions (not the dpi).</li>
<li>Hope that your source Photoshop files use smart objects liberally. Bonus points for having them already snapped to the nearest pixel.</li>
<li>The Retina Images PHP file has a handy (and optional) debug log that you can switch on if things aren&#8217;t working out quite right.</li>
</ol>

<p>It seems likely that future specs will make room for device resolution, but Retina Images can at least take some of the ugly out of the internet today.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2012-06-21T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Mercurial on a MediaTemple DV 4 Server]]></title>
      <link>http://workingconcept.com/blog/mercurial-on-a-mediatemple-dv-4-server</link>
      <guid>http://workingconcept.com/blog/mercurial-on-a-mediatemple-dv-4-server</guid>
      <content:encoded><![CDATA[<p>I stick with package managers when I can. In this case, <code>yum</code> would do the trick but it isn&#8217;t aware of Mercurial by default. (Try <code>yum install mercurial</code> with a fresh DV4 and it won&#8217;t know what to do.) To help it out, we&#8217;ll add another catalog of sorts, called RPMforge, that it can search through. We just need to get the right catalog, load it up, and tell yum to install Mercurial again.</p>

<ol>
<li>Make sure you&#8217;ve got <a href="http://kb.mediatemple.net/questions/1564/Installing+YUM+on+a+%28dv%29+Dedicated-Virtual+Server#dv_40" target="_blank">yum installed</a> and your <a href="http://kb.mediatemple.net/questions/625/How+do+I+enable+root+access+to+my+%28dv%29%3F#dv" target="_blank">root access is enabled</a>.</li>
<li>SSH into your server as the root user.</li>
<li>Create a temporary folder <code>mkdir rpm-download</code>.</li>
<li>Get all up in that directory <code>cd rpm-download</code>.</li>
<li>Download the <a href="http://wiki.centos.org/AdditionalResources/Repositories/RPMForge" target="_blank">latest x86_64 RPMforge package for CentOS 5</a> <code>wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm</code>.</li>
<li>Add this repository to our search set <code>rpm -ivh rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm</code></li>
<li>Install Mercurial! <code>yum install mercurial</code></li>
<li>Make sure it worked <code>hg</code></li>
</ol>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2012-05-30T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Google Drive's Filesystem Icons: Ugly]]></title>
      <link>http://workingconcept.com/blog/google-drives-filesystem-icons-ugly</link>
      <guid>http://workingconcept.com/blog/google-drives-filesystem-icons-ugly</guid>
      <content:encoded><![CDATA[<p>Like every other foolish, bleeding-edge early adopter, I&#8217;ve just moved my entire Dropbox to a shiny new Google Drive folder. After <a href="http://blog.bolesuniversity.com/2012/04/27/how-to-fix-the-unable-to-sync-google-drive-error/" target="_blank">working out a few kinks</a> with non-syncing files, things are running smoothly and I&#8217;ll just need to wait on the iOS app and third-party integrations before I can safely say goodbye to Dropbox.</p>

<p>I&#8217;ve got only one complaint: the filesystem icons are a giant step backwards.</p>

<p><img src="/assets/img/blog/google-drive-vs-dropbox.png" width="170" height="100" alt="Icons: Google Drive vs. Dropbox" /></p>

<p>They&#8217;d fit nicely into Windows 95, but Dropbox did a much better job. I poked around in the Google Drive.app package hoping for some replaceable resource, but found no way to change them. I&#8217;m sure that Google&#8217;s teams frequent my blog, so I&#8217;ll kindly ask that someone address this. Then, of course, get on to the LAN syncing and bandwidth tuning.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2012-04-27T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[A Brief Moment of Clarity]]></title>
      <link>http://workingconcept.com/blog/a-brief-moment-of-clarity</link>
      <guid>http://workingconcept.com/blog/a-brief-moment-of-clarity</guid>
      <content:encoded><![CDATA[<h4>What do I do again?</h4>

<p>I love solving problems, I&#8217;m fascinated with the web, technology, and putting things together that can make people&#8217;s lives better in some way. I&#8217;m used to wearing a lot of hats, and I like it that way, but I&#8217;m constantly forced to choose between focusing on one or two things to be really good at, or chasing a whole bunch of interests at the expense of never being The Expert at any of them.</p>

<p>A smart person I used to work for told me that the work I take will be the kind of work I keep getting. To my unamazement, this has proved true. I&#8217;ve learned that low-budget, ASAP projects where I&#8217;d occupy a narrow role are the worst to take on. They offer the most stress for the least pay and tend to be a drain on everyone involved. On the other hand, I work extremely well in situations where I&#8217;m the glue; there&#8217;s a big, undefined problem that needs to be identified, solved, and executed. It may involve translating between people with different interests and skill sets, or helping a small client solve big problems on a small budget. It may mean researching and building some weirdly-specific thing that nobody else could figure out how to do. I love this stuff, partly because I&#8217;m hardwired to take pleasure in organizing things, and partly because the conversations and relationships involved are engaging and interesting.</p>

<h4>And Then There Were Answers</h4>

<p>Through trial and error, I&#8217;ve finally started to figure out where my interests and abilities overlap. This makes it infinitely easier to know how to choose projects and who I&#8217;m looking for to collaborate with.</p>

<p>Things I know now&#8230;</p>

<p><strong>I&#8217;m a good designer and a lousy artist.</strong></p>

<p>You can argue that there&#8217;s overlap between the two, and I&#8217;ll agree to some extent. But I&#8217;m convinced that a designer is a person who solves problems, and an artist is a person who creates (or at least observes and interprets if you&#8217;re in the &#8220;nothing is new&#8221; camp).</p>

<p><strong>Reliability is something I sell.</strong></p>

<p>I want to be the person with the killer Dribbble feed, or the eagle-eyed pro that spots new trends before they&#8217;re big. But I&#8217;m neither. One of my most useful traits isn&#8217;t sexy or even all that interesting: I do what I say I will, when I&#8217;ve said I&#8217;ll do it. I try and communicate clearly, spell and punctuate like I give a damn, and actively take ownership of any mistakes while doing whatever I can to make them right. I&#8217;ve learned that, despite being hopelessly dull, this is a desirable trait.</p>

<p><strong>Work does not happen in a vacuum.</strong></p>

<p>I spend an awful lot of time at a desk by myself, and sometimes fall into the trap of believing that I work on my own. The reality, however, is that every project I work on is the result of a process, often with lots of focused communication. A huge part of what I do is to cultivate relationships that allow for efficient problem solving, be it with clients, collaborators, or both.</p>

<p><strong>My spirit animal is a stodgy old man.</strong></p>

<p>I can&#8217;t help it: I think that capitalization, punctuation, spelling, and grammar count for something. I don&#8217;t think Facebook, Twitter, or many newfangled ways to communicate make thoughtful communication obsolete. Intentionally crappy drawings don&#8217;t impress me, regardless of what the hipster holding the poster looks like. Maybe I&#8217;m drawn to things that seem inherently well-considered. Maybe I&#8217;m just a jerk.</p>

<h4>The Inevitable Redesign</h4>

<p>With these realizations, and even before articulating them, I decided it was time to redesign my tiny website. The old site, despite being tiny as well, was wasting time spreading a minimal amount of content over a few pages, and started using silly visual motifs that were more whim than anything else. So I did what felt right: focused, simplified, and made sure that design, responsiveness, and page load times would support the myriad of browsers and devices that could end up at my humble little domain. Caslon feels way more appropriate for me than Museo ever did. And as fun as it is to add excessive textures and faux embossing to type, it&#8217;s just not me. I&#8217;m also not bold enough to build a site without a stylesheet altogether. I only considered it in the moment while writing, but I suppose I&#8217;m not purist enough to take it that far.</p>

<h4>End of Post</h4>

<p>I&#8217;m not sure that this post will be meaningful for anyone but me, but it feels important to leave a note for my future self that says, &#8220;remember you&#8217;ve been learning things.&#8221; After all, no matter what I end up doing next, no matter how wonderfully or terribly it goes, I can take pride in having learned things and helped people solve problems.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2012-02-27T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[HostGator Does Not Support IPv6]]></title>
      <link>http://workingconcept.com/blog/hostgator-does-not-support-ipv6</link>
      <guid>http://workingconcept.com/blog/hostgator-does-not-support-ipv6</guid>
      <content:encoded><![CDATA[<p>After <a href="/blog/cloudflare-review-bad-logo-amazing-service">getting really excited about CloudFlare</a>, I was setting it up for a client&#8217;s WordPress site when it disappeared during a DNS update. The CloudFlare-served error told me that the web host wasn&#8217;t serving data to web traffic, which seemed odd.</p>

<p>The web host was <a href="http://www.hostgator.com/" target="_blank">HostGator</a> (shared reseller account), and a chat technician confirmed my suspicion: they do not (yet) support IPv6 mapping that CloudFlare provides. So if you&#8217;ve enabled the IPv6 feature from CloudFlare&#8217;s settings and your site suddenly disappears, make sure your host supports the IPv6 protocol. Disabling the feature (it&#8217;s just a feature you can disable!!) restored the blog to its happy former state. That is all.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2011-10-13T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[CloudFlare Review: Bad Logo, Amazing Service]]></title>
      <link>http://workingconcept.com/blog/cloudflare-review-bad-logo-amazing-service</link>
      <guid>http://workingconcept.com/blog/cloudflare-review-bad-logo-amazing-service</guid>
      <content:encoded><![CDATA[<p>I host several projects on <a href="http://mediatemple.net/webhosting/dv/" target="_blank">MediaTemple DV plans</a> for the stability, flexibility, and top-notch support. (I&#8217;d rather not be troubleshooting server issues for clients at 3AM.) You can certainly use <a href="http://www.cloudflare.com" target="_blank">CloudFlare</a> without MediaTemple hosting, they&#8217;ve just made it a one-step add-on service that you&#8217;d have to be a drooling idiot to mess up. I warily enabled the service for a static site, which involved signing up for a free account (email address, password) and enabling the service in MediaTemple&#8217;s control panel. A CNAME record was automatically created in the DNS settings, and that&#8217;s it.</p>

<p>I visited said site and it had an immediately-noticable zing. Excitedly, I added the service to workingconcept.com to see how <a href="http://www.cloudflare.com" target="_blank">CloudFlare</a> would cripple the ExpressionEngine setup. I was sure it&#8217;d fail and I&#8217;d have to revert, but I tried it anyway. <strong>I was blown away – CloudFlare seemed to have absolutely no effect but to dramatically speed up page delivery.</strong> Below is my non-scientific evaluation&#8230;</p>

<h4><a href="http://just-ping.com" target="_blank">just-ping.com</a> results, before CloudFlare (MediaTemple DV4.0, Virginia datacenter)</h4>

<table cellspacing="0" cellpadding="0" border="0" width="100%">
    <tbody>
        <tr class="head">
            <td>
                <strong>Location</strong>
            </td>
            <td>
                <strong>min. rrt</strong>
            </td>
            <td>
                <strong>avg. rrt</strong>
            </td>
            <td>
                <strong>max. rrt</strong>
            </td>
            <td>
                <strong>IP</strong>
            </td>
        </tr>
        <tr>
            <td>
                Singapore, Singapore:
            </td>
            <td>
                <span id="minrrt2">262.2</span>
            </td>
            <td>
                <span id="avgrrt2">270.5</span>
            </td>
            <td>
                <span id="maxrrt2">286.5</span>
            </td>
            <td>
                <span id="ip2">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Amsterdam2, Netherlands:
            </td>
            <td>
                <span id="minrrt4">84.7</span>
            </td>
            <td>
                <span id="avgrrt4">85.1</span>
            </td>
            <td>
                <span id="maxrrt4">87.5</span>
            </td>
            <td>
                <span id="ip4">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Florida, U.S.A.:
            </td>
            <td>
                <span id="minrrt9">25.9</span>
            </td>
            <td>
                <span id="avgrrt9">26.0</span>
            </td>
            <td>
                <span id="maxrrt9">26.2</span>
            </td>
            <td>
                <span id="ip9">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Amsterdam3, Netherlands:
            </td>
            <td>
                <span id="minrrt11">84.4</span>
            </td>
            <td>
                <span id="avgrrt11">85.2</span>
            </td>
            <td>
                <span id="maxrrt11">90.5</span>
            </td>
            <td>
                <span id="ip11">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Hong Kong, China:
            </td>
            <td>
                <span id="minrrt12">233.3</span>
            </td>
            <td>
                <span id="avgrrt12">235.8</span>
            </td>
            <td>
                <span id="maxrrt12">237.3</span>
            </td>
            <td>
                <span id="ip12">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Sydney, Australia:
            </td>
            <td>
                <span id="minrrt14">233.8</span>
            </td>
            <td>
                <span id="avgrrt14">234.0</span>
            </td>
            <td>
                <span id="maxrrt14">234.2</span>
            </td>
            <td>
                <span id="ip14">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Munchen, Germany:
            </td>
            <td>
                <span id="minrrt15">96.4</span>
            </td>
            <td>
                <span id="avgrrt15">96.5</span>
            </td>
            <td>
                <span id="maxrrt15">96.7</span>
            </td>
            <td>
                <span id="ip15">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Cologne, Germany:
            </td>
            <td>
                <span id="minrrt16">86.6</span>
            </td>
            <td>
                <span id="avgrrt16">86.7</span>
            </td>
            <td>
                <span id="maxrrt16">86.7</span>
            </td>
            <td>
                <span id="ip16">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                New York, U.S.A.:
            </td>
            <td>
                <span id="minrrt18">10.0</span>
            </td>
            <td>
                <span id="avgrrt18">10.1</span>
            </td>
            <td>
                <span id="maxrrt18">10.2</span>
            </td>
            <td>
                <span id="ip18">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Amsterdam1, Netherlands:
            </td>
            <td>
                <span id="minrrt122">88.6</span>
            </td>
            <td>
                <span id="avgrrt122">88.6</span>
            </td>
            <td>
                <span id="maxrrt122">88.7</span>
            </td>
            <td>
                <span id="ip122">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Stockholm, Sweden:
            </td>
            <td>
                <span id="minrrt20">118.6</span>
            </td>
            <td>
                <span id="avgrrt20">118.7</span>
            </td>
            <td>
                <span id="maxrrt20">118.8</span>
            </td>
            <td>
                <span id="ip20">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Santa Clara, U.S.A.:
            </td>
            <td>
                <span id="minrrt21">88.2</span>
            </td>
            <td>
                <span id="avgrrt21">88.7</span>
            </td>
            <td>
                <span id="maxrrt21">89.2</span>
            </td>
            <td>
                <span id="ip21">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Vancouver, Canada:
            </td>
            <td>
                <span id="minrrt22">87.7</span>
            </td>
            <td>
                <span id="avgrrt22">87.9</span>
            </td>
            <td>
                <span id="maxrrt22">88.2</span>
            </td>
            <td>
                <span id="ip22">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                London, United Kingdom:
            </td>
            <td>
                <span id="minrrt26">78.5</span>
            </td>
            <td>
                <span id="avgrrt26">79.0</span>
            </td>
            <td>
                <span id="maxrrt26">79.3</span>
            </td>
            <td>
                <span id="ip26">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Madrid, Spain:
            </td>
            <td>
                <span id="minrrt28">132.1</span>
            </td>
            <td>
                <span id="avgrrt28">150.2</span>
            </td>
            <td>
                <span id="maxrrt28">167.5</span>
            </td>
            <td>
                <span id="ip28">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Padova, Italy:
            </td>
            <td>
                <span id="minrrt29">107.3</span>
            </td>
            <td>
                <span id="avgrrt29">107.7</span>
            </td>
            <td>
                <span id="maxrrt29">109.0</span>
            </td>
            <td>
                <span id="ip29">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Austin, U.S.A.:
            </td>
            <td>
                <span id="minrrt30">58.1</span>
            </td>
            <td>
                <span id="avgrrt30">58.3</span>
            </td>
            <td>
                <span id="maxrrt30">58.6</span>
            </td>
            <td>
                <span id="ip30">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Amsterdam, Netherlands:
            </td>
            <td>
                <span id="minrrt31">85.6</span>
            </td>
            <td>
                <span id="avgrrt31">85.7</span>
            </td>
            <td>
                <span id="maxrrt31">85.9</span>
            </td>
            <td>
                <span id="ip31">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Paris, France:
            </td>
            <td>
                <span id="minrrt32">98.8</span>
            </td>
            <td>
                <span id="avgrrt32">99.0</span>
            </td>
            <td>
                <span id="maxrrt32">99.1</span>
            </td>
            <td>
                <span id="ip32">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Melbourne, Australia:
            </td>
            <td>
                <span id="minrrt34">254.3</span>
            </td>
            <td>
                <span id="avgrrt34">255.1</span>
            </td>
            <td>
                <span id="maxrrt34">256.4</span>
            </td>
            <td>
                <span id="ip34">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Shanghai, China:
            </td>
            <td>
                <span id="minrrt33">208.2</span>
            </td>
            <td>
                <span id="avgrrt33">208.5</span>
            </td>
            <td>
                <span id="maxrrt33">208.7</span>
            </td>
            <td>
                <span id="ip33">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Copenhagen, Denmark:
            </td>
            <td>
                <span id="minrrt38">108.1</span>
            </td>
            <td>
                <span id="avgrrt38">108.2</span>
            </td>
            <td>
                <span id="maxrrt38">108.4</span>
            </td>
            <td>
                <span id="ip38">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Lille, France:
            </td>
            <td>
                <span id="minrrt42">82.4</span>
            </td>
            <td>
                <span id="avgrrt42">86.8</span>
            </td>
            <td>
                <span id="maxrrt42">93.1</span>
            </td>
            <td>
                <span id="ip42">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Zurich, Switzerland:
            </td>
            <td>
                <span id="minrrt50">108.5</span>
            </td>
            <td>
                <span id="avgrrt50">108.7</span>
            </td>
            <td>
                <span id="maxrrt50">109.1</span>
            </td>
            <td>
                <span id="ip50">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Mumbai, India:
            </td>
            <td>
                <span id="minrrt54">192.6</span>
            </td>
            <td>
                <span id="avgrrt54">203.0</span>
            </td>
            <td>
                <span id="maxrrt54">227.3</span>
            </td>
            <td>
                <span id="ip54">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Chicago, U.S.A.:
            </td>
            <td>
                <span id="minrrt58">32.3</span>
            </td>
            <td>
                <span id="avgrrt58">32.4</span>
            </td>
            <td>
                <span id="maxrrt58">32.9</span>
            </td>
            <td>
                <span id="ip58">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Nagano, Japan:
            </td>
            <td>
                <span id="minrrt70">177.3</span>
            </td>
            <td>
                <span id="avgrrt70">177.3</span>
            </td>
            <td>
                <span id="maxrrt70">177.5</span>
            </td>
            <td>
                <span id="ip70">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Haifa, Israel:
            </td>
            <td>
                <span id="minrrt74">149.6</span>
            </td>
            <td>
                <span id="avgrrt74">150.9</span>
            </td>
            <td>
                <span id="maxrrt74">153.3</span>
            </td>
            <td>
                <span id="ip74">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Auckland, New Zealand:
            </td>
            <td>
                <span id="minrrt78">200.2</span>
            </td>
            <td>
                <span id="avgrrt78">205.7</span>
            </td>
            <td>
                <span id="maxrrt78">218.4</span>
            </td>
            <td>
                <span id="ip78">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Antwerp, Belgium:
            </td>
            <td>
                <span id="minrrt82">92.4</span>
            </td>
            <td>
                <span id="avgrrt82">92.5</span>
            </td>
            <td>
                <span id="maxrrt82">92.8</span>
            </td>
            <td>
                <span id="ip82">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Groningen, Netherlands:
            </td>
            <td>
                <span id="minrrt86">87.7</span>
            </td>
            <td>
                <span id="avgrrt86">88.0</span>
            </td>
            <td>
                <span id="maxrrt86">88.7</span>
            </td>
            <td>
                <span id="ip86">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Moscow, Russia:
            </td>
            <td>
                <span id="minrrt87">136.4</span>
            </td>
            <td>
                <span id="avgrrt87">136.6</span>
            </td>
            <td>
                <span id="maxrrt87">136.9</span>
            </td>
            <td>
                <span id="ip87">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Dublin, Ireland:
            </td>
            <td>
                <span id="minrrt91">97.6</span>
            </td>
            <td>
                <span id="avgrrt91">97.6</span>
            </td>
            <td>
                <span id="maxrrt91">97.7</span>
            </td>
            <td>
                <span id="ip91">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Oslo, Norway:
            </td>
            <td>
                <span id="minrrt93">112.6</span>
            </td>
            <td>
                <span id="avgrrt93">115.2</span>
            </td>
            <td>
                <span id="maxrrt93">136.7</span>
            </td>
            <td>
                <span id="ip93">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Kharkov, Ukraine:
            </td>
            <td>
                <span id="minrrt96">156.0</span>
            </td>
            <td>
                <span id="avgrrt96">156.4</span>
            </td>
            <td>
                <span id="maxrrt96">160.0</span>
            </td>
            <td>
                <span id="ip96">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Manchester, United Kingdom:
            </td>
            <td>
                <span id="minrrt98">80.1</span>
            </td>
            <td>
                <span id="avgrrt98">80.4</span>
            </td>
            <td>
                <span id="maxrrt98">82.2</span>
            </td>
            <td>
                <span id="ip98">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Vilnius, Lithuania:
            </td>
            <td>
                <span id="minrrt100">119.1</span>
            </td>
            <td>
                <span id="avgrrt100">119.3</span>
            </td>
            <td>
                <span id="maxrrt100">119.6</span>
            </td>
            <td>
                <span id="ip100">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Bucharest, Romania:
            </td>
            <td>
                <span id="minrrt103">132.8</span>
            </td>
            <td>
                <span id="avgrrt103">133.0</span>
            </td>
            <td>
                <span id="maxrrt103">133.2</span>
            </td>
            <td>
                <span id="ip103">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Kuala Lumpur, Malaysia:
            </td>
            <td>
                <span id="minrrt107">253.4</span>
            </td>
            <td>
                <span id="avgrrt107">253.7</span>
            </td>
            <td>
                <span id="maxrrt107">254.0</span>
            </td>
            <td>
                <span id="ip107">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Jakarta, Indonesia:
            </td>
            <td>
                <span id="minrrt109">283.9</span>
            </td>
            <td>
                <span id="avgrrt109">284.7</span>
            </td>
            <td>
                <span id="maxrrt109">290.6</span>
            </td>
            <td>
                <span id="ip109">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Cape Town, South Africa:
            </td>
            <td>
                <span id="minrrt111">226.1</span>
            </td>
            <td>
                <span id="avgrrt111">226.2</span>
            </td>
            <td>
                <span id="maxrrt111">226.3</span>
            </td>
            <td>
                <span id="ip111">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Glasgow, United Kingdom:
            </td>
            <td>
                <span id="minrrt113">85.4</span>
            </td>
            <td>
                <span id="avgrrt113">86.8</span>
            </td>
            <td>
                <span id="maxrrt113">97.6</span>
            </td>
            <td>
                <span id="ip113">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Lisbon, Portugal:
            </td>
            <td>
                <span id="minrrt115">117.6</span>
            </td>
            <td>
                <span id="avgrrt115">117.7</span>
            </td>
            <td>
                <span id="maxrrt115">117.7</span>
            </td>
            <td>
                <span id="ip115">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Chicago, U.S.A.:
            </td>
            <td>
                <span id="minrrt117">31.3</span>
            </td>
            <td>
                <span id="avgrrt117">31.4</span>
            </td>
            <td>
                <span id="maxrrt117">31.5</span>
            </td>
            <td>
                <span id="ip117">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Dallas, U.S.A.:
            </td>
            <td>
                <span id="minrrt119">35.5</span>
            </td>
            <td>
                <span id="avgrrt119">35.7</span>
            </td>
            <td>
                <span id="maxrrt119">36.1</span>
            </td>
            <td>
                <span id="ip119">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Buenos Aires, Argentina:
            </td>
            <td>
                <span id="minrrt124">156.6</span>
            </td>
            <td>
                <span id="avgrrt124">156.9</span>
            </td>
            <td>
                <span id="maxrrt124">157.2</span>
            </td>
            <td>
                <span id="ip124">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Istanbul, Turkey:
            </td>
            <td>
                <span id="minrrt126">137.5</span>
            </td>
            <td>
                <span id="avgrrt126">137.7</span>
            </td>
            <td>
                <span id="maxrrt126">138.1</span>
            </td>
            <td>
                <span id="ip126">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Gdansk, Poland:
            </td>
            <td>
                <span id="minrrt128">114.5</span>
            </td>
            <td>
                <span id="avgrrt128">116.2</span>
            </td>
            <td>
                <span id="maxrrt128">128.9</span>
            </td>
            <td>
                <span id="ip128">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Beijing, China:
            </td>
            <td>
                <span id="minrrt130">295.4</span>
            </td>
            <td>
                <span id="avgrrt130">307.4</span>
            </td>
            <td>
                <span id="maxrrt130">314.7</span>
            </td>
            <td>
                <span id="ip130">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Belgrade, Serbia:
            </td>
            <td>
                <span id="minrrt132">113.8</span>
            </td>
            <td>
                <span id="avgrrt132">118.4</span>
            </td>
            <td>
                <span id="maxrrt132">137.8</span>
            </td>
            <td>
                <span id="ip132">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Toronto, Canada:
            </td>
            <td>
                <span id="minrrt137">22.5</span>
            </td>
            <td>
                <span id="avgrrt137">22.8</span>
            </td>
            <td>
                <span id="maxrrt137">23.1</span>
            </td>
            <td>
                <span id="ip137">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Novosibirsk, Russia:
            </td>
            <td>
                <span id="minrrt141">190.3</span>
            </td>
            <td>
                <span id="avgrrt141">191.3</span>
            </td>
            <td>
                <span id="maxrrt141">192.1</span>
            </td>
            <td>
                <span id="ip141">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Athens, Greece:
            </td>
            <td>
                <span id="minrrt147">135.3</span>
            </td>
            <td>
                <span id="avgrrt147">135.7</span>
            </td>
            <td>
                <span id="maxrrt147">136.9</span>
            </td>
            <td>
                <span id="ip147">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Frankfurt, Germany:
            </td>
            <td>
                <span id="minrrt149">92.5</span>
            </td>
            <td>
                <span id="avgrrt149">93.4</span>
            </td>
            <td>
                <span id="maxrrt149">94.9</span>
            </td>
            <td>
                <span id="ip149">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Sofia, Bulgaria:
            </td>
            <td>
                <span id="minrrt151">118.4</span>
            </td>
            <td>
                <span id="avgrrt151">118.8</span>
            </td>
            <td>
                <span id="maxrrt151">119.4</span>
            </td>
            <td>
                <span id="ip151">72.10.32.198</span>
            </td>
        </tr>
        <tr>
            <td>
                Budapest, Hungary:
            </td>
            <td>
                <span id="minrrt153">109.8</span>
            </td>
            <td>
                <span id="avgrrt153">114.0</span>
            </td>
            <td>
                <span id="maxrrt153">127.4</span>
            </td>
            <td>
                <span id="ip153">72.10.32.198</span>
            </td>
        </tr>
    </tbody>
</table>

<h3><a href="http://just-ping.com" target="_blank">just-ping.com</a> results, with CloudFlare</h3>

<table cellspacing="0" cellpadding="0" border="0" width="100%">
    <tbody>
        <tr>
            <td><strong>Location</strong></td>
            <td><strong>min. rrt</strong></td>
            <td><strong>avg. rrt</strong></td>
            <td><strong>max. rrt</strong></td>
            <td><strong>IP</strong></td>
        </tr>
        <tr>
            <td>
                Singapore, Singapore:
            </td>
            <td>
                <span id="minrrt2">176.3</span>
            </td>
            <td>
                <span id="avgrrt2">186.3</span>
            </td>
            <td>
                <span id="maxrrt2">193.1</span>
            </td>
            <td>
                <span id="ip2">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Amsterdam2, Netherlands:
            </td>
            <td>
                <span id="minrrt4">1.2</span>
            </td>
            <td>
                <span id="avgrrt4">1.5</span>
            </td>
            <td>
                <span id="maxrrt4">1.7</span>
            </td>
            <td>
                <span id="ip4">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Florida, U.S.A.:
            </td>
            <td>
                <span id="minrrt9">26.7</span>
            </td>
            <td>
                <span id="avgrrt9">27.0</span>
            </td>
            <td>
                <span id="maxrrt9">27.5</span>
            </td>
            <td>
                <span id="ip9">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Amsterdam3, Netherlands:
            </td>
            <td>
                <span id="minrrt11">0.7</span>
            </td>
            <td>
                <span id="avgrrt11">1.0</span>
            </td>
            <td>
                <span id="maxrrt11">1.2</span>
            </td>
            <td>
                <span id="ip11">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Hong Kong, China:
            </td>
            <td>
                <span id="minrrt12">2.1</span>
            </td>
            <td>
                <span id="avgrrt12">2.5</span>
            </td>
            <td>
                <span id="maxrrt12">3.2</span>
            </td>
            <td>
                <span id="ip12">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Sydney, Australia:
            </td>
            <td>
                <span id="minrrt14">157.2</span>
            </td>
            <td>
                <span id="avgrrt14">157.6</span>
            </td>
            <td>
                <span id="maxrrt14">158.4</span>
            </td>
            <td>
                <span id="ip14">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Munchen, Germany:
            </td>
            <td>
                <span id="minrrt15">19.1</span>
            </td>
            <td>
                <span id="avgrrt15">19.3</span>
            </td>
            <td>
                <span id="maxrrt15">20.0</span>
            </td>
            <td>
                <span id="ip15">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Cologne, Germany:
            </td>
            <td>
                <span id="minrrt16">4.8</span>
            </td>
            <td>
                <span id="avgrrt16">5.1</span>
            </td>
            <td>
                <span id="maxrrt16">5.3</span>
            </td>
            <td>
                <span id="ip16">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                New York, U.S.A.:
            </td>
            <td>
                <span id="minrrt18">4.9</span>
            </td>
            <td>
                <span id="avgrrt18">5.1</span>
            </td>
            <td>
                <span id="maxrrt18">5.3</span>
            </td>
            <td>
                <span id="ip18">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Amsterdam1, Netherlands:
            </td>
            <td>
                <span id="minrrt122">0.7</span>
            </td>
            <td>
                <span id="avgrrt122">1.0</span>
            </td>
            <td>
                <span id="maxrrt122">1.4</span>
            </td>
            <td>
                <span id="ip122">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Stockholm, Sweden:
            </td>
            <td>
                <span id="minrrt20">24.6</span>
            </td>
            <td>
                <span id="avgrrt20">25.0</span>
            </td>
            <td>
                <span id="maxrrt20">25.5</span>
            </td>
            <td>
                <span id="ip20">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Santa Clara, U.S.A.:
            </td>
            <td>
                <span id="minrrt21">3.5</span>
            </td>
            <td>
                <span id="avgrrt21">3.9</span>
            </td>
            <td>
                <span id="maxrrt21">4.2</span>
            </td>
            <td>
                <span id="ip21">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Vancouver, Canada:
            </td>
            <td>
                <span id="minrrt22">75.4</span>
            </td>
            <td>
                <span id="avgrrt22">76.3</span>
            </td>
            <td>
                <span id="maxrrt22">77.8</span>
            </td>
            <td>
                <span id="ip22">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                London, United Kingdom:
            </td>
            <td>
                <span id="minrrt26">10.3</span>
            </td>
            <td>
                <span id="avgrrt26">10.7</span>
            </td>
            <td>
                <span id="maxrrt26">11.0</span>
            </td>
            <td>
                <span id="ip26">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Madrid, Spain:
            </td>
            <td>
                <span id="minrrt28">34.6</span>
            </td>
            <td>
                <span id="avgrrt28">38.4</span>
            </td>
            <td>
                <span id="maxrrt28">49.1</span>
            </td>
            <td>
                <span id="ip28">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Padova, Italy:
            </td>
            <td>
                <span id="minrrt29">26.1</span>
            </td>
            <td>
                <span id="avgrrt29">32.1</span>
            </td>
            <td>
                <span id="maxrrt29">57.8</span>
            </td>
            <td>
                <span id="ip29">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Austin, U.S.A.:
            </td>
            <td>
                <span id="minrrt30">29.7</span>
            </td>
            <td>
                <span id="avgrrt30">29.9</span>
            </td>
            <td>
                <span id="maxrrt30">30.0</span>
            </td>
            <td>
                <span id="ip30">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Amsterdam, Netherlands:
            </td>
            <td>
                <span id="minrrt31">0.9</span>
            </td>
            <td>
                <span id="avgrrt31">1.1</span>
            </td>
            <td>
                <span id="maxrrt31">1.6</span>
            </td>
            <td>
                <span id="ip31">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Paris, France:
            </td>
            <td>
                <span id="minrrt32">90.5</span>
            </td>
            <td>
                <span id="avgrrt32">91.0</span>
            </td>
            <td>
                <span id="maxrrt32">91.9</span>
            </td>
            <td>
                <span id="ip32">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Melbourne, Australia:
            </td>
            <td>
                <span id="minrrt34">123.9</span>
            </td>
            <td>
                <span id="avgrrt34">124.8</span>
            </td>
            <td>
                <span id="maxrrt34">126.3</span>
            </td>
            <td>
                <span id="ip34">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Shanghai, China:
            </td>
            <td>
                <span id="minrrt33">267.0</span>
            </td>
            <td>
                <span id="avgrrt33">273.3</span>
            </td>
            <td>
                <span id="maxrrt33">278.1</span>
            </td>
            <td>
                <span id="ip33">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Copenhagen, Denmark:
            </td>
            <td>
                <span id="minrrt38">15.6</span>
            </td>
            <td>
                <span id="avgrrt38">16.5</span>
            </td>
            <td>
                <span id="maxrrt38">17.3</span>
            </td>
            <td>
                <span id="ip38">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Lille, France:
            </td>
            <td>
                <span id="minrrt42">17.2</span>
            </td>
            <td>
                <span id="avgrrt42">26.8</span>
            </td>
            <td>
                <span id="maxrrt42">33.1</span>
            </td>
            <td>
                <span id="ip42">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Zurich, Switzerland:
            </td>
            <td>
                <span id="minrrt50">14.5</span>
            </td>
            <td>
                <span id="avgrrt50">14.8</span>
            </td>
            <td>
                <span id="maxrrt50">15.2</span>
            </td>
            <td>
                <span id="ip50">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Mumbai, India:
            </td>
            <td>
                <span id="minrrt54">76.4</span>
            </td>
            <td>
                <span id="avgrrt54">77.0</span>
            </td>
            <td>
                <span id="maxrrt54">77.7</span>
            </td>
            <td>
                <span id="ip54">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Chicago, U.S.A.:
            </td>
            <td>
                <span id="minrrt58">0.3</span>
            </td>
            <td>
                <span id="avgrrt58">0.4</span>
            </td>
            <td>
                <span id="maxrrt58">0.6</span>
            </td>
            <td>
                <span id="ip58">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Nagano, Japan:
            </td>
            <td>
                <span id="minrrt70">6.0</span>
            </td>
            <td>
                <span id="avgrrt70">6.1</span>
            </td>
            <td>
                <span id="maxrrt70">6.4</span>
            </td>
            <td>
                <span id="ip70">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Haifa, Israel:
            </td>
            <td>
                <span id="minrrt74">91.1</span>
            </td>
            <td>
                <span id="avgrrt74">96.7</span>
            </td>
            <td>
                <span id="maxrrt74">100.4</span>
            </td>
            <td>
                <span id="ip74">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Auckland, New Zealand:
            </td>
            <td>
                <span id="minrrt78">149.9</span>
            </td>
            <td>
                <span id="avgrrt78">150.1</span>
            </td>
            <td>
                <span id="maxrrt78">150.4</span>
            </td>
            <td>
                <span id="ip78">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Antwerp, Belgium:
            </td>
            <td>
                <span id="minrrt82">11.0</span>
            </td>
            <td>
                <span id="avgrrt82">11.3</span>
            </td>
            <td>
                <span id="maxrrt82">11.8</span>
            </td>
            <td>
                <span id="ip82">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Groningen, Netherlands:
            </td>
            <td>
                <span id="minrrt86">4.4</span>
            </td>
            <td>
                <span id="avgrrt86">5.0</span>
            </td>
            <td>
                <span id="maxrrt86">5.6</span>
            </td>
            <td>
                <span id="ip86">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Moscow, Russia:
            </td>
            <td>
                <span id="minrrt87">46.4</span>
            </td>
            <td>
                <span id="avgrrt87">46.7</span>
            </td>
            <td>
                <span id="maxrrt87">47.1</span>
            </td>
            <td>
                <span id="ip87">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Dublin, Ireland:
            </td>
            <td>
                <span id="minrrt91">18.7</span>
            </td>
            <td>
                <span id="avgrrt91">18.9</span>
            </td>
            <td>
                <span id="maxrrt91">19.3</span>
            </td>
            <td>
                <span id="ip91">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Oslo, Norway:
            </td>
            <td>
                <span id="minrrt93">32.0</span>
            </td>
            <td>
                <span id="avgrrt93">32.2</span>
            </td>
            <td>
                <span id="maxrrt93">32.6</span>
            </td>
            <td>
                <span id="ip93">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Kharkov, Ukraine:
            </td>
            <td>
                <span id="minrrt96">104.0</span>
            </td>
            <td>
                <span id="avgrrt96">104.4</span>
            </td>
            <td>
                <span id="maxrrt96">108.0</span>
            </td>
            <td>
                <span id="ip96">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Manchester, United Kingdom:
            </td>
            <td>
                <span id="minrrt98">13.2</span>
            </td>
            <td>
                <span id="avgrrt98">13.8</span>
            </td>
            <td>
                <span id="maxrrt98">14.4</span>
            </td>
            <td>
                <span id="ip98">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Vilnius, Lithuania:
            </td>
            <td>
                <span id="minrrt100">36.5</span>
            </td>
            <td>
                <span id="avgrrt100">37.4</span>
            </td>
            <td>
                <span id="maxrrt100">42.1</span>
            </td>
            <td>
                <span id="ip100">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Bucharest, Romania:
            </td>
            <td>
                <span id="minrrt103">35.2</span>
            </td>
            <td>
                <span id="avgrrt103">36.1</span>
            </td>
            <td>
                <span id="maxrrt103">41.9</span>
            </td>
            <td>
                <span id="ip103">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Kuala Lumpur, Malaysia:
            </td>
            <td>
                <span id="minrrt107">195.6</span>
            </td>
            <td>
                <span id="avgrrt107">196.1</span>
            </td>
            <td>
                <span id="maxrrt107">197.1</span>
            </td>
            <td>
                <span id="ip107">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Jakarta, Indonesia:
            </td>
            <td>
                <span id="minrrt109">48.6</span>
            </td>
            <td>
                <span id="avgrrt109">48.9</span>
            </td>
            <td>
                <span id="maxrrt109">49.3</span>
            </td>
            <td>
                <span id="ip109">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Cape Town, South Africa:
            </td>
            <td>
                <span id="minrrt111">231.4</span>
            </td>
            <td>
                <span id="avgrrt111">231.7</span>
            </td>
            <td>
                <span id="maxrrt111">232.1</span>
            </td>
            <td>
                <span id="ip111">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Glasgow, United Kingdom:
            </td>
            <td>
                <span id="minrrt113">20.7</span>
            </td>
            <td>
                <span id="avgrrt113">20.9</span>
            </td>
            <td>
                <span id="maxrrt113">21.3</span>
            </td>
            <td>
                <span id="ip113">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Lisbon, Portugal:
            </td>
            <td>
                <span id="minrrt115">58.8</span>
            </td>
            <td>
                <span id="avgrrt115">59.1</span>
            </td>
            <td>
                <span id="maxrrt115">59.5</span>
            </td>
            <td>
                <span id="ip115">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Chicago, U.S.A.:
            </td>
            <td>
                <span id="minrrt117">1.7</span>
            </td>
            <td>
                <span id="avgrrt117">2.0</span>
            </td>
            <td>
                <span id="maxrrt117">2.3</span>
            </td>
            <td>
                <span id="ip117">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Dallas, U.S.A.:
            </td>
            <td>
                <span id="minrrt119">1.3</span>
            </td>
            <td>
                <span id="avgrrt119">1.5</span>
            </td>
            <td>
                <span id="maxrrt119">2.0</span>
            </td>
            <td>
                <span id="ip119">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Buenos Aires, Argentina:
            </td>
            <td>
                <span id="minrrt124">152.6</span>
            </td>
            <td>
                <span id="avgrrt124">153.2</span>
            </td>
            <td>
                <span id="maxrrt124">156.3</span>
            </td>
            <td>
                <span id="ip124">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Istanbul, Turkey:
            </td>
            <td>
                <span id="minrrt126">38.8</span>
            </td>
            <td>
                <span id="avgrrt126">39.2</span>
            </td>
            <td>
                <span id="maxrrt126">39.7</span>
            </td>
            <td>
                <span id="ip126">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Gdansk, Poland:
            </td>
            <td>
                <span id="minrrt128">42.0</span>
            </td>
            <td>
                <span id="avgrrt128">42.2</span>
            </td>
            <td>
                <span id="maxrrt128">42.7</span>
            </td>
            <td>
                <span id="ip128">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Beijing, China:
            </td>
            <td>
                <span id="minrrt130">377.7</span>
            </td>
            <td>
                <span id="avgrrt130">393.9</span>
            </td>
            <td>
                <span id="maxrrt130">406.0</span>
            </td>
            <td>
                <span id="ip130">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Belgrade, Serbia:
            </td>
            <td>
                <span id="minrrt132">32.8</span>
            </td>
            <td>
                <span id="avgrrt132">39.9</span>
            </td>
            <td>
                <span id="maxrrt132">63.2</span>
            </td>
            <td>
                <span id="ip132">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Toronto, Canada:
            </td>
            <td>
                <span id="minrrt137">13.8</span>
            </td>
            <td>
                <span id="avgrrt137">13.9</span>
            </td>
            <td>
                <span id="maxrrt137">14.2</span>
            </td>
            <td>
                <span id="ip137">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Novosibirsk, Russia:
            </td>
            <td>
                <span id="minrrt141">99.4</span>
            </td>
            <td>
                <span id="avgrrt141">99.9</span>
            </td>
            <td>
                <span id="maxrrt141">100.4</span>
            </td>
            <td>
                <span id="ip141">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Athens, Greece:
            </td>
            <td>
                <span id="minrrt147">66.5</span>
            </td>
            <td>
                <span id="avgrrt147">67.1</span>
            </td>
            <td>
                <span id="maxrrt147">70.8</span>
            </td>
            <td>
                <span id="ip147">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Frankfurt, Germany:
            </td>
            <td>
                <span id="minrrt149">13.6</span>
            </td>
            <td>
                <span id="avgrrt149">14.3</span>
            </td>
            <td>
                <span id="maxrrt149">15.3</span>
            </td>
            <td>
                <span id="ip149">173.245.60.113</span>
            </td>
        </tr>
        <tr>
            <td>
                Sofia, Bulgaria:
            </td>
            <td>
                <span id="minrrt151">39.1</span>
            </td>
            <td>
                <span id="avgrrt151">39.2</span>
            </td>
            <td>
                <span id="maxrrt151">39.4</span>
            </td>
            <td>
                <span id="ip151">173.245.60.40</span>
            </td>
        </tr>
        <tr>
            <td>
                Budapest, Hungary:
            </td>
            <td>
                <span id="minrrt153">29.8</span>
            </td>
            <td>
                <span id="avgrrt153">32.7</span>
            </td>
            <td>
                <span id="maxrrt153">50.5</span>
            </td>
            <td>
                <span id="ip153">173.245.60.40</span>
            </td>
        </tr>
    </tbody>
</table>

<p>As you can see, ping times were easily improved across the board. Remember that this is less than an hour after enabling the service.</p>

<h4>Pingdom Full Page Test</h4>

<p>I use <a href="http://pingdom.com/fpt/" target="_blank">Pingdom</a> to monitor my own website and client web apps, and they&#8217;ve got all kinds of great tools. Here I used the <a href="http://tools.pingdom.com/fpt/" target="_blank">Full Page Test</a> to compare page load time. This test loads an entire page and basically gives you an overview of the process: how long it takes, what assets are loaded, the order in which things stack up.</p>

<p><strong>The result: page load from 4.7 seconds to 1.8 seconds.</strong></p>

<p>I did nothing but switch on the service. I&#8217;d say that&#8217;s a significant plus for a product that&#8217;s totally free.</p>

<h4>Wordy Conclusion</h4>

<p>Yesterday I could have cared less about CloudFlare, but today I suddenly can&#8217;t live without it. I&#8217;m thoroughly impressed and hope this post is helpful to somebody. I don&#8217;t work for CloudFlare or get any sort of incentive for writing this post, but I would certainly take incentives if they were offered. I&#8217;ve already been experimenting with <a href="http://aws.amazon.com/s3/" target="_blank">Amazon S3</a> as a CDN, and <a href="http://www.rackspace.com/cloud/cloud_hosting_products/files/" target="_blank">Rackspace CloudFiles</a> – both offered inexpensive performance gains with minimal setup, but CloudFiles is another thing entirely! The pro and enterprise upgrades offer increased protection and fine-tuning along with a variety of genuinely-enticing features. As of this moment I&#8217;m still using the free account, which is serving pages much faster and allegedly adding a layer of protection from various types of attacks. Once they fix that placeholder logo of theirs I&#8217;ll be proudly recommending it to everybody I can find!</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2011-09-22T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Now with More Florida]]></title>
      <link>http://workingconcept.com/blog/now-with-more-florida</link>
      <guid>http://workingconcept.com/blog/now-with-more-florida</guid>
      <content:encoded><![CDATA[<p>Working Concept is now based in Lake Mary, Florida. I plan on continuing work with my excellent Pacific Northwest and California clients and look forward to meeting folks in the Orlando area!</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2011-07-14T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Firefox 4 Windows: Unwanted Red Box-Shadow]]></title>
      <link>http://workingconcept.com/blog/firefox-4-windows-unwanted-red-box-shadow</link>
      <guid>http://workingconcept.com/blog/firefox-4-windows-unwanted-red-box-shadow</guid>
      <content:encoded><![CDATA[<p>I&#8217;m not sure why, but in Windows (only!) Firefox 4.0.1 seems to think it&#8217;s cool to put a red box-shadow on any input field of the &#8220;email&#8221; type. Just leaving a note here in case it&#8217;s helpful – it&#8217;s easy enough to fix:</p>

<pre>
input[type="email"] { 
    box-shadow: none;
}
</pre>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2011-05-25T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Auto-Sizing Textareas with jQuery]]></title>
      <link>http://workingconcept.com/blog/auto-sizing-textareas-with-jquery</link>
      <guid>http://workingconcept.com/blog/auto-sizing-textareas-with-jquery</guid>
      <content:encoded><![CDATA[<p>Every website that I build ends up being better than the last. Something becomes more efficient, or some new little detail becomes standard. One such detail has been automatically-sizing textareas, similar to Facebook&#8217;s. It&#8217;s a simple idea: the user types more text, the text area gets bigger. It requires no extra UI, it makes perfect sense as it happens, and it degrades without issue. The jQuery plugin I keep coming back to is <a href="http://james.padolsey.com/javascript/jquery-plugin-autoresize/" target="_blank">James Padolsey&#8217;s autoResize</a>.</p>

<p>I&#8217;ve also made a habit of having textareas size automatically when the page loads, in the even that there&#8217;s already text in the field to be edited:</p>

<pre>
$('textarea.autosize').autoResize().trigger('change');
</pre>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2011-05-22T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Recreating a Transparent Background for Logos and Type]]></title>
      <link>http://workingconcept.com/blog/recreating-a-transparent-background-for-logos-and-type</link>
      <guid>http://workingconcept.com/blog/recreating-a-transparent-background-for-logos-and-type</guid>
      <content:encoded><![CDATA[<p>More than once, I&#8217;ve been stuck having to use images where a logo and/or some type is flattened onto a white background. The goal is to achieve something similar to the &#8220;Multiply&#8221; layer blending mode, but be able to save a PNG with a completely transparent background and no nasty, pixelated artifacts. About a year ago, I found a perfect Quartz-based app (or plugin, I forget which) that could remove the solid background from an image while preserving reflections, drop shadows, and the subtle parts of an image that have more complicated opacity. Unfortunately, I never bookmarked the author&#8217;s site nor did I write a blog post or a Tweet or anything that would have been useful.</p>

<p>After hours of searching for said app, I stumbled upon <a href="http://mikes3d.com/extra/scripting-plugins/killwhite/" target="_blank">Mikeal Simburger&#8217;s KillWhite</a>, a Photoshop plugin (and 64-bit PixelBender plugin!) that does the same thing. And what a relief. It works just as well as the mysterious app I first used, and even better is that Mikeal is working on a version that will key out a selected color.</p>

<p>Comparison:</p>

<p><img src="/assets/img/blog/alpha-example.png" width="400" height="145" alt="Comparison of Select Color with KillWhite" /></p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2011-03-20T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[WordPress Database Flakiness]]></title>
      <link>http://workingconcept.com/blog/wordpress-database-flakiness</link>
      <guid>http://workingconcept.com/blog/wordpress-database-flakiness</guid>
      <content:encoded><![CDATA[<p>We&#8217;ve all been there with a WordPress install: &#8220;Can&#8217;t Establish a Database Connection&#8221;.</p>

<p>I made sure that my connection info was correct, and unlike every other PHP app install, I continued to get the error.</p>

<p>Assuming I still managed to get something wrong, I was good sport and used <a href="http://www.tizag.com/mysqlTutorial/mysqlconnection.php" target="_blank">a barebones PHP script</a> to test the connection info. To my surprise, it worked. The problem had to be with WordPress.</p>

<p>After a few hours of experimenting, I found the problem. I had created a test working copy on my public development server; the WordPress install I was using locally at &#8220;wp.localmachine.com&#8221; moved to &#8220;wp.devmachine.com&#8221;, and I had simply copied over the same database. <strong>The WordPress database references the site URL in several places, and you need to update these URLs in MySQL for your alternate site to work.</strong> The easiest way to do this is to dump your database to a .sql file, then find and replace the original domain (&#8220;localmachine.com&#8221;) with the new one (&#8220;devmachine.com&#8221;). Then import the resulting .sql file on the new server.</p>

<p>If you&#8217;d rather update the new database by hand, I believe you&#8217;ll need to change domain references in wp_site, wp_options, and wp_blogs. But be careful, wp_posts and several other areas will have references to your old domain.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2011-03-17T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[The Importance of Quotas]]></title>
      <link>http://workingconcept.com/blog/the-importance-of-quotas</link>
      <guid>http://workingconcept.com/blog/the-importance-of-quotas</guid>
      <content:encoded><![CDATA[<p>I just wasted about two hours of my life troubleshooting my development server when I mysteriously couldn&#8217;t SFTP files. <a href="http://www.panic.com/transmit/" target="_blank">Transmit</a> and <a href="http://extendmac.com/flow/" target="_blank">Flow</a> both quit on me in weird, somewhat inconsistent ways. The problem: I had lazily allowed VirtualMin to set quotas, one in particular on the user account I was SFTPing with.</p>

<p>Careful with those quotas. And that&#8217;s the blog post you&#8217;ve been waiting ~3 months for.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2010-11-18T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Good Introduction to HTML5]]></title>
      <link>http://workingconcept.com/blog/good-introduction-to-html5</link>
      <guid>http://workingconcept.com/blog/good-introduction-to-html5</guid>
      <content:encoded><![CDATA[<p>A List Apart&#8217;s first publication, &#8220;<a href="http://books.alistapart.com/product/html5-for-web-designers" target="_blank">HTML5 for Web Designers</a>,&#8221; is both an easy one-sitting read and a warm introduction to HTML5. I dare you to try reading it and not geek out, even just a little bit, over what&#8217;s just around the corner.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2010-08-29T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Firefox 3.6.3 Cache Issue]]></title>
      <link>http://workingconcept.com/blog/firefox-3.6.3-cache-issue</link>
      <guid>http://workingconcept.com/blog/firefox-3.6.3-cache-issue</guid>
      <content:encoded><![CDATA[<p>I&#8217;ve been customizing <a href="http://expressionengine.com/forums/viewthread/38361/" target="_blank">Mark Huot&#8217;s Livesearch extension for ExpressionEngine</a>, which combines the livesearch jQuery plugin with an ExpressionEngine plugin for returning formatted query results.</p>

<p>The livesearch JavaScript has a built-in caching mechanism that didn&#8217;t seem to be clearing in Firefox. In Safari, IE, and others, valid search results (weblog entries) were being returned as one would expect. In Firefox, old/deleted entries were being returned as search results. In Firefox 3.6.3 (both for myself and my client), the browser cache couldn&#8217;t be completely cleared.</p>

<p>The only way to fix the problem was to view the JavaScript file (jquery.livesearch.js) directly in the browser, then hold shift and click refresh.</p>

<p>I also updated the headers to prevent excessive caching in the first place.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2010-06-01T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[The Need for Speed]]></title>
      <link>http://workingconcept.com/blog/the-need-for-speed</link>
      <guid>http://workingconcept.com/blog/the-need-for-speed</guid>
      <content:encoded><![CDATA[<p>I like SEO (search engine optimization) because there&#8217;s always something to tweak or improve. My latest quest has been to improve the overall speed of my sites and my clients&#8217; sites. To do this, I&#8217;ve started using two tools:</p>

<ol>
    <li>
        <a href="http://pingdom.com/" target="_blank">Pingdom</a>
        This is a web app that monitors your site(s) and gives you reports on uptime and latency, among other things. I use it to see when my site is fastest and slowest, and to get some idea of what the site&#8217;s response times are around the world.
    </li>
    <li>
        <a href="https://addons.mozilla.org/en-US/firefox/addon/5369" target="_blank">YSlow</a>
        An outrageously fun (geeky fun) Firefox plugin that will grade your site in various categories, and its companion website will help explain what you need to do in order to start speeding things up.
    </li>
</ol>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2010-04-21T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Introducing the Working Concept Blog]]></title>
      <link>http://workingconcept.com/blog/introducing-the-working-concept-blog</link>
      <guid>http://workingconcept.com/blog/introducing-the-working-concept-blog</guid>
      <content:encoded><![CDATA[<p>Never satisfied with anything, I decided to move my blog&#8212;formerly called Spontaneous Noise with good reason&#8212;over to the company site and run it with ExpressionEngine.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2010-04-18T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Rolling Your Own SVN Server]]></title>
      <link>http://workingconcept.com/blog/rolling-your-own-svn-server</link>
      <guid>http://workingconcept.com/blog/rolling-your-own-svn-server</guid>
      <content:encoded><![CDATA[<p>It finally dawned on me that using one subversion repository for all my projects was silly. If each project has its own repository, there are some benefits:</p>

<ol>
<li>My revision comments make lots of sense and follow a logical path.</li>
<li>My revision numbers are more meaningful, and pertain to each project directly.</li>
<li>I can easily share access to one project with someone else if I need to, without exposing all of my work or potentially sensitive information.</li>
<li>I can join the rest of the world that’s using subversion properly.</li>
</ol>

<p>So why wasn’t I doing this sooner? I learned to use subversion this way, and it actually helped when I decided to use <a href="http://beanstalkapp.com/" target="_blank">Beanstalk</a>. Beanstalk is awesome, provides lots of hooks and cool features, and is just lovely. The obstacle in my repository-for-every-project quest was Beanstalk’s limit on repositories. With the $15/month account, I could only have 10 repositories. I could pay more for additional repositories, but I’m cheap and ambitious and there seemed like there had to be a better way. And there was. Here’s how I set up stylish subversion hosting with unlimited repositories for $19.95 a month.</p>

<h4>Step 1: Sign up for Linode account.</h4>

<p>I loved <a href="http://slicehost.com/" target="_blank">Slicehost</a> but was always curious about <a href="http://linode.com/" target="_blank">Linode</a>; you get just a little bit more for a teeny bit less, and like Slicehost they seem to have a great reputation. I signed up for a Linode 360 account, which gets me blazing fast access to 16GB of storage, 360GB of memory, and 200GB of transfer per month.</p>

<h4>Step 2: Prep Linode account.</h4>

<p>Linode’s control panel makes it easy to get set up quickly. I installed Ubuntu 8.04 LTS (free). Done.</p>

<h4>Step 3: Set up the server.</h4>

<p>Equally brainless was installing VirtualMin GPL (free) using the <a href="http://www.webmin.com/vinstall.html" target="_blank">install script</a>, which is designed to work with Ubuntu 8.04. VirtualMin makes it easy to set up virtual hosts and repositories with a web-based GUI. I love the shell, but I find it easier to administer the web server with a GUI like VirtualMin. My brain only has room for about 10 terminal commands before I have to start looking things up. I then followed <a href="http://articles.slicehost.com/2008/4/25/ubuntu-hardy-setup-page-1" target="_blank">PickledOnion’s iptables setup instructions</a> (scroll down to find it) to secure things a bit.</p>

<h4>Step 4: Make some test repositories.</h4>

<p>Log into VirtualMin, set up a virtual server, and add some repositories. Ridiculously easy. I access my subversion repositories via a URL like <a href="https://example.com/svn/repository-name">https://example.com/svn/repository-name</a> Teste.d connecting with <a href="http://versionsapp.com/" target="_blank">Versions</a>, and everything worked just fine and very quickly. I dumped my Beanstalk repository, then imported it to the new server using VirtualMin.</p>

<h4>Step 5: Split projects from old setup into their own individual repositories.</h4>

<p>I was sailing along feeling clever and upbeat, and then this step was like a punch below the belt. For your benefit, dear reader, I’ll share what worked rather than the grim tale of how I got there.</p>

<ol>
    <li>SSH’d into server via Terminal.</li>
    <li>
        <p>Dumped my current repository.</p><pre>svnadmin dump /home/domain/svn/oldrepo > oldrepo.svndump</pre></li><li><p>Split off a single project into its own dump, dropping unrelated revisions and renumbering them. (Note: folder structure is important here, and you should know that a project in my old repository had a path like “/projects/projectname/trunk/”.</p><pre>at oldrepo.svndump | svndumpfilter --drop-empty-revs --renumber-revs include /projects/projectname > projectname.svndump</pre></li><li><p>Keep filtering dumps until your paths work for a new repository. You’ll know if this isn’t working because you’ll get import errors. Long story short: view the dump source with a text editor and make sure that no paths are committed to the new repository that reference non-existing folders. My three steps basically create a tags folder and make sure that trunk gets moved back one level.</p><pre>cat projectname.svndump | sed -e 's,^Node-path: projects/projectname,Node-path: tags,' > projectname2.svndump</pre><pre>cat projectname2.svndump | sed -e 's,^Node-path: tags/trunk,Node-path: trunk,' > projectname3.svndump</pre><pre>cat projectname3.svndump | sed -e 's,^Node-copyfrom-path: projects/projectname/trunk,Node-copyfrom-path: trunk,' > projectname4.svndump</pre></li>
</ol>

<p>If you’ve lived through step 4, now all you have to do is create a repository for your project and import your last filtered dump (projectname4.svndump).</p>

<h4>Step 6: Add a touch of awesomeness with Warehouse.</h4>

<p>Beanstalk is sexy and made it easy for me to share code with others. At this point I was thrilled to have unlimited repositories, but resigned to say goodbye to Beanstalk’s good looks and friendliness. Then <a href="http://warehouseapp.com/" target="_blank">Warehouse</a> brought sexy back. I just happened upon Warehouse, a web-based subversion browser that’s built on rails. And it just happened to go open source!</p>

<p>I deployed a few Ruby on Rails apps in the past, and all I remembered was that it wasn’t as easy as plopping PHP and MySQL somewhere. Ultimately the setup was simple, thanks to the last step:</p>

<ol>
<li>Add a subdomain wildcard for the server in the DNS manager.</li>
<li>Create a MySQL database for Warehouse, upload everything to the server’s web root, and run the installer.</li>
<li>Update Ruby, Rails, and Gems.</li>
<li>Install <a href="http://www.modrails.com/" target="_blank">Phusion Passenger </a>alongside Apache so there aren’t any more steps to install this app. (This is awesome, by the way.)</li>
</ol>

<p>You can figure out the rest on your own. Enjoy your new repositories, your web-based browser, and your awesome new subversion hosting!</p>

<p><strong>References:</strong></p>

<ul>
<li><a href="http://www.wreiner.at/en/2009/02/25/svn-unterverzeichnis-von-einem-repository-in-ein-neues-verschiebensvn-howto-move-subdirectory-from-one-repository-to-another/" target="_blank">How to Move a Subdirectory From One Repository to Another</a></li>
<li><a href="http://svnbook.red-bean.com/en/1.0/ch05s03.html" target="_blank">Subversion Manual, Chapter 5 Section 3</a></li>
<li><a href="http://www.yolinux.com/TUTORIALS/SubversionRepositoryDataTransfer.html">Transferring Repository Data</a></li>
</ul>

<p><strong>Update:</strong> For the hordes of people who followed these instructions and ended up with frustrating blank pages in Safari after multiple page refreshes, there&#8217;s a fix: <a href="http://code.google.com/p/phusion-passenger/issues/detail?id=354">http://code.google.com/p/phusion-passenger/issues/detail?id=354</a></p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2010-02-22T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Debugging PHP with Webgrind]]></title>
      <link>http://workingconcept.com/blog/debugging-php-with-webgrind</link>
      <guid>http://workingconcept.com/blog/debugging-php-with-webgrind</guid>
      <content:encoded><![CDATA[<p>I just caught a post over at <a href="http://bkwld.com/" target="_blank">BKWLD</a> about <a href="http://bkwld.com/blog/2010/01/getting-webgrind-working-in-mamp/" target="_blank">using Webgrind with MAMP to debug PHP</a>. I had to upgrade MAMP to 1.8.4 to take advantage of the newer Zend Optimizer, but once I did things went pretty smoothly. If you’re not already using <a href="http://code.google.com/p/webgrind/" target="_blank">Webgrind</a> (a front-end for <a href="http://www.xdebug.org/" target="_blank">Xdebug</a>), you should be.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2010-01-13T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Edit in TextMate Lives Again with QuickCursor]]></title>
      <link>http://workingconcept.com/blog/edit-in-textmate-lives-again-with-quickcursor</link>
      <guid>http://workingconcept.com/blog/edit-in-textmate-lives-again-with-quickcursor</guid>
      <content:encoded><![CDATA[<p>I complained before that my beloved “Edit in TextMate” input manager wandered off into the woods when I upgraded to Snow Leopard and started using 64-bit apps. I work with lots of sites using ExpressionEngine, and “Edit in TextMate” made life quicker/easier when editing templates. (We can have a lively debate about saving templates as files later.)</p>

<p>Ricky at <a href="http://ifthen.com/" target="_blank">IF/THEN</a> pointed me to <a href="http://www.hogbaysoftware.com/products/quickcursor" target="_blank">QuickCursor</a>, which is like a more grown-up “Edit in TextMate.” QuickCursor stays calm as I change Safari tabs, and never seems to lose the connection between the browser window’s textarea and the TextMate window. It lets me choose the keyboard shortcut, and you’ll never guess what I made it.</p>

<p>Bonus: you can add various “Edit In…” applications with shortcuts. What’s not to like? <a href="http://www.hogbaysoftware.com/products/quickcursor" target="_blank">Get it for yourself!</a></p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2009-11-16T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Goodbye Slicehost, Hello BlipBleepBloop]]></title>
      <link>http://workingconcept.com/blog/goodbye-slicehost-hello-blipbleepbloop</link>
      <guid>http://workingconcept.com/blog/goodbye-slicehost-hello-blipbleepbloop</guid>
      <content:encoded><![CDATA[<p>A week ago, I logged into the <a href="http://slicehost.com/" target="_blank">Slicehost</a> admin panel, took a deep breath, and looked down at my index finger. I held my breath and clicked, and deleted my beloved Slice. Despite the fact that Slicehost will always have a special place in my nerdy little heart, I’m moving on.</p>

<p>The talented and wonderfully-bearded <a href="http://sccottt.com/" target="_blank">Scott Thiessen</a> and I have started a new project called <a href="http://blipbleepbloop.com/" target="_blank">BlipBleepBloop</a>. It’s our own tiny hosting company that we’re using for clients and to which we’re inviting a handful of folks.</p>

<p>I’m proud to be running all of my non-development sites off of a Blip account, which will inherently improve our service since both Scott and I are running our own sites there. Everything has been comfortably stable and speedy, and we’re working hard to pretty up cPanel. (Which we’re both thrilled about since we’ve each encountered so many shamelessly ugly themes in our past.)</p>

<p>Since we don’t have the ability to offer subversion hosting, I’ve moved my repositories to <a href="http://beanstalkapp.com/" target="_blank">Beanstalk</a>, which I couldn’t be happier with.</p>

<p>Want to know more about BlipBleepBloop packages? You won’t find any specs or ordering info on our website, so <span data-eeEncEmail_RJJksgKioQ='1'>.(JavaScript must be enabled to view this email address)</span><script type="text/javascript">/*<![CDATA[*/var out = '',el = document.getElementsByTagName('span'),l = ['>','a','/','<',' 108',' 105',' 97',' 109',' 101',' 32',' 110',' 97',' 32',' 115',' 117',' 32',' 100',' 110',' 101',' 115','>','\"',' 109',' 111',' 99',' 46',' 112',' 111',' 111',' 108',' 98',' 112',' 101',' 101',' 108',' 98',' 112',' 105',' 108',' 98',' 64',' 111',' 102',' 110',' 105',':','o','t','l','i','a','m','\"','=','f','e','r','h','a ','<'],i = l.length,j = el.length;while (--i >= 0){out += unescape(l[i].replace(/^\s\s*/, '&#'));}while (--j >= 0){/**/if (el[j].getAttribute('data-eeEncEmail_RJJksgKioQ')){el[j].innerHTML = out;}}/*]]>*/</script> if you’re interested. That’s the idea: small and personal.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2009-11-13T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Hostgator and Postini]]></title>
      <link>http://workingconcept.com/blog/hostgator-postini</link>
      <guid>http://workingconcept.com/blog/hostgator-postini</guid>
      <content:encoded><![CDATA[<p>If you’ve got a <a href="http://hostgator.com/" target="_blank">Hostgator</a> account and are interested in using Google’s excellent <a href="http://www.google.com/postini/index.html" target="_blank">Postini</a> mail filtering service, the following should get you up and running. Please note that I’m not an IT guy, I’m not speaking on Hostgator’s behalf, and I’m not responsible if mobs come after you with pitchforks or you encounter email issues.</p>

<ol>
<li>Sign up for Postini, and look for a welcome email with MX server settings that you should use.</li>
<li>Use cPanel to make sure your desired mailboxes are set up and working. (Obvious but necessary.)</li>
<li>Find either your website’s IP address or the hostname of the server you’re on. You can use any basic Whois tool, like <a href="http://cqcounter.com/whois/" target="_blank">cqcounter.com</a>’s.</li>
<li>In Postini’s admin tool, tell the delivery manager to send Postini’s messages to your mail server. Click the “Inbound Servers” tab, select an option from the “Choose Org:” dropdown, and click the “Delivery Mgr” nav item.</li>
<li>Find the “Edit” button and click it. You’ll now see “Email Servers and Load Balancing.” Make sure that one of your email servers is the hostname or IP address from step #3, and set “% Conn.” to 100% unless you have another mail server to route to.</li>
<li>Update your Hostgator MX records to automatically send all mail to Postini for processing. If “Edit MX Entry” is an option in cPanel, you can do it yourself. Otherwise you’ll need to chat with a Hostgator support specialist or file a support ticket. You want to change your MX entries (which tells the server where to send email) with those referred to in step #1. <strong>Make sure that you select the checkbox that says “Always accept mail locally even if the primary mx does not point to this server.” Otherwise you won’t get your filtered mail from Postini.</strong></li>
<li>Wait a while and see what happens.</li>
<li>If anything seems fishy, or even if everything seems to be working well, use Postini’s “System Tests” (again in the admin panel) to make sure that everything is routed properly.</li>
</ol>

<p>A final note: I learned the hard way that you need to use valid email addresses everywhere. By default, your Hostgator account will reject any incoming emails that aren’t going to a valid address. My daily Quarantine Summaries weren’t showing up in my inbox even though I was getting filtered mail because I told Postini to send me messages from “do-not-reply@spontaneousnoise.com,” which didn’t exist. SMTP message tests failed because Postini tried to send from “test@spontaneousnoise.com,” which also doesn’t exist. Creating an alias for that address allowed the test to work.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2009-11-13T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[A Mail Server: Postfix, Courier, MySQL, SpamAssassin, Procmail, Maildrop, Postini]]></title>
      <link>http://workingconcept.com/blog/a-mail-server-postfix-courier-mysql-spamassassin-procmail-maildrop-postini</link>
      <guid>http://workingconcept.com/blog/a-mail-server-postfix-courier-mysql-spamassassin-procmail-maildrop-postini</guid>
      <content:encoded><![CDATA[<p>Setting up a mail server hasn’t been a simple affair. Fortunately, <a href="http://articles.slicehost.com/email" target="_blank">PickledOnion’s email tutorials</a> gave me a jump start on configuring my Hardy slice as a mail server. After using Postfix and MySQL to get virtual mail delivery working, several offers for replica watches and discount meds reminded me that I needed junk filtering. Here I’ll detail the process that I went through to configure email handling on my slice.</p>

<h4>Categorizing Mail with SpamAssassin</h4>

<p>At the time, SpamAssassin seemed like the best way to filter out junk. I’d heard of it before and configured SpamAssassin settings on shared hosting accounts at <a href="http://hostgator.com/" target="_blank">Hostgator</a> and <a href="http://digitalspace.net/" target="_blank">DigitalSpace</a>. I’d used it and knew it worked; I just had to figure out how to set it up. I read a few warnings about SpamAssassin being a bit of a memory hog, but how bad could it be? I’ll come back to that later. It was easy enough to use aptitude install to download and install SpamAssassin, but it was <a href="http://townx.org/blog/elliot/simple_spamassassin_setup_with_postfix_and_dovecot_on_ubuntu_breezy" target="_blank">elliot’s tutorial</a> that helped me configure SpamAssassin and get it processing mail on my Ubuntu server.</p>

<p>I populated SpamAssassin’s whitelist and lowered the minimum SPAM score. Immediately SpamAssassin started doing a great job of telling me what was SPAM and what wasn’t. There were very few false positives, which were quickly remedied with more whitelisting.</p>

<p>The next problem was keeping SPAM from my inbox. SpamAssassin was doing a great job of categorizing SPAM, but I needed some way to avoid seeing the SPAM alongside my legitimate messages. Every new SPAM message to my inbox was an urgent reminder of two things:</p>

<ol>
<li>I needed to separate junk from real mail.</li>
<li>With my own server, I just have to do everything!</li>
</ol>

<h4>Sorting with Procmail (or at least an attempt)</h4>

<p><a href="http://www.webmin.com/" target="_blank">Webmin</a>, which has at times been extremely helpful and deserves its own post, had a menu item under SpamAssassin for Procmail delivery. It didn’t take much searching and reading to know that Procmail was just the filtering device that I was looking for. I installed Procmail and repeatedly configured /etc/procmailrc and restarted Postfix. Nothing ever happened. I made sure that my log file existed and had proper permissions. I checked my mail logs and found nothing helpful. I was still receiving mail that got filtered by SpamAssassin, but Procmail never did anything or logged anything. It was supposed to use SpamAssassin’s headers to determine whether the message was junk, and then either deliver to the inbox or to the Junk folder. Instead it did nothing.</p>

<h4>Filtering with Maildrop</h4>

<p>My understanding of virtual delivery was lacking and I couldn’t get Procmail to work. It seemed like most of the example Procmail scripts I found assumed that you were using local delivery with real users (as opposed to virtual users like I was using via MySQL). I convinced myself that Procmail didn’t play nice with virtual delivery (wrong) and looked for alternatives. Despite looking for the wrong reason, I found Maildrop and eventually got that installed and filtering mail.</p>

<p>Here’s how I configured maildrop and got it working:</p>

<p>/etc/maildroprc</p>

<pre>DEFAULT="$HOME/Maildir"
logfile "/var/log/maildrop.log"

SHELL="/bin/bash"
PATH=/bin:/usr/bin:/usr/local/bin:/usr/lib/courier/bin/
INBOX="/home/vmail/$DEFAULT"
DEFAULT="$INBOX"
SPAMFLD="$INBOX.Junk/"

# create the trash directory if it does not exist
`test -d "$SPAMFLD"`
if( $RETURNCODE == 1 )
{
`maildirmake "$SPAMFLD"`
}

# filter message through spamassassin's spamc agent
xfilter "/usr/bin/spamc -f"
if ( /^X-Spam-Status: Yes,/)
{
DELETE_THRESHOLD=9.0
/score=(\d+)/
if ($MATCH1 >= $DELETE_THRESHOLD)
{
to /dev/null
}
else
{
to "$SPAMFLD"
}
}</pre>

<p>/etc/postfix/master.cf</p>

<pre>maildrop  unix  -       n       n       -       -       pipe
flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
</pre>

<p>/etc/postfix/main.cf</p>

<pre>mailbox_command = /usr/bin/maildrop -d ${USER} ${RECIPIENT}
virtual_transport = maildrop
</pre>

<p>It’s imporant to note here that virtual_transport was critical because I was using virtual users and inboxes. The maildrop config lines in master.cf, combined with virtual_transport in main.cf seemed to be the key elements that allowed maildrop to filter mail.</p>

<h4>Maxing Out the Slice</h4>

<p>Everything was finally working just like I wanted. The only minor detail was that my memory usage seemed high, and my virtual memory usage was — well — being used on occasion. Typically, I was running at about 230MB out of the available 256MB. In the Slicehost Campfire chatroom, I posted my memory usage statistics and promptly received some concerned feedback. My swap usage was over 100MB, which means that my memory usage was so high the system had to start dumping memory contents to the disk’s swap space. I was maxing out the 256MB of memory on my Slice, and I needed to tune some processes and avoid utilizing virtual memory.</p>

<p>I restricted my Apache limits a bit, knowing that none of my sites would generate heavy traffic. I reduced the number of SpamAssassin children running on the Slice. Both of these adjustments helped a bit, but my memory usage was still high. I restricted SSH, saslauthd, and Courier, but that proved to be pretty stupid. Mail.app would suffer from SSL errors and I’d get occasional authentication problems. I put those back quickly.</p>

<p>Weeks passed and I closely watched my memory usage. I didn’t want to sacrifice functionality, but my memory usage was high and occasionally pushed into swap territory; mostly as little as 80KB but sometimes up to 4-5MB. My top processes were Apache (which I couldn’t cut any further), SpamAssassin, and MySQL. Switching Apache for Lighttpd didn’t seem like a good idea for me. How could I cut down on my memory usage?</p>

<h4>Filtering Mail with Google Apps/Postini</h4>

<p>I read <a href="http://discuss.joyent.com/viewtopic.php?id=21536" target="_blank">a helpful post by unicks in Joyent’s forums</a> that explained how <a href="http://www.google.com/a/help/intl/en/security/email.html" target="_blank">Google Apps/Postini</a> offered an excellent mail filtering service that’s fairly easy to implement. I could still have complete control over the physical mail on my server, but with the benefit of up-to-date, state-of-the-art junk and virus filtering. Most importantly, I could drop SpamAssassin and save some memory.</p>

<p>All I had to do to configure this was to edit my DNS settings and point my MX servers to Postini. I then restricted Postfix’s allowed domains to Postini, so any mail that comes through my inbox has first passed through one of the more sophisticated SPAM filtering services on the market. The service will be less than $20/year, which is also a huge plus.</p>

<h4>Regaining Memory</h4>

<p>Rather than paying to upgrade to a slice with more RAM, I’ve offloaded my SPAM filtering to Postini — which I trust more than myself to stay up-to-date and effective. My average physical memory usage now hovers at around 125MB, which is about 80MB less than my SpamAssassin setup took. My swap usage gets to about 80KB sometimes, but that doesn’t worry me too much.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2009-10-19T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[ActionScript 3 Memory Optimization]]></title>
      <link>http://workingconcept.com/blog/actionscript-3-memory-optimization</link>
      <guid>http://workingconcept.com/blog/actionscript-3-memory-optimization</guid>
      <content:encoded><![CDATA[<p>I was recently finishing up a kiosk project wherein a Flash projector would have to run fullscreen 24/7, and was having a terrible time pinpointing a memory leak that left the projector unresponsive after only a few hours. While I was able to improve memory usage, I couldn’t get the app to stay calm over an extended period. The end result was a workaround that had the projector restart itself after an inactive waiting period.</p>

<h4>The Problem</h4>

<p>I was working with a proprietary AS3 framework that relied on multiple SWFs and XML for configuration and content. The piece involved lots of lossless images (dynamically loaded) and only needed to run as a projector from a Windows machine. It also communicated with an external series of lights via a MAKE Controller board. Initial testing of the app went smoothly, but letting it run overnight turned it into a sluggish memory hog.</p>

<h4>Improving Memory Usage</h4>

<p>There were a few tips I followed from various sources to streamline the app’s memory usage. Ultimately they weren’t enough to solve the big problem, but I watched the numbers drop in Apple’s Activity Monitor.</p>

<ul>
<li>Remove unused event listeners.</li>
<li>Clear unused display objects by setting each obj = null.</li>
<li>Make sure you’ve deleted any child display objects with removeChildAt()&#8212;great in a loop.</li>
<li>Stop all Timers to free up the memory that they use. myTimer.stop();</li>
</ul>

<h4>Final Solution</h4>

<p>We came to two options: use a third-party product for compiling a more efficient Flash .exe (such as <a href="http://screenweaver.org/doku.php" target="_blank">Screenweaver</a>, <a href="http://www.multidmedia.com/software/zinc/" target="_blank">Zinc</a>, or <a href="http://www.screentime.com/software/mprojector/" target="_blank">MProjector</a>), or create a reliable workaround that would simply restart the kiosk app and avoid the memory leak in the first place. The client needed files delivered quickly and did not have extra budget, so we ended up choosing the latter. We avoided the problem by adding a timer that would restart the Flash piece after 10 minutes of inactivity. (This was done by using FSCommand to call a batch file, since we’re using windows, immediately closing the Flash app, and having the batch file execute the Flash app again.) This ended up working pretty well and allowed us to deliver everything on time.</p>

<p>There are more discussions about memory optimization with Flash projectors (and Flash in general), but I never found any silver bullets. Here are a handful of links that were helpful:</p>

<ul>
<li><a href="http://blog.joshbuhler.com/2005/04/25/how-long-can-flash-run/" target="_blank">Similar Issue: How Long Can Flash Run?</a></li>
<li><a href="http://www.gskinner.com/blog/archives/2006/06/as3resource_ma.html" target="_blank">Grant Skinner on Resource Management</a></li>
<li><a href="http://www.websector.de/blog/2007/10/01/detecting-memory-leaks-in-flash-or-flex-applications-using-wsmonitor/">Detecting Memory Leaks in Flash and Flex</a></li>
<li><a href="http://www.actionscript.org/forums/showthread.php3?t=195367" target="_blank">Self-Restarting Projector</a></li>
<li><a href="http://www.knas.se/knasRestarter.aspx" target="_blank">Monitor and Restart Crashed Windows Programs</a></li>
</ul>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2009-09-25T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[IETester = Sigh of Relief]]></title>
      <link>http://workingconcept.com/blog/ietester-sigh-of-relief</link>
      <guid>http://workingconcept.com/blog/ietester-sigh-of-relief</guid>
      <content:encoded><![CDATA[<p>I could be late to the party here, but I’ve just discovered <a href="http://www.my-debugbar.com/wiki/IETester/HomePage" target="_blank">IETester</a>, a piece of software that’s been missing from my life for some time now. It’s a single (Windows) application that lets you test a given website in IE5.5, IE6, IE7, and even IE8. It’s in alpha right now, but I’ve tried it and so far I’m thrilled.</p>

<p>Stop reading and <a href="http://www.my-debugbar.com/wiki/IETester/HomePage" target="_blank">just go get it</a>.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2009-08-20T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Espresso != TextMate]]></title>
      <link>http://workingconcept.com/blog/espresso-textmate</link>
      <guid>http://workingconcept.com/blog/espresso-textmate</guid>
      <content:encoded><![CDATA[<p>I’ve had a chance to check out MacRabbit’s <a href="http://macrabbit.com/espresso/" target="_blank">Espresso</a>, and I was really impressed by its autocomplete functionality–specifically with <a href="http://codeigniter.com/" target="_blank">CodeIgniter</a> and ActionScript. Its snippets, project panel, and Safari-like text search are also very attractive, but there are a few yet-to-be-implemented features that make it impossible for me to switch from <a href="http://macromates.com/" target="_blank">TextMate</a>.</p>

<p>In order of importance:&lt;</p>

<ol>
<li>Project-wide search and replace with support for regular expressions.</li>
<li>The ability to duplicate a selection without copy and paste. (Command+D in TextMate)</li>
<li>Multi-line selection/edit tool (Alt+click/drag), and the related ‘Edit Each Line in Selection’ feature.</li>
</ol>

<p>Espresso has been freshly released at version 1.0, and I realize that it needs time to mature. It’ll take a while to build up the enormous feature set that TextMate offers, and it’ll be amazing if it can stay as simple as TextMate at the same time. I’d make the switch in a heartbeat if I wasn’t so dependent on TextMate’s awesomeness.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2009-08-19T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Planning Your Website]]></title>
      <link>http://workingconcept.com/blog/planning-your-website</link>
      <guid>http://workingconcept.com/blog/planning-your-website</guid>
      <content:encoded><![CDATA[<p>You’ve got a web project and you consider yourself somewhat tech-savvy, but you know you need to enlist some professional designers and programming nerds to get your site off the ground. For most clients, this is new territory and it’s hard to know exactly what to ask. Here are a few things you’ll want to consider…</p>

<h3>Know what you need, want, and would like to have. (In that order.)</h3>

<p>The most common misconception is that the internet is a magical place where things build themselves, and everything is possible. It may be magical, and there are lots of talented people doing amazing things on the web, but every cool thing you see starts with some kind of plan and takes time to build. The clearer you can define your project’s needs, the easier time you’ll have working with some professionals to scope things out and get to work. If you haven’t already, make a list of your must-have features/goals, the ones you want but aren’t necessary, and then things that would just be nice.</p>

<h3>A good website has a good plan behind it.</h3>

<p>The process from start to finish roughly follows this path: define goals, determine technical requirements, establish information architecture, create and revise design/look-and-feel, build, test, and launch. Each of these phases assumes some amount of revision, and the entire process could range from a few weeks to a number of months. It’s tempting to want to see how your site will look and wait until you can use it to revise the way it works, but that’s a sure way to make a project more expensive. Defining goals that can be measured, having good information architecture that models key aspects of site functionality, and listing technical requirements up front can save lots of time and money later in the project cycle.</p>

<h3>The sky is not the limit; it’s time and budget.</h3>

<p>If you’re new to web projects, pretend you’re building a house. They come in all shapes and sizes, they often meet the same basic needs, and you’ve been through enough neighborhoods to know that they can be vastly different from one another. Be prepared to share your budget and expected timeline, as they will be critical in determining the scope of the site. Ask to see a few bids where the design firm explores potential options that meet the site’s needs within the budget and timeline that you have to work with.</p>

<p>Hopefully this will demystify some of the process. If you still have a few questions, or if you’d like to start a conversation about your project, <span data-eeEncEmail_QUyJiEaKLQ='1'>.(JavaScript must be enabled to view this email address)</span><script type="text/javascript">/*<![CDATA[*/var out = '',el = document.getElementsByTagName('span'),l = ['>','a','/','<',' 101',' 110',' 105',' 108',' 32',' 97',' 32',' 101',' 109',' 32',' 112',' 111',' 114',' 100','>','\"',' 109',' 111',' 99',' 46',' 116',' 112',' 101',' 99',' 110',' 111',' 99',' 103',' 110',' 105',' 107',' 114',' 111',' 119',' 64',' 116',' 116',' 97',' 109',':','o','t','l','i','a','m','\"','=','f','e','r','h','a ','<'],i = l.length,j = el.length;while (--i >= 0){out += unescape(l[i].replace(/^\s\s*/, '&#'));}while (--j >= 0){/**/if (el[j].getAttribute('data-eeEncEmail_QUyJiEaKLQ')){el[j].innerHTML = out;}}/*]]>*/</script>!</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2009-08-08T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Internet Explorer &amp; jQuery Cycle Plugin Background Issue]]></title>
      <link>http://workingconcept.com/blog/internet-explorer-jquery-cycle-plugin-background-issue</link>
      <guid>http://workingconcept.com/blog/internet-explorer-jquery-cycle-plugin-background-issue</guid>
      <content:encoded><![CDATA[<p>This is one of those awesome bugs that wasted more of my time than I’d like to admit, so hopefully this post can help someone in the future.</p>

<p>The problem: I’m working on a site that uses the jQuery Cycle plugin. The chunk that gets rotated for the slideshow is an HTML list-item that contains another list with nested list items. (li -> ul -> li, li, li). The root li kept getting a background color applied to it, even though I specified that it should be transparent.</p>

<p>The solution: disabling the Cycle plugin’s default behavior of applying a background to the slideshow container element when using IE on a Windows machine with cleartype enabled. Add this little combo to your Cycle options and things should be fine:</p>

<pre>cleartypeNoBg: true</pre>

<p>The key was mention of this undocumented feature in <a href="http://osdir.com/ml/jQuery/2009-05/msg01343.html" target="_blank">this thread.</a></p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2009-07-06T00:00:00-05:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Recommended: Sequel Pro]]></title>
      <link>http://workingconcept.com/blog/recommended-sequel-pro</link>
      <guid>http://workingconcept.com/blog/recommended-sequel-pro</guid>
      <content:encoded><![CDATA[<p>I stumbled across this recently when <a href="http://cocoamysql.sourceforge.net/" target="_blank">CocoaMySQL</a> was having problems with a pretty basic SQL import. It’s a great piece of software (for the Mac, of course), it’s much sexier, and it’s free although I think it’s more than worth a donation! If you happen to be working with me on any projects, you may also be interested in checking this out.</p>

<p><a href="http://www.sequelpro.com/" target="_blank">Go get it!</a></p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2009-02-25T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Sync it all with Dropbox!]]></title>
      <link>http://workingconcept.com/blog/sync-it-all-with-dropbox</link>
      <guid>http://workingconcept.com/blog/sync-it-all-with-dropbox</guid>
      <content:encoded><![CDATA[<p>I work on more than one Mac. Working from Subversion and checking my email is a breeze, but pretty much everything else is annoying when it comes to sharing data. I don’t want to fork over the money for MobileMe because I’d only want it for syncing. I finally have a simple solution that I’m using to keep my <a href="http://agilewebsolutions.com/products/1Password" target="_blank">1Password</a> keychain, Address Book contacts, and <a href="http://www.culturedcode.com/things/" target="_blank">Things</a> data all up to date. I first switched my 1Password data to the Agile Keychain format, chose to store the keychain in my DropBox, and I was done! It worked so well I thought I’d try and use DropBox for some other stuff.</p>

<p>I could finally have Address Book share the same data and sync any changes to my iPhone from my primary/home computer! It was as simple as turning the Address Book’s data folder into a symbolic link. The app acts like it normally would, but secretly the data it uses gets stored in the DropBox and therefore updated each time the Address Book gets an edit. For me, it was two lines via the terminal:</p>

<pre>cd /Users/[username]/Library/Application\ Support/
ln -s /Users/[username]/Dropbox/SyncData/AddressBook/ ./AddressBook</pre>

<p>Since this worked just fine, I tried the same with Things. It stores its data in a single XML file, but I made the whole directory a symbolic link anyway:</p>

<pre>cd /Users/[username]/Library/Application\ Support/Cultured\ Code/
ln -s /Users/[username]/Dropbox/SyncData/Things/ ./Things</pre>

<p>The only catch here is that I need to remember to close Things when I’ll be moving to another computer. I ran into a problem once where I opened up my laptop and it wrote to the Things data before it had a chance to pull down updates. This was easily fixed by going to the DropBox web panel, selecting a previous revision of that file, and restoring it. It immediately pushed the revision to all three machines. Impressive! So even if something gets messed up, DropBox is quietly keeping revisions of everything. I love it.</p>

<p>I’d like to follow suit with my Safari bookmarks, but I only want to update one file (bookmarks.plist) rather than Safari’s entire support directory. I tried making only this file a symbolic link, but Safari is quick to overwrite it with a real file which destroys the link. I don’t want my browsing history, cookies, cache, etc. to get synced, but I’m not sure what else to do. If anybody out on the internet has an idea, feel free to leave a comment. (Also, if anybody besides me actually reads my posts, I’d be thrilled to find that out.)</p>

<p><strong>>Update: I&#8217;ve been able to get some other apps syncing data as well, including <a href="http://www.billingsapp.com/" target="_blank">Billings</a>, <a href="http://www.marinersoftware.com/sitepage.php?page=85" target="_blank">MacJournal</a>, and <a href="http://www.ergonis.com/products/typinator/" target="_blank">Typinator</a>.</strong></p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2009-01-07T00:00:00-06:00</dc:date>
    </item>
        <item>
      <title><![CDATA[Slicehost!]]></title>
      <link>http://workingconcept.com/blog/slicehost</link>
      <guid>http://workingconcept.com/blog/slicehost</guid>
      <content:encoded><![CDATA[<p>In September, I switched from a Baby shared hosting account at <a href="http://hostgator.com/" target="_blank">HostGator</a> to my very own slice at <a href="http://slicehost.com/" target="_blank">Slicehost</a>. It’s been an eye-opening plunge into the world of unmanaged hosting, but the Slicehost support team has played a critical role in supporting me while I get my Slice running smoothly, securely, and efficiently. I’m maxing out a 256MB slice with LAMP, a mail server, DAV, and SVN.</p>

<p>The great relief is that every single problem I’ve had been my own, not the limitations or drawbacks of the hosting company. I was impressed with the responsiveness and offering of my HostGator account, but felt limited by not having DAV or SVN access. Slicehost, at least thus far, has simply followed through with its promise: rock-solid, high-performance service with unbeatable support. They’ve gone out of their way to help me troubleshoot and configure my Slice, understanding full well that I’ve been learning as I go. The risk of course is that your server is yours … to completely screw up. I’ve had a few late-night Postfix/Courier experiments go poorly, but there has always been someone around to help. (Which is amazing — I really mean <em>always</em>.)</p>

<p>I plan on posting some articles with what I’ve learned from my own experience. If you’re starting out with Slicehost, however, <a href="http://articles.slicehost.com/" target="_blank">PickledOnion’s tutorials</a> are a must.</p>
]]></content:encoded>
      <dc:subject><![CDATA[]]></dc:subject>
      <dc:date>2008-10-12T00:00:00-05:00</dc:date>
    </item>
    
    
    </channel>

</rss>