Posts Tagged ‘WordPress’

Ad Logger ‘click logging’ plugin for WordPress

Tuesday, October 4th, 2011

Ad Logger for WordPress is a new plugin for logging clicks on iframe adverts and other social network buttons. At the moment it can log Google AdSense / Amazon Associates adverts, and Facebook, Twitter and Google +1 social media buttons. It also has a ‘catch-all’ mode which will log any other iframe clicks.

Clicks stats in one place – You can get statistics for all these services individually but Ad Logger allows you to see all the clicks in one place. It will however give you different number; Ad Logger counts raw clicks, whereas your ad/social media provider will count valid clicks.

Raw click logs – With Ad Logger you can see the raw logs which will give you information that your ad/social media provider probably won’t allow you to see such as IP address, page referrer, and browser agent.

Reports – Ad Logger has an AJAX UI to allow you to move through the results easily. As well as seeing the log you can view reports showing the which browser, referrer, page, IP most of your clicks come from. And you can filter the results to show all the logs for a specific IP, page, iframe type, etc by clicking on the type icon, or the ⇓ arrows.

Click bombing protection – As it has access to the raw click logs Ad Logger can help you to combat intentional or accidental AdSense ‘click bombing’ by disabling adverts if too many clicks are registered. It can disable ads that you may have inserted using the Ad Injection plugin, or by dynamically hiding the div that you have put the adverts into.

Ad Logger’s main UI

Here is the main UI, from top to bottom you can see the yellow message bar which I use to highlight the latest updates, then the navigation buttons. To the right of the navigation buttons are the report links.
Next is the main log table – you can see it combines clicks from AdSense, Amazon Associates, Facebook, Twitter and Google +1. You can click on the type icon or the ⇓ arrows to filter your results.
Under the table you can set how many rows are shown at once.
Next are the boxes to select which iframes are logged.
Then the optional click blocking preferences.
Finally you can configure what information is shown in the log table, and what information gets stored to the database.

ad logger main ui

Example Ad Logger report

This is the type report and shows how many clicks occurred on each type of iframe. Here you can see that there were 27 clicks on Facebook like buttons, and 5 on Google +1.

ad logger type report

Filtered report

By clicking on any of the ‘type’ icons you can filter your results to just that type. Here I clicked on the Facebook icon and so am just seeing Facebook button clicks.

ad logger filtered

How does it work?

Ad Logger works by using JavaScript to monitor whether a click has ‘probably’ occurred. I say probably because this method isn’t 100% accurate. It is pretty good though. It notes when the mouse pointer has entered the iframe, and then listens for a ‘blur’ even which corresponds quite well to someone clicking on the ad/social button.

Ad Logger does not modify your original ad code, so hopefully won’t break your ad provider’s TOS. I can’t however guarantee this, so you have to make a judgement call as to whether you think it is safe for you to use.

Results are stored in a new table in your WordPress database. This table can be cleared of data at any time, and it will be automatically deleted if you uninstall the plugin. The plugin limits the size of the table to 100,000 rows (this will be configurable in a later release).

If you have configured click blocking then Ad Logger will use a cookie to count how many clicks have occurred. If the limit is reached then Ad Logger can then set another cookie which will prevent Ad Injection’s ads from being added to new pages, and/or it can remove the div containing the ads from the current page.

How much does it cost?

Nothing! £0, $0! You are however welcome to make a donation via the plugin UI if you find it useful. I have spent several hundred hours of my own time producing this plugin, which I have now released under a GPLv2 licence.

How do I install Ad Logger?

Ad Logger is available for free from the WordPress plugin repository.

The easiest way to install it by searching for ‘Ad Logger’ from the ‘Add New’ link in the ‘Plugins’ section of the WordPress UI.

Future planned features

Future planned features include being able to block adverts by IP address (which will work either standalone with Ad Logger, or in conjunction with Ad Injection), more awareness of other iframe types, and possibly the ability to log non-iframe events. E.g. other advertising/affiliate link clicks.

Include a different advert in each WordPress post depending on category

Sunday, September 11th, 2011

I’ve had many requestes from people who want to include different adverts on each post according to the post category. One example would be a football website that has a different post category for each team. They might want different ads to show depending on the team. E.g. ads for Liverpool F.C. might not appeal to followers of Manchester United!

With Ad Injection there is no way to achive this directly in the UI, but by adding some simple PHP code to one of the ad slots you can do this.

1. In your plugins directory create a sub-directory called ‘ad-injection-ads’. e.g. /wordpress/wp-content/plugins/ad-injection-ads/

2. Create a text files in this folder for each of the categories that you want an ad for. The text files should be named [category nicename].txt The ‘nicename’ of the category is the category name with spaces and dots converted to ‘-‘ and apostrophes removed. e.g.

Liverpool = liverpool.txt
Manchester United = manchester-united.txt
A.F.C Aldermaston = a-f-c-aldermaston.txt
Bishop’s Stortford = bishops-stortford.txt

ad injection ad code box

3. Then put the code below (from the starting <?php to the closing ?>) into one of the ad box – shown above. The code will load the text file ad matching the category name when the post is displayed.

