Redemption via JSXHint

Recently while shipping a feature for an awesome ReactJs app we have been working on at Automattic I made the mistake of removing a variable declaration that resulted in a dreaded undefined error on production.

But like life, in coding we learn from our mistakes, and work to prevent them from happening in the future. Obviously a test framework wired in with CI would have likely caught this – but the error only happened on certain sites – making it somewhat of an edge case that some test cases would not have caught.

A simple quick run thorugh jsxhint would have caught it though.

jsxhint
Simply but jsxhint is:

A wrapper around JSHint to allow linting of files containing JSX syntax.

Installation of jsxhint is done via npm, and by using the global flag: npm install -g jsxhint

I thought, wouldn’t it just be neat to always run jsxhint on my revisions prior to committing them?

After a bit of searching, I found an answer on stackoverflow detailing how to setup a git pre-commit hook for jshint. So with a little bit of massaging, I created a pre-commit git hook that runs all changed .js and .jsx files through jsxhint. You can find the pre-commit hook here.

If jsxhint finds any errors in any files changed in your revision, it will not let the commit proceed… and wonderfully it prevents James Van Der Beek from shedding any more tender tears.

Installing WP-CLI on OS X Mavericks

The Backstory

A recent project has me working quite a bit with WordPress and WP Plugin development. After getting my sea legs on the subject of Plugin Development, I started going down the path to writing tests for the plugin I am developing.

$this->assertEquals( ‘testing_framework’, ‘PHPUnit’);

PHPUnit is the testing framework used on WordPress Core, so I decided to use the same framework while writing my tests. It has been a bit of a learning curve for me to get started with testing a Plugin, so this is the first in a series of posts I will be writing about getting a testing environment setup on OS X Mavericks.

For the record, my local setup is a Macbook Pro that is running OS X 10.9.2, and the Apache/PHP/MySql services are being handled by MAMP. MAMP is pretty straightforward to get running so I’ll move ahead to the subject of this post – WP-CLI.

The WP Toolbelt

My first exposure to WP_CLI came when I was looking for a less painful way to perform upgrades on The Longboard Blog. For anyone at home on the command line WP_CLI just feels right. For example, when our marketing person wants some hot new plugin installed, I just fire up an ssh session and jam in `wp plugin install omg-internet-cats` to install her desired plugin.

But on my quest to TDD WordPress Plugin nirvana lead me right back to WP_CLI. You see to get the test suite setup and running easily, WP_CLI is a key ingredient.

Installing WP_CLI

