Wednesday, November 12, 2014

Samsung Galaxy S5 Black Friday Deals at WalMart, Target, and Best Buy

If you have been waiting to pick up a Galaxy S5 until Black Friday comes around, you are in luck this year! Wal-Mart, BestBuy, and Target all have excellent deals.

Starting at Best Buy, you can get the Galaxy S5 for $1. A few hours later, you can get the Galaxy S5 for $0.01 at Target. The next morning, on Black Friday itself, you can get paid $1 to get the Galaxy S5 from Wal-Mart. Yes, they charge $99 and include a $100 Wal-Mart gift card! All of these deals require new/upgrade 2yr contracts of course, but that doesn't mean there aren't good cash and finance deals as well. I will be looking for a good deal on a Galaxy Note 4 but will likely go for the practically free Galaxy S5.

Samsung Galaxy S5 at Best Buy for $1 at 5pm Thanksgiving, Day before Black Friday

Samsung Galaxy S5 at Target for $0.01 at 9pm Thanksgiving, Day before Black Friday

Samsung Galaxy S5 at Wal-Mart for -$1 at 6am on Black Friday ($99 w/ $100 Gift Card Included)

Good luck to all you Black Friday shoppers!

Sunday, September 7, 2014

ColdFusion CFHTTP and WebDav

As it turns out, I recently ran into the need to interface with a WebDAV server via ColdFusion. Surprisingly, there is practically no information online regarding this topic. I just wrapped up a test PUT file snippet and figured I would share it with all you ColdFusioneers who aren't finding the copy/paste you are looking for :-).

First off, you can't simply use cfhttpparam type="file" as you'll end up sending file data with headers included in the body of the request. The WebDAV server will write these headers into the file content and you'll end up with a corrupted file. Instead, the WebDAV spec calls for the entire body of the request to be file data.

That leads us to the following code. You'll see this is uploading a simple jpeg to the WebDAV server. The cffile readbinary file attribute is being set to the full local file path. The cfhttpparams include the typical Content-Type header, but also Overwrite and Translate which are commonly supported and sometimes required by WebDAV servers. The body of the request is the raw binary file data. Simple!


<cffile action="readBinary" file="#loc.images[curr_image]#" variable="loc.curr_binary">
<cfhttp method="PUT"
url="#This.webDAVsettings.server#/import/#loc.curr_filename#.jpg"
username="#This.webDAVsettings.username#" password="#This.webDAVsettings.password#"
throwonerror="true">
<cfhttpparam type="header" name="Content-Type" value="image/jpeg">
<cfhttpparam type="header" name="Overwrite" value="T">
<cfhttpparam type="header" name="Translate" value="F">
<cfhttpparam type="body" value="#loc.curr_binary#">
</cfhttp>

Tuesday, September 2, 2014

Taming the Elusive 5 Column Bootstrap Layout

Twitter Bootstrap is one of the best things to happen to web development in recent years. Bootstrap 3 brought some awesome changes, but still there are troublesome areas. One the most common is setting up 5 column rows. Sure, you can build a custom compiled Bootstrap with a 20 column grid system or something, but most of us use vanilla Bootstrap. Thanks to SICC, we have a great solution for 5 column rows in Bootstrap 3. Simply add the following to a custom CSS file (no need to alter the Bootstrap CSS).

Core CSS

.col-xs-15,
.col-sm-15,
.col-md-15,
.col-lg-15 {
    position: relative;
    min-height: 1px;
    padding-right: 10px;
    padding-left: 10px;
}
.col-xs-15 {
    width: 20%;
    float: left;
}
@media (min-width: 768px) {
    .col-sm-15 {
        width: 20%;
        float: left;
    }
}
@media (min-width: 992px) {
    .col-md-15 {
        width: 20%;
        float: left;
    }
}
@media (min-width: 1200px) {
    .col-lg-15 {
        width: 20%;
        float: left;
    }
}


General Use

<div class="row">
    <div class="col-md-15">
    ...
    </div>
    <div class="col-md-15">
    ...
    </div>
    <div class="col-md-15">
    ...
    </div>
    <div class="col-md-15">
    ...
    </div>
    <div class="col-md-15">
    ...
    </div>
</div>


Sunday, April 13, 2014

Forcing Google to NOT Crawl and Index Mobile Site

Let's assume you've got a desktop site and a mobile version on different subdomains or subdirectories. Google might actually index your mobile site's URLs and serve them up in desktop search results... yes, I have been a victim of this and seen it myself (see screenshot below). It is surprising, but Google can't get this right 100% of the time.
Desktop search result with mobile URL in Google index
So what do you do?

You have two main options to force Google desktop to crawl your desktop site and Google mobile to crawl your mobile site. Setup Webmaster Tools to specify this setup and/or modify your robots.txt. The Webmaster Tools option pretty much consists of registering both sites in Webmaster Tools and setting up distinct sitemaps. This still leaves a lot to chance assuming Google will take these directions when indexing your URLs. Also, this only works if your mobile site is on a different subdomain. If your mobile site resides in a subdirectory, like http://www.gtautomax.com's mobile site (http://www.gtautomax.com/mobile/), then you are left with robots.txt modification as your main option.

The strategy is to direct Googlebot and other desktop search bots away from the mobile site and allow Googlebot-Mobile and other mobile search bots to access the mobile site. (This assumes your site is already redirecting users from desktop URLs to mobile URLs automatically.)


If you have different desktop/mobile subdomains, your robots.txt will look something like this:

Desktop Site:
User-agent: Googlebot
User-agent: Slurp
User-agent: bingbot
Allow: /

