YSlow’s Smush.it Adds File Uploader
by jim on March 24th, 2010Almost all of the images on Bargaineering are stored in a local directory. My experience with Flickr has taught me that it’s all too uncommon for a photographer to remove a photo and have things look silly on my site. To Flickr’s credit, they replace it with a nice “This photo is no longer available” image, rather than an ugly broken 404 image. So in response to this, I search for CC-licensed images and I download them locally. I put them through Yahoo! Yslow’s Smush.it and upload them to the site.
Storing images locally is a trade off. You get that control but there’s increased server load, the risk that someone hotlinks an image thus creating more load (though you can stop this easily), but you get one less lookup. I think it’s worth it.
I didn’t always do this and my directory had tons of files that were un-smushed, so I was pumped when the recent update to Smush.it included an uploader tool. This lets me download all of my image files, smush them in batches, rewrite some filenames, and upload them back to my server.
The “rewrite some filenames” piece is the result of Smush.it converting GIFs to PNGs, PNGs are better because they’re more efficient, and you can do that by running this file renaming .JS script file in the directory.
I was able to trip a good 20% off the size of my image directory using Smush.it for about thirty minutes.
How to Get Rid of Feedproxy Links in Your RSS Feed
by jim on March 11th, 2010Paul at Providentplan.com emailed me the other day because he had a vexing problem. It appears that all of his links in his RSS feed are a redirect through feedproxy.google.com. He has his feed hosted through Feedburner, now owned by Google, and wanted them “back to normal.”
…for some feeds in my Google Reader the link to the post is feedproxy.google.com followed by a bunch of junk. (It still takes you to the website.) But other feeds go straight to the post on the website.
I’m wondering why this is and how you can fix it because I’ve noticed it for my own website.
Fortunately there is a simple solution. If you have feedburner’s click tracking feature turned on, it’ll turn all those links to the “gibberish” feedproxy links. They’re redirects for tracking purposes and you need to remove tracking to get the links back to normal.
To turn it off, log into your Feedburner account and click on the Analyze tab. In the left sidebar you’ll see under “Services” a link that says “Configure Stats.” Click it and you’ll see a screen where you can modify tracking. Uncheck the boxes and you’ll see your links return to normal.
Rewrite & Rename Filenames using Javascript
by jim on March 8th, 2010Ever need to a search and replace with a folder of filenames? You saved a bunch of images from your camera as Steve and Michelle Wedding when you meant Stephen and Michelle? Or you put the wrong date or otherwise need to change a lot of filenames and don’t feel like doing it manually?
Fortunately you can use javascript to do the work for you. Javascript is very versatile and perfect for these quick and dirty solutions where you don’t need something complex, just a little script that goes into a directory and replaces all instances of one word, or string, with another. I adapted this script from this snippet.
In this example, I’m going to rename all the files that end in .gif.png so that they end in just .gif. The code will replace all instances of .gif.png, even if they appear in the middle of a filename (so image.gif.png.jpg will be renamed image.gif.jpg), but I know that in my directory this won’t happen because of the files I have inside of it.
Again, this is a quick and dirty script, no error checking and is not a robust solution. Remember to make your edits to the values before you run it.
var sFolderName, sStringToFind;
var nResult;
//////////////////////////////////////////
// Set these values
sFolderName = "C:\\Temp\\Images"; // use directory containing image
sStringToFind = ".gif.png";
sStringToReplace = ".gif";
//////////////////////////////////////////
nResult = renameFiles(sFolderName, sStringToFind, sStringToReplace);
WScript.Echo(nResult + " files renamed");
// Function Name: renameFiles
// Parameters:
// sFolder: Folder Name (use double backslashes)
// sString1: String to search for
// sString2: String to replace
// Returns: Number of files renamed
function renameFiles(sFolder, sString1, sString2) {
var oFSO, oFile, oFolder;
var re, index;
var sName;
var i = 0, n;
oFSO = new ActiveXObject("Scripting.FileSystemObject");
oFolder = oFSO.GetFolder(sFolder);
try {
index = new Enumerator(oFolder.Files);
for (; !index.atEnd(); index.moveNext()) {
oFile = index.item();
sName = oFile.Name;
n = sName.indexOf(sString1);
if(n != -1) {
try {
sName = sName.substring(0, n) + sString2 +
sName.substr(n + sString1.length);
oFile.Name = sName;
i++;
} catch(e) {
WScript.Echo("Can not rename file " + sName + " because\n" + e.description);
}
}
}
}
catch(e) {
WScript.Echo("Could not access folder " + sFolder + " because\n" + e.description);
return 0;
} finally {
oFSO = null;
re = null;
return i;
}
}There you have it, a quick search and replace javascript for renaming files.
How to Track Clicks with Google Analytics
by jim on February 24th, 2010Google Analytics makes it dead simple to track outbound clicks on your site.
First, you need to put your Google Analytics code above the content of your page (or at the very least, before any link you want to track). The function call you will add to the OnClick javascript hook will reference a function in the Analytics code so it needs to be loaded by the time you get to the link. Page speed principles recommend that you put javascript at the bottom, since there can be a little lag in loading it, but in this case there’s no way around it. Google is pretty fast anyway so I consider this a fair tradeoff for additional data.
Then, simply add this bit to your links (if you use Google Website Optimizer, you’ll notice it uses the same mechanism to track clicks):
onClick='javascript: pageTracker._trackPageview("/click/tracking")'You can change /click/tracking to anything you want. I like to bucket my tracking into different areas and change the term tracking to something that makes sense to me. If it’s affiliate clicks I might put /click/aff/company/tag and programmatically change the company name or the tag based on the page. (you can use php to do this).
Let’s say you want to track a click on an affiliate link on a particular page, you could do this if you were running WordPress:
onClick='javascript: pageTracker._trackPageview("/click/affiliate/<?php echo $post->ID; ?>")'which would resolve to:
onClick='javascript: pageTracker._trackPageview("/click/affiliate/XXXX")'with XXXX as the ID of the post.
(remember, to run PHP in a post on WordPress you’ll need to download a php execution plugin and turn off comments for security)
How do you review the data? Go into your Google Analytics and each of the clicks is considered a pageview. I review it by going to Content -> Top Content – View full Report and then searching on the term /click/. Advanced users of Analytics now recognize that you can start assigning goal values and whatnot but I generally avoid that because I don’t find that adds value.
How to Add a Reddit Button to Your Site
by jim on February 15th, 2010As your site grows, the likelihood that it gets submitted to a social news site like Reddit also grows. When that happens, you’ll want to get it as many upvotes as possible so that it can become more popular. The best way to do that is leverage your existing visitors, hoping they will have Reddit accounts and having them give you the votes to put you over the top. It’s as simple as putting in this snippet of code to your page.
<script type="text/javascript" src="http://www.reddit.com/button.js?t=1"></script>
The cost of putting a button like this on a page is that it’s an extra javascript call to an external server. While the cost may seem minimal, it’s enough that you probably don’t want to put this type of button on every post in the hopes that someone clicks on it. If you just want a standard static reddit button, you can do this instead:
<a href="http://www.reddit.com/submit" onclick="window.location = 'http://www.reddit.com/submit?url=' + encodeURIComponent(window.location); return false"> <img src="http://www.reddit.com/static/spreddit7.gif" alt="submit to reddit" border="0" /> </a></script>
It’ll put something like this:

If you want to make it a bit faster, download the image and store it locally.
How to Password Protect a Web Directory
by jim on February 9th, 2010The easiest way to put password protection on a directory of your website (this assumes you’re running Apache) is to take advantage of the basic authentication features of Apache. htpasswd is the command you’ll be using to create and update the files that will store your usernames and passwords.
Create the directory you want to protect and navigate into it. Next, run the “pwd” command, that will give you the full pathname of the directory. Create and edit the .htaccess file in that directory, it should have this at the top:
AuthUserFile /usr/you/hidden-directory/.htpasswd AuthGroupFile /dev/null AuthName "Super secret directory" AuthType Basic <Limit GET> require valid-user </Limit>
First line, AuthUserFile, indicates the location of your password file. You should replace /usr/you/hidden-directory/ with the information from the “pwd” command. AuthGroupFile, which we have set to dev/null, sets the list of user groups for authentication but we won’t be needing that. You will limit the users based on who has a username and password set in the htpasswd. AuthName sets the title of the username/password dialog that the users will see asking them to log in. Finally AuthType sets whether you want the password to be MD5 hashed (digest) or not (basic). For most cases, basic will work fine, but if you are concerned someone is sniffing your data, you should use digest.
If you use digest, you’ll have to follow a different set of instructions as you will be using htdigest instead of htpasswd. Remember, while the password is encrypted, any of the subsequent data you send or access will not be. You can read more about it here.
I put the .htpasswd file inside the hidden-directory so from here I just create a new user using htpasswd:
htpasswd -c .htpasswd [new_user]
You will be prompted for a password and the user will be created.
If you already have an .htpasswd file and want to append to it, use this instead (take out the -c):
htpasswd .htpasswd [new_user]
If you run into any problems (such as forgetting your login), you can always delete the .htpasswd file and recreate it.
How to Set Up an Affiliate Link Redirect System
by jim on January 25th, 2010Most websites that do any affiliate marketing will almost never run naked affiliate links on the site. Using redirects has several benefits over plain affiliate links:
- Easier to maintain. If you need to swap out all the links from one affiliate company and replace them with another, it’s impossible if you have to change the link on every page. Change it at the redirect and save yourself tons of time.
- Looks cleaner. Most affiliate links look like a string of random letters whereas your redirects can be cleaner, using company or product names rather than a string of jumbled letters.
- Lets you track clicks better. Before the days of Analytics, the easiest way to track clicks was to record it in your database and that was only possible if you use redirects. Now, you can just javascript to track it in Analytics or, if you are concerned that many visitors have disabled javascript, you can still use database calls to record clicks.
The reason I use redirects is mostly because of the first reason – maintenance. I prefer it over other solutions like GoCodes (a plugin that achieves the same result) because the way I’ve implemented it requires no additional database calls and is pretty much as fast as you can get.
Setting Up The Redirect Scripts
<?php include('allredirects.php'); $tag = htmlspecialchars($_GET['tag']); $link = "<strong>[the url]</strong>".$tag; header("Location:".$link); ?>
The links themselves will look like this –
The above code will pull the variable out of the URL (in the above case, it’s “SubID”) and append it to the affiliate link. You will have to look at the affiliate link to know where that information goes.
For example, for CJ, you take your affiliate link and append ?sid=XXXX to the end to pass along that SubID tracking value.
The include(‘allredirects.php’); is an empty file that I left in there in the event I wanted to add something to the start of all redirects. Years ago, before Google Analytics, I had it insert data into my database to help me track clicks. Nowadays there’s a far simpler solution.
Tracking Clicks
Often times the affiliate network will provide this data but if you don’t trust them or you want to verify their data, you can add your own tracking. Tracking clicks is dead simple with Google Analytics. Simply take the link and add the following call in the OnClick function:
onClick='javascript: pageTracker._trackPageview("/click/affiliate/tag")'You can change /click/affiliate/tag to whatever you want but every time someone clicks, Analytics tracks it. Then, you can go into analytics and search for “click” or “click/affiliate” to see how many clicks you have on those links. Replace tag with the SubID and you get even more data to work with.
One tip, you will need to move your javascript for Google Analytics above these calls for it to work. I put mine in the header.
One script or many?
In the above example, there’s one .php file for each redirect. Another alternative is to use one script for every redirect and just pass in two variables – one for the subID and one for which affiliate link to use.
What you do is up to you, I personally like the individual pages though it really affords no significant advantage.
Wasn’t that simple?
How to Load Adsense In Any Order with Javascript
by jim on January 19th, 2010Adsense loads the highest paying ads first, so it’s recommended that you load your highest CTR ads first to maximize advertising revenue. In my last post, I didn’t discuss the mechanics of changing the order of your Adsense (other than offering up some CSS code) because I wanted to address it better today. In that post, I said you could use fancy CSS to do it, and that is certainly one option, but here’s a simpler javascript way of doing it.
In addition to increasing revenue, you can use this strategy to improve your site’s load time. The general consensus is that when loading a page, you want to load javascript last whenever possible. That’s because most browsers render the page from the beginning of the source to the end and will pause whenever there are any delays, such as when loading javascript. If you’ve ever wondered why some people recommend that you use the height and width tags on images, that’s why (images also take a relatively long time to load, so if you can specify their screen dimensions then the browsers can continue rendering).
Here’s what the approach will be:
- You will put an empty <div> block as a placeholder for where your ad will appear.
- You will put a hidden <div> block in the footer that contains your Google Adsense javascript code.
- You will add two lines of Javascript code to be executed on the window.onload event. The two lines of code will append your Google Adsense javascript code DIV to your empty placeholder DIV and then unhide it.
1. Empty DIV Block Placeholder
Stick this line of code, changing “GoogleAdsenseBlock” to something descriptive, wherever you want to insert Adsense:
<div id="GoogleAdsenseBlock"></div>
2. Hidden DIV Block in Footer
For each one of your DIV Block placeholders, add a hidden DIV block in the footer:
<div id="GoogleAdsenseCode" style="display: none;"> <strong>[Google Adsense Code]</strong> </div>
Here’s where the Adsense blocks are being loaded, so order these from highest CTR to lowest. For example, if you have a header and a sidebar block, you would want to load the sidebar’s hidden DIV block first (assuming it has a higher CTR).
3. Shuffling DIVs with Javascript
Once you’ve created all the empty placeholders and loaded the Adsense javascript in hidden blocks, it’s time to stick them in the right places and make them visible.
<script type="text/javascript"> window.onload = function() { document.getElementById('GoogleAdsenseBlock').appendChild(document.getElementById('GoogleAdsenseCode')); document.getElementById('GoogleAdsenseCode').style.display = ''; } </script>
The first section tells the code to execute whenever the window.onload event first. The first line of actual code takes your footer DIV block and appends it the placeholder. The second line takes away the display: none, which was hiding the second block from view.
Are there drawbacks to this? A small one. When you load your site, the page will initially render the page without the Adsense and then it will pop in once the page has completed loading (that’s the onload event firing). This is necessary or Internet Explorer will get upset.
Mucho gracias to Ed at Semplice, who came up with the code.
Accumulate Link Equity by Shuffling Annual Reference Posts
by jim on January 11th, 2010Chances are your website has some reference-types of posts that are refreshed every year. In personal finance, there are plenty like IRA contribution limits or the income tax brackets. One great strategy that can help you accumulate more links is to make the post URLs dateless and shuffling the content around each year.
For example, let’s say you have a post on 2009 IRA contribution limits with the following URL:
http://www.yourblog.com/2009-IRA-contribution-limits.html
In 2010, I recommend that you use this URL for the 2010 version of the post:
http://www.yourblog.com/IRA-contribution-limits.html
When 2011 rolls around, create a new page:
http://www.yourblog.com/2010-IRA-contribution-limits.html
Move all the IRA-contribution-limits.html content into the new 2010-IRA-contribution-limits.html page and update the IRA-contribution-limits.html version with the updated information. The titles of the pages themselves should retain the date, it will help the reader know more clearly what year the information applies to.
This lets the dateless URL accumulate links, thereby increasing its link profile, while keeping the data fresh and accurate. This also gives people a chance to find the archived reference information should they need that as well. This won’t pay huge dividends at first but after a few iterations, you will see good results. At the very least, your site won’t be competing with itself.
Don’t Blindly Trust Another Site’s Results
by jim on January 4th, 2010I’ve been writing a lot about optimization, be it improving click through rate or site responsiveness, lately because it’s something I’ve been focused on the last few weeks. Getting more traffic is harder than optimizing your site so that it offers the best information to the traffic you’re already getting. Boosting your conversion rate by making your content more appealing is a lot easier than trying to get more eyeballs!
So in some of my posts I’ve been sharing what has worked well for me and there may be a temptation for you to blindly implement them on your site – I advise against it. In fact, I advise taking any results anywhere and blindly implementing them without any data because you don’t know how that change will perform on your site.
Let’s take a prime example -Amazon.com. It’s a well known fact that Amazon.com tests almost every aspect of their site. With their traffic and their optimization brains, it’s obvious that they are probably very close to “perfect” when it comes to the buying experience. The start of that buying experience is the product page and the pivotal action on that page is clicking that Add to Shopping Cart button.

The orange “Add to Shopping Cart” button with the navy blue text is the highest converting button for their layout and that’s after years of optimization and study. Does that mean you should apply it on your site blindly?
Nope. To test this theory, I tried a few buttons on Bargaineering, including their orange button, and my results were different. I had four options, one text link and three buttons. Each button had the same text, were placed in the same place, and I simply calculated CTR (I did this study long ago and so I don’t have more data than this to offer):
- Text – 1.71%
- Green Button – 6.44%
- Blue Button – 5.08%
- Orange Button – 3.38%
The Amazon orange button performed better than the text but worse than both green and blue. When I had to guess, my guess was that the predominately blue layout of Bargaineering made the green and blue buttons more appealing. In a head to head test, green outperformed blue.
The one color I didn’t test was Red, because the general consensus advice was that red was a “stop” color. It catches the eye but it tells people to implicitly “stop.” However, based on my own advice, I should try red to see if it performs better.
There are two lessons out of this – always test ideas for your site with real data and always use a button.