First things first, grab some handy info to complete the install. First of which is firing up MAMP’s start page (likely here if MAMP is running: http://localhost:8888/MAMP/?language=English) and grab your PHP path from the phpinfo tab. It will likely be /Applications/MAMP/bin/php/php5.5.3, with the last directory varying depending on your PHP version.

Next the install is super quick and easy, just cd to your MAMP php directory and do the following:

curl -L https://raw.github.com/wp-cli/builds/gh-pages/phar/wp-cli.phar > wp-cli.phar

Verify it works:

php wp-cli.phar --info

And create a shortcut:


chmod +x wp-cli.phar
mv wp-cli.phar /usr/bin/wp

Then the only unique part of the install is to add in some convenience aliases to your ~/.bash_profile. From the command line again run:

vi ~/.bash_profile

And append the following to the end of your profile, be sure to adjust the path to your MAMP path you looked up in step #1:

Now if you open up a new terminal window, or source ~/.bash_profile you can start wp‘in like a champ. Stay tuned for the next post in the series about setting up the PHPUnit test stack in your project.

Extending Rails Engins with the Decorators Ruby Gem

Over the past month I have been launching a few sites using a neat little Rails engine called Piggybak. Piggybak (worth a blog post on its own) handles just the basics of an e-store, and leaves the rest up for the creative developer.

While building these sites I would run into scenarios where I needed to extend the engine’s functionality and I went searching for an elegant “railsy” way of doing so. My search led me to some threads from the Forem project, and ultimately to the Decorators gem.

RTFM

I couldn’t readily find any how-to’s on the gem so I dug into the code, and the usage in the Forem gem. It is super simple to use, but I figured I would add some documentation here on the blog. First things first, to utilize Decorators in your rails project add it to your Gemfile

gem 'decorators'

The gem does have some opinions on how one should construct their decorators for Rails engines. I based my usage upon what was found in Forem and created a decorators folder in the app root of my Rails.root. Within that folder, one should then create folders that mimic your extensions/decorations to engines (i.e. /app/decorators/models, /app/decorators/views etc), and the decorators themselves need to have a suffix of _decorator.rb.

Decorate

So lets decorate the Piggybak::Order model to include an association for packages. Following the folder structure above, we would create a file at /app/decorators/models/piggybak/order_decorator.rb like so:

Initialize

The last piece to take care of is add the following line to a config/initializer file:


Decorators.register! Rails.root

SMS Shipment Notifications via Twilio

Since the dawn of interweb commerce, etailers have been serving up e-mail based alerts when a package is sent out the door. The shopper then clicks on some form of tracking link within that email, and the waiting game begins.

Email Shipment Alerts: The Meh

So this process does work, but we all know the downfalls of this route. Email of course is just broken in general, but more specifically, shoppers will often mis-type their emails during the checkout process, or notifications such as these often get routed directly to a SPAM folder.

Sprinkle in Some SMS with Twilio

Now I am not advocating for the omission of shipment emails, rather simply giving your customers an alternate channel to receive these alerts. We are big fans of SMS messaging at The Longboard Store. We already let our customers subscribe to text alerts for products that come back in stock, so we figured why not let them get notified via SMS when their package ships out?

Last week we did just that. A simple form was added to the order status page, allowing customers to sign up to be alerted via text when their order is shipped. The system lets customers add multiple phone numbers to be signed up to the alert system – and like the product alerts – requires users to validate ownership of the mobile device via a confirmation code.

Neat, but Why?

In the first week of this system being online ONE THIRD of all customers who placed an order signed up. Rub your eyes, read it again, thirty percent of all customers placing an order signed up to be notified via SMS when their order ships.

The people have voted, and they want to be notified immediately when their new toy ships.

The text alert simply states their order has shipped, and the user can click on a shortened URL that directs them to a shipping status page where they can track the package. Perhaps down the road we can send an additional alert when UPS marks the package as out for delivery….

Give The People What They Want

Ultimately this again shows that SMS is an effective means of communicating in the online retail space. Quite possibly our demographic (longboards and skateboards) skews the interest in SMS a bit, but I believe that similar interest would be seen amongst nearly any online marketplace.

Plainly put though, by offering these types of notifications, you are adding just a little bit of extra customer service for your shoppers… besides, who wouldn’t be excited to see that their package is enroute?

I’m excited to see CTR on these text messages, and possibly see if any up-sell opportunities exist for these clicks.

Conversion Analytics Nirvana: Clicky Stats + High Charts

I often find myself being caught in the time sucks of Google Analytics and Clicky Stats. When I code a new feature on a given site, I’m very eager to see how the greater masses of the web use my shiny new feature, but most often I end up sinking too much time clicking around these third party services… when I should be like writing code and stuff.

Conversion Tracking – What Sources Convert?

To me though, the most useful data form any analytics packaging, for an ecommerce site at least, is researching what sources are converting. The uses of this are obvious, and endless, so yesterday I decided to make it a little bit easier for the users of our admin application at The Longboard Store to get in touch with conversion tracking.

Clicky API, Serving Up the JSON Data

I am a big fan of Get Clicky. It is simple, easy to use, and even has some fun features like ‘Spy’ and ‘Big Page’. But the feature I like most is their dead-simple API. So with the final half hour of the day ahead of me yesterday at work, I decided to leverage that API and Highcharts to build a quick view into conversion sources.

Look Out, Psuedo Untested Code

Hackity Hack time ensued, and I whipped up a quick little bit of jQuery and Highcharts to build a Pie Chart of conversion sources.

Essentially I have a button with an id of ‘clicky-chart’, when the user clicks that, the Clicky API is called and a pretty Pie Chart is painted like so:

Make Everyone an Analyst

The wonderful thing about quick features like this is it empowers users of your drab admin tool to really analyze data a bit further. If you dig into the gist above, you can see that when a user clicks on a slice of the pie, a new window is opened to the clicky stats detail page where they can dig into a given group of conversions in finer detail.

Getting this data in front of more users helps foster new ideas, and helps easily identify under-performing marketing channels.

I might abstract out this code a bit to make generating HighChart graphs from the ClickyAPI a bit easier too. We’ll see!

Meet Flipper – A jQuery Plugin to Change Image Src on Hover

Although we do come up with some original ideas at The Longboard Store – we too find inspiration from other online stores as well.  So my boss sent me a link to a Macy’s page and had me hover over some of the product images.

Thus Flipper was born.

Flipper is a super-duper small jQuery plugin that facilitates swapping of image sources on hover. It doesn’t do any fancy fade affects like the one on Macy’s (it could, but why?), but it does pre-load the alternate image for a smooth flipper experience. Now board shoppers can checkout the top and bottom graphics of the boards – all from the same page!

Simple Maps via Google Static Maps

I love maps. When I first laid eyes on Google Maps I was blown away… and when I began dabbling in adding layers of topo maps, I was smitten (I suppose I should have gone into GIS). Anyhow, whenever there is the slightest reason to drop a map on a web page, I am there, Google Maps JavaScript API in hand.

So when I went to add in tracking data on the order status page at The Longboard Store, the new functionality was just screaming for a map. I mean, how cool would it be to watch your order status page, and see where your sweet new Landyahctz Longboard was at?

As such, I dove in, dropping in the JavaScript needed for a map… plopping a marker down… but it kind of dawned on me that it seemed a bit heavy for what is a very basic map. A quick search yielded a Google product that I was unaware of: Static Maps.

Simply put, the API for Static Maps simply involves a standard image tag, where some GET attributes are added into the src tag, and magically a map is shown on your page:

No loading of a JS resource needed, heck, no scripting needed at all. Just a simple url:

http://maps.googleapis.com/maps/api/staticmap?center=45.5626214,-122.6591902&zoom=12&size=567x200&maptype=roadmap
&markers=color:blue%7Clabel:%7C45.5626214,-122.6591902&sensor=false