Installing WP-CLI on OS X Mavericks

08 Mar
March 8, 2014

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

14 Apr
April 14, 2013

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

31 Oct
October 31, 2012

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

13 Sep
September 13, 2012

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

29 Aug
August 29, 2012

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

19 Jun
June 19, 2012

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

Crowd Sourcing E-Commerce Photos

21 May
May 21, 2012

There is no longer any doubting the power of mobile phones, and in particular the ability to rapidly share photos with hipster-esque filters applied. After all, we can all cite theone billion$reasons for this.

So when the idea was hatched at thelongboardstore.com to add in some social photo aspect to our site, I was very excited to bring the functionality to life.

Photos By The People, For The People

The concept is rather simple – tap into the massive growing user base of Instagram, and our customer’s mobile devices to power photos for the website. A majority of our customers are in the younger crowd, so why not give them a way to post pictures of what they love – their longboards.

Instagram Photos in Product Detail Page

So all a friend of thelongboardstore.com needs to do is tag any photo with #thelongboardstore within Instagram, and the rest is Rails/Instagram API magic.

Some Code, Some Moderation

To implement the new feature, I leveraged the `official` Instagram ruby gem:

#Gemfile
gem "instagram"

And depending on how you roll with your configuration options, simply add something like so:

#/config/initializers/instagram.rb
Instagram.configure do |config|
config.client_id = "z0mgcl13nt1d"
config.access_token = "s3cr3ts4u1r3ll"
end

For data modeling, I setup a has_many through relationship for Instagram media to our `Product` model. This allows a given photo of a longboard, or a truck, to be attached to many products on the public-facing side of our website. Super social huh?

With all that in place, the process of fetching photos from the Instagram API to persist in our system is so simple it hurts:

instagrams = Instagram.tag_recent_media('thelongboardstore', {:min_tag_id => @last_import_min_tag_id})

The min_tag_id option is a timestamp of sorts that Instagram passes back in their response. This allows the developer to specify a point in time to search for photos.

I iterate over the result set, and add the new photos into a moderation queue in our Admin interface… because you can’t always trust people to do the right thing, and it allows us to attach photos to products.

In Moderation

In-House Efficiencies

The perks of the social photo aspect are obvious for our site visitors. It gives them a way to share their stoke with us, and the rest of the community, and it offers a great glimpse at our products in-action… in a way its almost as good as an in-depth review of the board.

One other awesome thing that has come of the new system though is how we are using Instagram in-house for adding detailed photos to our products. We currently shoot all of our own product photos at the shop – stock photos are just so, well meh. But now, any person in the shop can take a few snapshots of a deck from a different angle, or a close up detail shot of a graphic and add it to the site.

The process is extremely fast, and really fun as well. In the first day alone, two folks at the shop added close to 100 photos. One Hundred. In a single afternoon.

I’m curious to see how our customers start using the system. This morning there were a dozen or so pictures in the queue from them. Furthermore, the Instagram API option of subscribing to tags or geographic areas has got me thinking of a few other applications to use with the service.

Omniauth and Facebook’s #_+_

23 Apr
April 23, 2012

I’m in the process of implementing a new review system for thelongboardstore.com and am using Omniauth to allow users to sign on via their Facebook account. All is happy and well, but there is a known issue with Facebook where they append ‘#_+_’ to url’s when redirecting a user back to your application.

Being foolish stubborn, I attempted various work-arounds for this one… up to and including nginx re-writes, rack middleware, and cursing. In the end, the functioning work-around is to follow the advice at stackoverflow and reset the hash via javascript:

window.location.hash = ""

As such in my implementation, I have set an instance variable to determine if the user is being redirected from Facebook, and redirecting them upon page load to a new page where the #_+_ doesn’t totally tank my JS:


<% if @show_review -%>
if(window.location.hash.length > 0){
window.location.hash = '';
window.location.href = "<%= @product.url %>?review=1";
}
<% end %>

Ghetto, hack, ugh.

SMS In-Stock Reminders with Twilio

19 Apr
April 19, 2012

We have all been in that place.  After scouring the web for that latest *must have* toy, and just as you are ready to add to growing debt you see the dreaded words – OUT OF STOCK.