User-agent: Googlebot-Mobile
User-Agent: YahooSeeker/M1A1-R2D2
User-Agent: MSNBOT_Mobile
Disallow: /

Mobile Site:
User-agent: Googlebot
User-agent: Slurp
User-agent: bingbot
Disallow: /

User-agent: Googlebot-Mobile
User-Agent: YahooSeeker/M1A1-R2D2
User-Agent: MSNBOT_Mobile
Allow: /


If your desktop/mobile sites are differentiated by subdirectory, then your robots.txt will look something like this:

Desktop Site:
User-agent: Googlebot
User-agent: Slurp
User-agent: bingbot
Disallow: /mobile/

Mobile Site:
User-agent: Googlebot-Mobile
User-Agent: YahooSeeker/M1A1-R2D2
User-Agent: MSNBOT_Mobile
Allow: /mobile/


As always, make sure and check your robots.txt file in Webmaster Tools for any errors and to ensure mobile URLs and desktop URLs are handled properly.

Friday, March 14, 2014

Google AdWords Event Based Conversion Tracking

If you've ever implemented AdWords, you've probably dropped a conversion tracking snippet in your code that looks like this:

<!-- Google Code for Conversion Page -->
<script type="text/javascript">
/* <![CDATA[ */
var google_conversion_id = 123456789;
var google_conversion_language = "en";
var google_conversion_format = "3";
var google_conversion_color = "ffffff";
var google_conversion_label = "12345678-123-123456";
var google_remarketing_only = false;
/* ]]> */
</script>
<script src="//www.googleadservices.com/pagead/conversion.js" type="text/javascript">
</script>
<noscript>
<div style="display:inline;">
<img height="1" width="1" style="border-style:none;" alt="" src="//www.googleadservices.com/pagead/conversion/123456789/?label=12345678-123-123456&amp;guid=ON&amp;script=0"/>
</div>
</noscript>


This works great for success or landing pages, much like simple URL based goals in Analytics. However, just like Analytics, simple URL based goal/conversion tracking doesn't always cut it. Analytics offers Event tracking to allow more control over tracking goal conversions (even automatically).

So what about when you need to track AdWords conversions more programmatically though? For example, tracking a link click as an AdWords conversion. Luckily, the AdWords conversion logic makes this easy. See the <noscript> part of the tracking snippet? Typically the most useless part of the code, this is actually our lucky break. Throw in some jQuery and you've got event based AdWords conversion tracking! I also threw in some Analytics event tracking for good measure (the _gaq.push() portion).


$(document).ready( function() {
  $("#conversionLink").click( function() {
    $('body').append('<br /><div style="display: inline;"><img alt="" height="1" src="//www.googleadservices.com/pagead/conversion/123456789/?label=12345678-123-123456&amp;guid=ON&amp;script=0" style="border-style: none;" width="1" /></div>');
    _gaq.push(['_trackEvent','Conversion Link', 'Conversion Link Click']);
 });
});

Wednesday, November 6, 2013

Tracking Vimeo Video Events into Google Analytics, the Easy Way!

So you've got an awesome website and an awesome video hosted on Vimeo. You dropped the Vimeo hosted video into your page like so:



But now you have no way of tracking the video events in Google Analytics. Did your paid traffic play the video? Did your organic traffic complete your video? Did most people stop watching after the first 25%? These questions can now be answered by dropping in a single jQuery powered JavaScript.

Big thanks to Sander Heilbron for the original which supports ga.js, Google's widely used asynchronous tracking script. I have built on his code and added support for the Universal Analytics analytics.js syntax at https://github.com/MrRobWad/vimeo.ga.js.

The script detects which version of Analytics you have (ga.js or analytics.js) and tracks events accordingly.

Events being tracked include:
  • Vimeo played
  • Video paused
  • Video completed
  • Video skipped forward or backward
  • Video reached 25%
  • Video reached 50%
  • Video reached 75%

Thursday, October 24, 2013

No Code Required - Auto Analytics Event Tracking with Google Tag Manager #GASummit2013

Coming off of the Google Analytics Summit 2013, some exciting things have been officially announced!

The most exciting to me is an update to Google Tag Manager that allows Analytics Event Tracking to be setup without writing any code! As a developer, it is an ongoing battle to keep Analytics running at its best with some random SEO/marketing group messing around with URL based events and sloppily throwing together Analytics goals without even telling anyone. This is a dangerous practice when the person setting up the goals doesn't understand how the site works.

Event-tracking is the best solution for tracking site data in a surprisingly large number of cases, but if the client doesn't communicate their needs to the developer and the marketing company doesn't reach out either then how can the developer know that Event Tracking should be implemented? They can't... and even if there is great communication all around and all parties agree that Event Tracking should be implemented, it still takes custom coding to make it happen. With these barriers, Event Tracking surely doesn't get used as often as it should.

With the new Auto Event Tracking in Google Tag Manager, a developer simply needs to implement tracking via Tag Manager and then the client, marketing company, or developer themselves can login and add custom Event Tracking without ever editing the code on the website. Too good to be true? It kind of is... Auto Event Tracking isn't for the faint of heart. It requires some Analytics know-how and a certain degree of developer style logic to make the pieces come together. In the end, someone experienced with Analytics implementations should still be generating the Auto Event Tracking rules, but this new system does allow for much better transparency and collaboration across all parties involved.


Thanks to Justin Cutroni for a good Auto Event Tracking video tutorial of the changes and features.

I am looking forward to trying this out on my next project. Anyone implemented it already? What do you think?