$plugin_dir = dirname(__FILE__);
$ad_dir = dirname($plugin_dir).'/ad-injection-ads/';
if (file_exists($ad_dir)){
    global $post;
    $categories = get_the_category($post->ID);
    foreach ($categories as $cat){
        // nicename: spaces and dots are converted to '-' and apostrophes are removed
        $full_ad_path = $ad_dir.$cat->category_nicename.'.txt';
        if (file_exists($full_ad_path)){
            $ad = file_get_contents($full_ad_path);
            if ($ad === false) echo "<!--ADINJ CATCODE: could not read ad from file: $full_ad_path-->n";
            echo $ad;
            break; // only show first category ad that matches
        } else {
            echo "<!--ADINJ CATCODE: could not find ad at: $full_ad_path-->n";
} else {
    echo "<!--ADINJ CATCODE: could not find ad directory: $ad_dir-->n";

Some extra information:

  • This code will load one text file ad per post. If for example you had a post with the categories ‘Liverpool’ and ‘Manchester United’ it would load which ever ad it found first.
  • If will ignore categories that have no text file in the directory. If you have a post with the categories ‘Liverpool’ and ‘Latest News’ then it will always load the liverpool.txt as long as you don’t create a ‘latest-news.txt’.
  • This code will only work in ‘direct’ ad insertion mode. It won’t work in ‘mfunc’ mode.

Expansion ideas:

  • Show a default advert if no text file exists.
  • Create multiple text files for each category and then randomly select one (shown below).
  • Use different code for top, random or bottom ads. e.g. you could have liverpool_top.txt and liverpool_random.txt

Randomly picking one advert from a pool of ads

Here is a more complex example which allows each category to have a pool of text ads to choose from. It will randomly pick a file that contains the category nicename as a substring. If the category nicename is ‘liverpool’ the code will pick out any files in the directory containing ‘liverpool’, e.g. ‘liverpool.txt’, ‘liverpool1.txt’, ‘liverpool2.txt’. If you put this code into the ‘random’ advert and want a different advert to appear in each slot you should tick the ‘Re-select an ad for each position on post’ box in the ad placement settings of Ad Injection.

if (!function_exists('adinj_filter_category_ads')){
function adinj_filter_category_ads($file) {
    global $adinj_filter_category_ads_filter;
    return strpos($file, $adinj_filter_category_ads_filter) !== false;
$plugin_dir = dirname(__FILE__);
$ad_dir = dirname($plugin_dir).'/ad-injection-ads/';
if (file_exists($ad_dir)){
    $files = scandir($ad_dir);
    global $post;
    $categories = get_the_category($post->ID);
    foreach ($categories as $cat){
        // nicename: spaces and dots are converted to '-' and apostrophes removed
        global $adinj_filter_category_ads_filter;
        $adinj_filter_category_ads_filter = $cat->category_nicename;
        $filtered_files = array_filter($files, 'adinj_filter_category_ads');
        $random_file = array_rand($filtered_files);
        $full_ad_path = $ad_dir.$filtered_files[$random_file];
        if (file_exists($full_ad_path)){
            $ad = file_get_contents($full_ad_path);
            if ($ad === false){
                echo "<!--ADINJ CATCODE: could not read ad at: $full_ad_path-->n";
            echo $ad;
            break; // only show first category ad that matches
        } else {
            echo "<!--ADINJ CATCODE: could not find ad at: $full_ad_path-->n";
} else {
    echo "<!--ADINJ CATCODE: could not find ad directory: $ad_dir-->n";

Randomly picking many adverts from a pool of ads

This will pick a selection of adverts from an ad pool and display them all without duplicates. The use case for this could be if you want to display a selection of adverts down your sidebar. You might have a pool of 20 adverts, and this code can pick any number of those and show them in random positions, without duplicating any adverts. Name your adverts ‘widgetadpool1.txt’, ‘widgetadpool2.txt’, etc. Then modify the ‘$i < condition' in the for loop to select how many of the adverts you want to show.

if (!function_exists('adinj_adhtml_filter_ads')){
function adinj_adhtml_filter_ads($file) {
    return strpos($file, 'widgetadpool') !== false;
$plugin_dir = dirname(__FILE__);
$ad_dir = dirname($plugin_dir).'/ad-injection-ads/';
if (file_exists($ad_dir)){
    $files = scandir($ad_dir);
    $filtered_files = array_filter($files, 'adinj_adhtml_filter_ads');
    for ($i=0; $i<10; ++$i){ // max num ads shown
        $random_file = array_rand($filtered_files);
        $full_ad_path = $ad_dir.$filtered_files[$random_file];
        if (file_exists($full_ad_path)){
            $ad = file_get_contents($full_ad_path);
            if ($ad === false){
                echo "<!--ADINJ RAND: could not read ad at: $full_ad_path-->n";
            echo $ad.'<br />';
        } else {
            echo "<!--ADINJ RAND: could not find ad at: $full_ad_path-->n";
        if (empty($filtered_files)) break;
} else {
    echo "<!--ADINJ RAND: could not find ad directory: $ad_dir-->n";

Ad Injection preview – WordPress ad management plugin

Tuesday, September 6th, 2011

Ad Injection (the plugin for injecting adverts into your WordPress blog) version should be out in a week or two (mid-September 2011). Here is a preview of some of the new features – the screen shots are from the unreleased version so the UI may change slightly before release.

New ad positioning options

Ad Injection already has many options for selecting exactly how the top, random and bottom ads are positioned. But some people need more control, so will have a load of new features.

ad injection placement settings

  1. With it will be possible to have the top ad start at a position other than at the very top. You will be able to choose a paragraph for it to start, or a character position. If you choose a character position the ad will appear at the next paragraph after your chosen character. The character count is based on the raw number of characters in the content (which includes HTML tags).
  2. Ad Injection has had the option to select which paragraph the random ads start at for a long time. Recently I added options to start the ads ‘at or after’ a paragraph/character position as well. The new will have options to start the ads from the middle of the post – particularly useful if you like a top, middle and a bottom advert. There are several different methods by which the middle position can be calculated.
  3. A brand new feature is to set a position to stop the random adverts. You can stop the adverts by paragraph/character count, in the middle of the post, or two thirds of the way down the post.
  4. These options were previously hidden away on the Ad Rotation tab. They all affect the ad placement settings so it made more sense to move them here.
  5. The bottom ad no longer has to be right at the bottom of the post. If you want it at the last-but-one paragraph, you’ll be able to do that.
  6. Another setting relevant to this section that was previously hidden away where you probably wouldn’t spot it.
  7. Instead of disappearing when you exclude all the home or archive ads, these sections will now fade away. This (I hope) makes it obvious that the options do exist, but that they are disabled.

Blogs with thousands of tags

I had been having intermittent reports that parts of the UI were not drawing on some blogs. I found out that this was caused on blogs that had large numbers of tags, but very little memory. The old Ad Injection would load all the tags at once (which on some blogs could be thousands).

A recent update to Ad Injection includes an update to load the tags in batches of 100, and the new version will move the filters section futher down the screen, so if you do run out of memory you will (hopefully) still be able to use the most useful parts of the UI.

ad injection filters

Minor UI tweaks

You can see in this screenshot the tick boxes which will become transparent instead of invisible in Ad Injection And on the right I’ve added the ‘days older than’ settings information to the summary. These are important settings so I think it makes sense to have the information easily visible.

ad injection global settings

New features :) / New bugs :(

This update will include major changes to the part of the code that does the insertion of advert into your post content. As such it may contain new bugs – but don’t worry I usually get bugs fixed pretty soon after they are reported. If you want to beta test the version contact me via the feedback form in Ad Injection, or via this website.

If you have any comments on the soon to be released Ad Injection please do get in touch.

You can download Ad Injection from the WordPress site, or from your blog by searching for ‘Ad Injection’.

How to point 1and1 domain to HostGator hosting

Friday, May 27th, 2011

Using HostGator for your web hosting, and 1and1 for your domain name is not too difficult to set up.

Configure HostGator so it knows about the domain name

First of all you have to make sure that your HostGator hosting account knows about the domain name. If you have already added the domain to your account by either setting it up as the primary domain or as an addon domain then you need do nothing further at the HostGator end.

If you haven’t done this then log into your HostGator cPanel. Then in the Domains section click on Addon domains.

hostgator cpanel

Enter your domain name and all the other details you need and click on Add Domain.

hostgator create addon domain

Configure HostGator so it knows about any email addresses

Whilst you are in the HostGator cPanel configure any email addresses for the domain name. Once you point the 1and1 domain to HostGator, 1and1 will no longer be responsible for collecting email to this address. HostGator will now have control of the email, so setting up any email boxes in advance to save you from losing any emails.

Configure 1and1 to point the domain to HostGator

Login to your 1&1 Control Panel. Click on Domains.

1and1 domain settings

Select the domain name you want to point to HostGator and click Edit DNS Settings from the DNS pull down menu.

1and1 edit domain dns settings

You’ll get a warning saying the following.

Please note:
Full functionality cannot be guaranteed if you choose DNS settings other than the original 1&1 settings, such as e-mail and web space. Domains can be (re)set to 1&1 default settings by clicking Reset

This means that if you change the name servers to point to HostGator then 1and1 will no longer be hosting your website, or your email. You will have to configure both your website and email via HostGator from now on.

Select the option for ‘My name server’.

1and1 point domain to hostgator hosting

Then enter the HostGator name server names (there should be two of them) into the boxes. You can find the name server names on cPanel.

hostgator name servers

Then confirm the settings on the 1&1 Control Panel. You’ll get a message saying it will take some time for the settings to take effect. This could be 24 hours, or even more depending on what DNS server you are using. After changing the settings keep checking the new domain so you spot when the changes are live you for. But beware – just because you can see the new site doesn’t mean everyone can. Leave the old site in place for at least 48 hours so you can be sure that all DNS records have updated.

Advanced topic – minimising downtime

If there is already a live website at your original 1and1 hosting then you might have to think about copying the files over to HostGator before updating the domain to minimise any website downtime. This is fairly easy to do if your website just contains static HTML files.

If however you are moving a dynamic website there is a lot more to think about.

Whilst the DNS settings are propagating some people will see the website from the 1and1 hosting, and others from the HostGator hosting. What if someone posts a comment on the 1and1 hosted site, and someone else posts on the HostGator site? It could be a nightmare to merge all the comments back together. You may therefore want to consider setting the old (1and1 hosted) site to read-only by disabling all new comments on it.

A further difficulty is that moving a dynamic site requires more than just moving the files. You will have to create new databases, import the database tables and maybe customise .htaccess files or other config files if the configurations need to be different between the two hosts (which is often the case).

One way to work around this is to set up the new version of the site in full at the new hosting provider using a secret dummy domain name. You can register a domain just for this purpose if you don’t have a spare one that isn’t in use. Just make sure not to tell anyone about it, and even better protect access to it to just your IP address using a .htaccess file.

There are a lot more complexities involved in moving a live dynamic site from one host to another. If you want more information about moving a WordPress blog between hosts have a look at

Ad Injection plugin for WordPress

Monday, December 6th, 2010

Ad Injection is a free WordPress plugin that injects any kind of advert (e.g. Google AdSense, Amazon Associates, ClickBank, TradeDoubler, etc) into the existing content of your WordPress posts and pages. You can control the number of adverts based on the post length, and it can restrict who sees adverts by post age, visitor referrer and IP address. Adverts can be configured in the post (random, top, and bottom positions) or in any widget/sidebar area. There's support for A:B split testing / ad rotation.

ad injection plugin for wordpress 1 450

PayPal – The safer, easier way to pay online.


Download Ad Injection plugin for WordPress for free from this link. Or just search for Ad Injection from your WordPress install and WordPress will automatically install it for you.


Automatic advert injection

The ads can be injected into existing posts without requiring any modification of the post. The injection can be done randomly between paragraphs, and there is an option to always inject the first advert at a specified paragraph (e.g. the first or second). Randomly positioning the adverts helps to reduce 'ad blindness'. Two additional adverts can be defined for the top and bottom of the content. Widget adverts can be defined as well for your sidebars.

ad injection plugin for wordpress 3 450

Widget support

Widgets can be added to your sidebars, or other widget areas on any pages. The same ad display restrictions that you setup for your other ads will also apply to the widgets.

Ad rotation / split testing

You can define multiple adverts for the same ad space which are rotated according to the ratios you define. Works with random, top, bottom and sidget/sidebar ads.

Ad quantity by post length

The number of adverts can be set based on the length of the post. It is a good idea for longer posts to have more adverts than shorter posts for example. Adverts can also be turned off for very short posts.

ad injection plugin for wordpress 4 450

Ads on old posts only

Adverts can be restricted to posts that are more than a defined numbers of days old. This prevents your regular visitors from having to see your ads.

Category, tag and post type filters

You can configure the adverts to only appear on specific categories, tags, or post types, or block the adverts from specific categories, tags or post types.

Search engines only (dynamic feature)

You can specify that ads should only be shown to search engine visitors (or from any other referring websites) so that your regular visitors (who are unlikely to click your ads) get a better experience of your site. You can define which search engines or any other referring sites see your adverts. A visitor who enters the site by a search engine will see ads for the next hour.

Block ads from IP addresses (dynamic feature)

IP addresses of people who shouldn't see your ads can be defined. These could be the IP addresses of your friends, family, or even yourself.

ad injection plugin for wordpress 2 450

Not tied to any ad provider

The advert code can be copied and pasted directly from your ad provider (Google AdSense, adBrite, ClickBank, etc) which will help you to comply with any terms of service (TOS) that state their ad code may not be modified.

Flexible ad positioning

Easy positioning options are provided for left, right, center, float left, and float right. Extra spacing can be set above and below the ad. Or if that isn't flexible enough, you can write your own positioning code using HTML and CSS.

You can specify a specific paragraph for random ads to start from, or if you need per-post control of the random adverts you can insert tags into the post source to say where the adverts should start and end.

ad injection plugin for wordpress 5 450

Inject PHP and JavaScript

As the plugin will inject whatever content you like into the page you can write your own ad rotation or a/b split testing code for the ads you inject. PHP code can be automatically executed.

Full documentation is available on the WordPress Ad Injection page.

If you do get any errors please use the 'Report a bug or give feedback' link on the plugin to send me the error details.

Non–blocking Facebook and Twitter buttons

Friday, November 19th, 2010

On all the posts on this blog (like on most other websites you probably visit) you’ll see buttons to ‘Like’ a post (from Facebook) and to ‘Tweet’ about a post (from Twitter or TweetMeme). These buttons are very popular but if you use the iframe versions of the buttons (which are easy to install) you may have noticed a problem.

twitter facebook tweetmeme logos

If either the Facebook, Twitter, or TweetMeme servers don’t respond quickly enough when your browser requests the page content, your page loading may well block. On this site I’ve seen the Facebook Like button delay the page by 1-3 seconds. The bad part about the type of blocking is that in most browsers the rest of the page doesn’t render whilst the browser is waiting for these 3rd party servers to respond. There’s a more in depth explanation of why this is so on Steve Souders’ High Performance Web Sites blog.

Browsers usually start loading resources in the order that they are specified in the HTML. Below is a screenshot of one of the pages on this site (this one in fact). The red line shows the order of loading of the page. This order is typical for blogs.

rml page load order facebook twitter

If you place the social bookmarking buttons before your content then the problem is particularly noticeable as they can block your whole content from loading. During which time your visitor may decide to go elsewhere.

Is there a solution? Yes there is a well understood solution to this problem. Simply load these externally hosted buttons after your content. Here’s how I did it on this site.

Use a div to reserve space for your buttons

You should reserve the correct amount of space for your buttons. If you don’t you’ll cause the page to be re-rendered once the buttons are inserted.

<div class="socialbuttons" style="width:450px; height:28px; text-align: top;">

In my case I’m including the compact Facebook like button which is 25 pixels high, and either the TweetMeme button (20 pixels), or the Twitter Tweet button which is also 20 pixels high. More about how I decide on which Twitter button to include later.

For this blog I’m including the buttons at the start of my content, and at the end. If you are using WordPress you could add the div to your content either directly in the template (single.php) or by using a plugin such as PostPost.

I’m including the top div in the template, and the bottom div using PostPost. The reason I’m using PostPost for the bottom div is because this plugin gives itself a priority of ‘1’ which means that it inserts the div before most of my other plugins insert their content.

User JavaScript to add the Facebook/Twitter buttons after the content has loaded

You’ll notice that the div has the id ‘socialbuttons’. This allows us to easily find the element and insert the social bookmarking buttons after the content has loaded.

Here is the WordPress specific JavaScript that I’m using. I add it just before the closing </body> tag. For WordPress this means editing the footer.php template.

<script  type='text/javascript' language='javascript'>
var permalink='<?php echo urlencode(get_permalink()); ?>';
var socialhtml='<iframe src="' + permalink + '&amp;layout=standard&amp;show_faces=false&amp;width=300&amp;height=25&amp;action=like&amp;font=arial&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:300px; height:25px; display:inline;"></iframe>';
<?php if (new_twitter()) { ?>
socialhtml += '<iframe allowtransparency="true" frameborder="0" scrolling="no" src="' + permalink + '&via=reviewmylifeuk&related=reviewmylifeuk&text=<?php echo the_title(); ?>" style="width: 130px; height: 20px;"></iframe>';
<?php } else { ?>
socialhtml += '<iframe src="' + permalink + '&style=compact&source=reviewmylifeuk&b=2" height="20" width="90" frameborder="0" scrolling="no" style="border:none; overflow:hidden; display:inline;"></iframe>';
<?php } ?>
var divs=document.getElementsByTagName('div');
var divcount=divs.length;
for (var i=0; i<divcount; ++i) {
	if (divs[i].className=='socialbuttons'){

This JavaScript works by find all the div tags with the class ‘socialbuttons’ and then inserting the Facebook and Twitter HTML inside the div tags.

I’ve highlighted in red my Twitter account name. You’ll want to change these values to your own Twitter account name. If you aren’t using WordPress you’ll need to replace the get_permalink() function with something that correctly encodes your current page URL.

You may be wondering what the new_twitter() function is.

PHP to select TweetMeme or Twitter Tweet button

TweetMeme is handing over the Tweet button to Twitter. As of July 2010 the recommended button to use (recommended by both TweetMeme and Twitter) is the official Twitter one. Unfortunately the Twitter Tweet counts will only be correct for articles posted after July 2010. Therefore for the moment I’m using the TweetMeme button for articles posted before July, and the Twitter one for articles posted after.

Here is the WordPress specific PHP that checks if the current post is after July 2010 (you could make it a one-liner if you like).

function new_twitter(){
	$twitter_switchover_date = strtotime("2010-07-01");
	$post_date= get_the_time('U');
	if ($post_date > $twitter_switchover_date) {
		return true;
	} else {
		return false;

If they ever remove the TweetMeme button completely it will be very easy with this code to change all the Twitter buttons to be the official Twitter ones.

Including hashtags with the TweetMeme button

The old TweetMeme button had the option of specifying hashtags for the Tweet. You can add this in as well if you want. You’ll need to write a function to get the hastags (e.g. called something like get_hashtags()), and include it in the TweetMeme URL.

You can find code for constructing the TweetMeme hashtags in the TweetMeme plugin. Look in tweetmeme.php for the ‘// append the hashtags’ section.

If you manage to create your get_hashtags() function you can replace the TweetMeme line in the JavaScript with.

socialhtml += '<iframe src="' + permalink + '&style=compact&source=reviewmylifeuk<?php echo get_hashtags() ?>&b=2" height="20" width="90" frameborder="0" scrolling="no" style="border:none; overflow:hidden; display:inline;"></iframe>';

(again don’t forget to replace my Twitter account name with yours!)

Does it make a difference?

From my experience of using this code it definitely makes a difference. The annoying delays (caused mainly by the Facebook Like button) have gone. The button still sometime takes several seconds to load, but at least it isn’t blocking the rest of the page.

More info on how to customise the buttons

If you want to customise the buttons have a look at the developer documentation for each one.

Compressing HTML and PHP files on 1and1

Friday, July 9th, 2010

1and1 doesn’t have mod_deflate or mod_gzip enabled on its home or business shared server packages which means that many of the usual .htaccess tweaks to compress your web pages won’t work. Here’s something very simple tweaks that will work with 1and1, and with other hosts too.

Set up your .htm and .html files so that they are parsed by the PHP interpreter by adding this one line to your .htaccess file.

AddType x-mapp-php5 .html .htm

Then create and upload a php.ini file to your websites root directory. If you are using WordPress then this should be the same directory as the one where wp-config.php is.

The contents of the php.ini should be as follows.

zlib.output_compression = On

This line causes PHP files to be served as compressed if the browser supports it. And as we have registered .html and .htm as being PHP files they will now be compressed.

You can test that the HTTP compression is turned on by using this simple HTTP compression checking tool, or by using the more comprehensive Page Speed add-on for Firefox from Google.

Here are the results from the HTTP compression checking tool showing that compression is now on, and that the home page HTML is being served using 76% less data. Note that this saving refers only to the HTML page, and not to any other images, style sheets, or JavaScript.

rml gzipped on 1and1

Increasing expiry time of images on 1and1

Another quick tweak you can make to your .htaccess is to increase the expiry time of your images, and other data files. This will result in quicker loading times for regular visitors as the files will stay in their browsers cache for longer.

Add this to your .htaccess. You can increase the expiry times if you don’t think those files will change.

#Increase cache time for resources

ExpiresActive On
ExpiresByType image/gif "access plus 2 weeks"
ExpiresByType image/jpeg "access plus 2 weeks"
ExpiresByType image/png "access plus 2 weeks"
ExpiresByType image/ico "access plus 2 weeks"
ExpiresByType text/css "access plus 2 weeks"
ExpiresByType text/javascript "access plus 2 weeks"
ExpiresByType application/x-javascript "access plus 2 weeks"

Use Google’s Page Speed add-on to verify that this has worked. Go to the Resources tab to see the headers for each individual file served from the HTTP server. Below you can see the current date/time, and that the expiry time is set two weeks into the future.

expires date for image

Caching and expiry changes combined

Here are before and after results for Google’s Page Speed tool of applying both the above changes to another of my websites. You can see that these quick changes give the website a small increase in score.

website score before

From 88 to 92.

website score after

This isn’t a big jump, but it may make a difference. I highly recommend you look at the other performance recommendations from the Page Speed tool, as it can give you loads of ideas for how to make your site faster and more responsive.

Notes on upgrading to WordPress 3.0 on 1and1

Tuesday, June 22nd, 2010

Normally I’d wait until at least the x.01 release of a new WordPress before upgrading. But this time I wanted to try the new WordPress soon after the final 3.0 version was out. I still waited a few days before installing it to let other people discover and fix any initial problems.

Problems and fixes

My wait paid off as a number of people who were using the same hosting company as me (1and1) found that the upgrade was failing with a ‘Fatal error: Allowed memory size of xxxxxxxx bytes exhausted’.

The fix for this problem is very simple – increase the allowed memory size, either by adding a php.ini , updating the wp-config.php, or for those who could wait a few days for an easier fix, by installing the Memory Bump plugin.

I installed Memory Bump, and went through all my usual WordPress backup steps, before attempting the install.

I pressed the Upgrade button, WordPress did something for about a minute and then I got this error message:

Downloading update from
Download failed.: Operation timed out after 60 seconds with 1023460
bytes received
Installation Failed

Not to panic though, this error is just saying that WordPress didn’t manage to download the new install package before its 60 second timeout. I pressed the button again, and this time it worked!

Downloading update from
Unpacking the update.
Verifying the unpacked files…
Installing the latest version…
Upgrading database…
WordPress upgraded successfully

New themes

The reason I wanted to upgrade as soon as possible was so that I could give reviewmylife a new theme. The old Kubrick theme was getting a bit old.

old reviewmylife blog

After a bit of searching and experimenting I found the News Magazine Theme 640 which I have now switched to.

new reviewmylife blog

One word of advice if you are switching themes – if you swap to a new one, and then back to the previous you might find that all your widgets have been set to inactive. You’ll have to re-add them again.

A second piece of advice is to keep any caching plugin you might have disabled whilst you play about with new themes and theme settings. This will make sure that you always see the latest generated pages, and not older cached ones. Don’t forget to turn the caching back on afterwards!

A later error

Whilst modifying one of my plugins I got this error on trying to activate it.

The plugin generated 3 characters of unexpected output during
activation. If you notice “headers already sent” messages,
problems with syndication feeds or other issues, try deactivating
or removing this plugin.

There are many possible causes, but in my case the problem was down to having opened the .php in Notepad and accidently saving it as UTF-8 instead of ANSI. I re-saved it as ANSI and it worked again.

Renaming table prefix on WordPress 2.9

Wednesday, May 19th, 2010

I wanted to rename the table prefix for this blog before upgrading to WordPress 3.0. I knew about the WordPress Table Prefix Rename Plugin which claimed to work for WordPress 2.x, but I couldn’t find anyone saying they had tried it specifically on WordPress 2.9.

wordpress table rename plugin

The only thing to do was to try it myself. As stated in the documentation this plugin doesn’t actually rename the tables, it copies the tables, and gives the copies your chosen prefix. It also modifies a few entries in the new tables which refer to the tables by name. Then it modifies the prefix entry in wp-config.php.

Before using it I looked through the PHP source code to make sure I was happy with what it was going to do. And of course I made full backups of my tables just in case it all went wrong.

I disabled the WP Super Cache plugin, and deleted the cache, to make sure that after the rename I could see the actual generated blog pages, rather than pages that had previously been cached by WP Super Cache.

I also opened the phpMyAdmin control panel that my web host (1and1) uses for managing the MySQL databases.

After installing and activating the plugin I went to its setting page, typed in my chosen table prefix, and pressed ‘Generate New Tables’. After 2-3 seconds it was done. I made a copy of the SQL statements that had been used (they get displayed on screen) for reference just in case I needed them later.

Then I pressed ‘Change $table_prefix’ button. This only took a second.

To check that everything had worked I logged out of WordPress and back in. I checked a few pages on the blog as well. And I checked wp-config.php using my FTP program to make sure it had been modified. It had all worked!

Using phpMyAdmin I checked that the new tables were the same size as the old ones (taking into account any overhead in the original tables).

I’d recommend you keep the old tables until you are sure that the new ones are working fine. Wait a few weeks – or even longer before deleting them if you have space. They don’t do any harm, and act as an extra backup of your data.

Table renaming tips

  • Read the plugin source so you know what it is going to do.
  • Backup your database tables, and verify that the backup is good.
  • Set aside enough time to restore your blog from backups in case it all goes wrong.
  • Keep your original tables if you have the space. More backups are good.

What I’ve learnt after 100 blog posts

Saturday, March 27th, 2010

Today marks a significant milestone for this blog. After two and a half years I have reached my 100th post! I thought this would be a good moment to look back at what I’ve learnt from writing a hobby blog.

mini keyboard and cadbury sweets

Why I created this blog

I’ve been a hobbyist website builder for about 13 years now. I’ve created a mixture of technical and personal topics. These have always been static websites where each page was created individually, either using a HTML editor such as HoTMetaL, or by using hand written HTML templates. Each website tended to stick to a particular topic, and some of them have done moderately well, getting many hundreds of visitors each day.

I had an ideal for another website where I could write about miscellaneous topics that didn’t fit anywhere else. I registered a new domain name with 1and1, created some static HTML templates, and started writing some content. I soon gave up as I found that I was spending too much time on the mechanics of creating each page, rather than on the more creative writing aspect. I abandoned the idea for a year, and didn’t think much more of it.

Starting up

I began reading about blogs, and self hosted blogging platform like WordPress. I thought that my miscellaneous topic website might work if I used something like WordPress as the content management system.

At the time I was on a very basic web hosting package with 1and1 and I had to upgrade to a more expensive package that included MySQL database support before I could install WordPress. Once the web hosting was upgraded I had the basic blog up and running in a couple of hours. I registered the domain name to host the blog.

The domain name is fairly self explanatory; I’d be posting articles that in some way related to my life. I thought there would be reviews (of hardware, films, and so on), but the name was generic enough to allow me to put any kind of content on the blog.

My very first post on 5th August 2007 was about setting up the blog on 1and1 (the company I use to host the site). It wasn’t a classic post, but it was a start. That month I posted a few other cheap posts, and also moved some of the content from my failed ‘miscellaneous content website’ over to the new blog.

You should think carefully before deciding to use a self hosted blog like WordPress. Self hosted blogs do require a fair bit of maintenance. At first it was a real pain as all the plugins and the blog itself had to be manually updated on a regular basis. As WordPress evolved it got easier as features such as one-click plugin updates, and then full one-click updates were added.

Over the years I’ve written many posts about the various issues I’ve had to solve with hosting my own WordPress blog on 1and1 such as configuring custom error pages, adding spacing round iframes, and adding a related posts section to each post.

As well as keeping WordPress up to date, you’ll have to dedicate time to customising it (if you want), and backing up your data (very important if you don’t want to risk losing everything). I’d recommend you backup your posts (doing a Tools->Export, and do a MySQL backup) every month. And backup before you upgrade the blog. New minor updates come out every month or two, and major updates seem to come out every three months.

Backing up your blog is very important as not only can you lose data from:

  • Your own mistakes.
  • Mistakes made by your hosting company.
  • Malicious hacking into your site. WordPress has had a steady stream of vulnerabilities being found and patched over the years.

The blog picks up

As time went on I posted more useful information. I got plenty of appreciative comments for my post warning about the Spanish lottery scam, and for a post explaining how to get documents certified cheaply.

The number of comments went crazy when I posted about my experiences of trying to get rid of clothes moths. To date I have 74 comments for this one post, many of them would make worthy posts in themselves. This post is an example of a seasonal post. Clothes moths tend to cause problems in the Spring, Summer and Autumn so these are the times when this post get visitors. The number of people looking for information on moths goes down a lot in the winter.

Getting feedback from other people is one of the most satisfying aspects of writing a blog. I find that when I post about personal experiences I get a lot more comments than if I just provide some information.

As well as the clothes moths post, the posts on my cyst removal surgery, and my problem with knee pain and considering a lateral release got plenty of feedback.

In terms of what posts are popular I find that there are two types of posts that get lots of visitors.

  • Personal experiences – like the posts I mentioned above. People like reading about others who are going through similar things to them.
  • Useful information – posts where I’ve provided free useful information such as my 2011 Excel Calendar, and my guide to upgrading the Samsung N140 memory to 2GB get plenty of readers.

Whatever you are writing about I find that if you add quality original material to the internet you will get more readers then if you just re-hash information that already exists.

I’d predict for example that this blog post won’t get very many visitors. There are so many people blogging about blogging that this post will probably vanish in the noise out there. But I still consider it worthwhile to write it so I can look back once I reach 200 posts.

How I write each post

When I started I used to use the WordPress WYSIWYG editor. I found that it wasn’t a great experience. Typing text into a box on a web page isn’t as good as writing text in a word processor. I like having a proper spell checker, and grammar checker ready to use.

I switched to writing my posts in Microsoft Word and using a set of VBA macros that add the WordPress mark-up to the post.

I don’t have a fixed length for each post, some are very short being just a few hundred words long, and others are many thousands of words long.

The shortest posts have been done in less than half an hour, whereas the longest posts with original research, photos and charts have sometimes taken me four to five hours to complete.

Often I don’t have a plan for each post, I just start writing and finish when I think the post is done. Take this post for example; I have very little idea where I’m going after this sentence! All I have is a few notes about certain topics I want to include.

I didn’t always include photos in my posts, but more recently I’ve tried to have at least one photo or diagram in each post. I think the sight of a large block of text can be off-putting to blog readers. A few relevant (or even not so relevant) photos can help to break the text up. All my photos are taken with a Sony Cybershot W80 camera which I reviewed on this site in 2008.

To upload the photos I use the FileZilla FTP client which has useful functions such as directory bookmarking, synchronised browsing, and filters.

Getting ideas for posts

As my blog is a multi-topic one rather than being a specialised one I can think of ideas for posts all the time. The problem is that I don’t have time to write many of them up.

reviewmylife thumbnails

Often my ideas are topics that I’ve tried to find out about on the internet, had no success, and so have decided to write about them myself.

I find that if I get an idea for a post, I need to write it down right away. If I don’t then I’ll have probably forgotten a few minutes later. If I’m at my computer I record my ideas as a simple list in Word. If I’m away from my computer I put the ideas in a ToDo list on my phone.

If I have specific ideas for what content should be in those posts then I might jot down a few bullet points, but most of the time I just write the idea down in a single line.

Promoting the posts and website

I spend very little time on promoting each post or SEO compared to the amount of time spent writing new content. But I have done some simple things to make sure each post has basic SEO hygiene factors.

  • I’ve installed the All in One SEO Pack plugin, and I make sure I add a title, description, and keywords for each post.
  • I add tags and a category to each post.
  • I submit most of my new posts to Digg, reddit, Delicious, and StumbleUpon.
  • More recently I’ve installed the Tweetly Updater plugin so Twitter is notified when I make a new post.
  • The Google XLM Sitemaps plugin is installed on this blog to make it easier for search engines to index my blog.
  • I have a TweetMeMe Retweet button on my posts to allow other people to Tweet about them.
  • I have an AddThis button on my posts to allow them to be easily submitted to social bookmarking sites.

One area where I haven’t put much/any effort into the blog is with the look. At the time of writing this 100th post I’m still using the default Kubrick theme. I will probably customise it at some point, but may wait until the default theme changes in WordPress 3.0 before I do that.

The Kubrick theme may be basic, but it works well and means I don’t get incompatibility problems each time I need to upgrade the blog. You can get plenty of readers without having to use a fancy theme.

Here is a graph showing the number of visitors I get per week which goes back to when I first installed Google Analytics. The left of the graph is October 2007. The right side is the day I made this post; 27th March 2010. The number of visitors is not huge, but at least it is growing.

visitors per week

Monetising the blog

I decided early on to monetise the blog. Not to make real money, but to at least pay for the costs of the web hosting, and domain names. To do this I use the AdSense Injection plugin with a number of custom tweaks.

It inserts text adverts into the posts automatically, and randomises their position. I find it to be a very easy way of generating a small amount of money for the site. It covers my web hosting costs, but isn’t enough to give up the day job just yet!

If I’m writing a post about something that can be bought from Amazon then I might add an Amazon affiliate link as well. This worked particularly well when I reviewed the Samsung N140 netbook. The review has nearly paid for the netbook already!

Where do my visitors come from?

This site may look like a blog, but in reality I treat it more like a static website that just happens to be using WordPress as the content management system.

Blogs usually have some common theme through their posts, mine are on quite random topics.

Because of my scattered topics almost all my readers come from search engines. I have very few – almost zero – subscribers. People use Google, Yahoo, or Bing to search for something specific, and sometimes they find one of my pages in the results.

82% of my visits come from search engine queries, and 75% of those are from Google.

You might have noticed that quite a few of the list item in the ‘Promoting the posts and website’ section above were relating to social bookmarking websites. However only about 1% of my traffic comes directly from these kinds of sites. It does make me wonder if it is even worth submitting the pages to these sites at all.

Of course these social bookmarking sites may be driving visitors in other ways – by increasing the rank of my pages in the search engines. I don’t think there is any way to find out, but I’ll keep submitting for now.

The top referring social bookmarking website for me is StumbleUpon.

In terms of which country my visitors come from 41% are from the UK, 25% from the US, and India, Canada, Australia, the Netherlands, and Germany are all in the low single figures. In the last month I had visitors from 122 different countries.

Internet Explorer is the most popular browser with 48% of my visitors using it. Firefox gets 34%, Chrome 10%, Safari 5% and Opera 1%.

The future

So what does the future hold for this blog?

Quite simple – more posts! On average I’m posting about one post per week, but sometimes there will be several in a week, and then none for a few more weeks.

I hope to keep to at least this amount of posts for the next year, and work my way towards 200 posts. I have a big backlog of post topics to write about so I won’t run out of ideas anytime soon. And I hope my writing is getting better as I go on.

If you read this I’ll say ‘thanks’. And do pop back sometime soon.