At thelongboardstore.com, such scenarios often resulted in young shredders contacting us via email, or even phone, asking when that super sick Landyachtz Evo deck was going to be available again.  Indeed something had to be done… the consumers want their stuff, so we brewed up a fancy new In-Stock reminder tool to satisfy the retail hunger.

New School and Old Skool

The feature is far from ground-breaking in the online retail world.  Many large e-tailers for years have been offering email-based reminders to shoppers to receive an alert when their desired item is back in stock.

But since a majority of the shoppers at The Longboard Store tend to be in their teens and early twenties, it seemed natural to offer a similar notification service, but via SMS. Additionally, SMS obviously has some major advantages over email-based communications (no-spam folders for the message to die in, immediate customer attention), so we decided to create a system that offered both email and sms notifications.

Sign Up Flow

When a product is out of stock, the user is presented with a call to action to be informed when the inventory is replenished. The design of the page is somewhat muted/grey, and this call to action is rather prominent:

The subsequent page provides the shopper two options for notification, SMS or email. Nothing too exciting here.

When a user chooses the text option, a confirmation sms is sent via the Twilio API (using twilio gem). The user can click the link in the text -or- enter the confirmation code on the web form to confirm their alert subscription.

Waiting Game

Now the consumer waits, iPhone in hand, credit card warming in pocket for that alert to arrive. A few other things that happen during this time though are the buyers can evaluate the number of alerts for given products/brands and adjust buying decisions accordingly.

When our receiving department checks in product, our Rails application determines if the product being checked in has any alert subscriptions, and enqueue’s a job to send notification to our customers that their product is now in stock. Simple. Beautiful.

All About Conversions

Indeed the project was fun to do, and having Twilio in my programmer toolkit made it all possible, but in the online retail space, it all comes down to conversions. So after letting the system run for the first quarter of the year, I decided to analyze the numbers.

To determine if a given alert signup resulted in a paid conversion on our sites, I simply cross-referenced the email/mobile signups from the alert table with those in the billing and shipping addresses on orders. Granted, this won’t catch every possible conversion, it is fairly accurate and accommodates not being able to track conversions with cookies across multiple devices.

  Email Alerts SMS Alerts
Alerts Sent 638 314
Unique Recipients 558 261
Conversions 75 33
Rate 11.75% 10.50%

These conversion rates are obviously well above our overall conversion rate for site visitors, and more than justify the added (albeit minor) expense of sending a text message over an email. I was personally quite surprised to see users signing up for multiple alerts. This makes me think in a future iteration we should allow users to manage all stock alerts via one unified tool – and thus reduce the burden (and cost) of confirming a subscription for each product.

The Future

Ultimately the beauty of this system is opening yet another way to keep a ongoing conversation alive with our customers. Being able to leverage systems like Twilio to connect with first-time and returning customers on mobile devices will continue to be a growing part of our strategy at The Longboard Store.

One of Those Domains

19 Apr
April 19, 2012

I’m sure most web folk like myself have at least a half dozen of them.  We collect them like paper coffee cups from Starbucks strewn across our desks – once cherished ideas born during a bender – those *awesome* domain names we just had to buy!

The Original Idea

When I first set out on my new career path of a code slanger (circa 2006), I did what most programmers did back then… I created my very own CMS using PHP.  It was rad.  It still runs a few sites around the web actually.  To spare myself some jeering and giggles, I will not furnish a full list, but hey, the thing worked well… and still does.

I built this creation on top of CakePHP and the admin interface was created using a pre 1.0 version of ExtJS.  Super hot.  And the name I gave it was Haiku.  So I bought this domain.  For the longest time when you pulled up haiku2.com all you saw was this:

wing my target
I inflated my princes
under my gravel

So I decided to finally dust it off, install WordPress, and create my very own programming oriented blog.

Why?

Excellent question, and the answer is simple: Blogs Help.  Outside of stackoverflow, I think I have found so many answers to nagging coding questions in the greater blogosphere… so this is going to be my contribution to that grand resource online… and hopefully it will help some random folks out there.

Also, much like reading old code, I get a kick out of reading some of my old blog material.  I will continue to blog about personal items at my Posterous blog, but this will be the business side of my blogging mullet.  Enjoy, and thanks for reading.