Category / Programming


Loading missing images from a remote server

When developing on a local server it can be painful to keep images in your media library synced with your production site. Sure, you could download the missing images and attachments to your local machine every time you need to work on the site, but this approach has two problems:

  1. It is time consuming
  2. The files take up space on your local drive

I recently discovered a way to seamlessly handle missing images so that they never 404 or occupy space on your local machine. The solution is an htaccess rewrite rule that checks if an image exists locally, and if it doesn’t, attempts to load it from your production server.

Here is a sample htaccess directive for WordPress:

# Load media files from production server if they don't exist locally
<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteBase /
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{HTTP_HOST} ^localsite\.dev$
  RewriteRule ^wp-content/uploads/(.*)$$1 [NC,L]

Remember to change “” and “” in the example to match your own domain, and adjust your file paths as necessary. If you’re implementing this on a WordPress site make sure to place it before WordPress’ own htaccess directive.

Hat tip to @stevegrunwell for bringing this technique to my attention.


Automated git deployments from Bitbucket

Important: Bitbucket have changed how webhooks function, and the technique described in this post will no longer work without modification. One of my readers has created an updated version, and I recommend trying that instead. I no longer use this deployment method and won’t be updating my tutorial or answering comments, but I have left the comment section open so that readers can post their tips and help each other out.

Git may not have been designed as a deployment tool, but for small projects it can do the job quite nicely. What makes Git deployments attractive is how frictionless the process is: make some changes to your project, merge them into your production branch, push the commit to a remote repository and like magic the changes are live! Git knows which files need to be changed or deleted, so you don’t have to think about it. If you’re already using git to version control your project then you probably won’t even need to modify your existing workflow, once the initial setup is done.

I use Bitbucket for hosting my private repositories, and have recently implemented a deployment process that integrates with Bitbucket’s POST hooks feature. There are basically three things you need to do to make this work:

  • Set up SSH keys so your server can talk to Bitbucket
  • Clone your Bitbucket repository on your web server
  • Setup a hook on Bitbucket and an associated deployment script on your server

Here’s what your deployment workflow will look like once we’re done:

  • Develop your website locally
  • When you’re ready to deploy, commit your changes and push them to Bitbucket
  • When Bitbucket receives the commit it will notify a deployment script on your server
  • The deployment script will fetch the changes into a cloned repository on your server, and checkout files to your public web directory

Continue reading


TweetPHP: Display tweets on your website using PHP

If you’ve ever wanted to display your latest Twitter tweets on a website, TweetPHP lets you do that using PHP. TweetPHP is a rewrite of my old Twitter RSS feed parser, which stopped working when Twitter phased out their v1 API.


  • Works with Twitter API v1.1
  • Tweets are cached to avoid exceeding Twitter’s API request rate limits
  • A fallback is provided in case the twitter feed fails to load
  • Retweets and @replies can be optionally ignored
  • A configuration parameter allows you to specify how many tweets are displayed
  • Dates can optionally be displayed in “Twitter style”, e.g. “12 minutes ago”
  • You can customize the HTML that wraps your tweets, tweet status and meta information


TweetPHP is available on Github


To interact with Twitter’s API you will need to create an API KEY, which you can create at:

After creating your API Key you will need to take note of following values: “Consumer key”, “Consumer secret”, “Access token”, “Access token secret”

Those values can be passed as options to the class constructor, along with the Twitter screen name you wish to query:


$TweetPHP = new TweetPHP(array(
  'consumer_key'              => 'xxxxxxxxxxxxxxxxxxxxx',
  'consumer_secret'           => 'xxxxxxxxxxxxxxxxxxxxx',
  'access_token'              => 'xxxxxxxxxxxxxxxxxxxxx',
  'access_token_secret'       => 'xxxxxxxxxxxxxxxxxxxxx',
  'twitter_screen_name'       => 'yourusername'

Then you can display the results like so:

echo $TweetPHP->get_tweet_list();


See TweetPHP’s Github for documentation of all options.


Caching is employed because Twitter rate limits how many times their feeds can be accessed per hour.

When the user timeline is first loaded, the resultant HTML list is saved as a text file on your web server. The default location for this file is: cache/twitter.txt

You can change this file path by setting the cache_file option. For example, to set a path from your root public directory try:

$_SERVER['DOCUMENT_ROOT'] . '/path/to/my/cache/dir/filename.txt'


If you are experiencing problems using the plugin please set the debug option to true. This will set PHP’s error reporting level to E_ALL, and will also display a debugging report.

Here are a few tips to help you solve common configuration issues:

tmhOAuth response code: 0

If your debugging report shows the error “tmhOAuth response code: 0”, you can find out more about this error message in the tmhOAuth github README. Dario also offers this solution: “My server didn’t like the the two __DIR__ constants in the tmhOAuth.php file, hard-coded them and it all works now.”

unserialize error

If you receive the PHP warning “[function.unserialize]: Error at offset 0 of 49 bytes”, it might be the case that you have magic quotes enabled in your PHP configuration.


– Feed parsing uses Matt Harris’ tmhOAuth
– Hashtag/username parsing uses Mike Cochrane’s twitter-text-php


A jQuery plugin boilerplate

I created this boilerplate for a jQuery plugin I’m working on, and you can use it to kick start your own jQuery plugin development. The features of my boilerplate are:

  • Plugin can be customised using options
  • Setters/Getters for options
  • Private and public methods
  • Callback hooks
  • Plugin instances can be destroyed

Continue reading


Test your JavaScript skills with js-assessment

I recently discovered js-assessment, a “test-driven approach to assessing JavaScript skills” created by Rebecca Murphey. The js-assessment application contains a series of tests designed to assess a job candidate’s grasp of JavaScript, but it can also be used to gauge your own knowledge of the language. Think of it as a mini Project Euler for JavaScript.

The questions are divided into five topics covering different aspects of the language: arrays, objects and context, functions, asynchronous behavior and Backbone views. If, like me, you have a decent grasp of JavaScript, but wouldn’t feel confident writing “JavaScript programmer” on your curriculum vitae, then I think you’ll find the tests an enjoyable challenge. None of the questions are super difficult, though I confess to needing help from MDN to arrive at a few of the solutions. I definitely learned a thing or two about JavaScript along the way.

Continue reading


Don’t believe the hype

This week I came across a new JavaScript framework, called Meteor, which promises to simplify the process of developing web applications. It looks like an interesting project, run by some very smart and talented people, but something about the Meteor marketing pitch rubbed me the wrong way.

The Meteor website is full of claims about how amazingly easy the framework will make web developer’s lives. It will allow us to build “top-quality web apps in a fraction of the time.” Its demo applications require “no programming knowledge.” What “once took weeks, even with the best tools, now takes hours.” In fact, you can “build a complete application in a weekend.”

If building a world class web application was really something that could be done in a weekend, wouldn’t everyone and their dog be CEO of their own Internet startup? If the barrier to entry was as low as the Meteor team would have us believe, then business owners would have no need for developers at all – a few hours of training and they’d have all the skills required to build their own app or website.

Continue reading


Launching XAMPP at OSX startup

A few days ago I posted about my experiences setting up XAMPP on OSX. Here’s another little XAMPP tip…

By default XAMPP won’t start the Apache and MySQL services at system startup, so every time you reboot your computer you’ll need to restart them. Wouldn’t it be nice if those services started automatically? One way of doing that is to create a Launch Daemon that runs at system startup and have it start XAMPP for us.

Fire up Terminal, and run the following command:

cd /Library/LaunchDaemons
sudo nano apachefriends.xampp.apache.start.plist

Enter your OSX password when prompted, then in nano paste the following into your new plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">

Save the file and exit nano (control+o, return, control+x).

Now run the following terminal command:

sudo nano apachefriends.xampp.mysql.start.plist

And into this new file paste:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">

Save the file and exit nano (control+o, return, control+x).

When you restart your computer the XAMPP Apache and MySQL services should start automatically. You can check this by launching XAMPP Control and checking that Apache and MySQL have green lights displayed next to them.

A note about security

If you’re concerned about the security of your system while running XAMPP, the safest approach is not to run Apache or MySQL at all, in which case you might not want to have those services running while you’re not using them. However, I’m fairly certain that unless you intentionally open up port 80 in your hardware/software firewall your XAMPP server should be invisible outside your local network.


A hat tip to ‘cwd’, who posted this solution on Superuser. I tried a couple of other approaches before I stumbled upon this one which actually works.


Configuring VirtualHosts in XAMPP on Mac

A few weeks back I rejoined the “Cult of Mac” when I replaced my old Asus notebook with a MacBook Pro, and since then I’ve been busy settling into my new OS X workflow. I do all my development locally, so one of the first applications I installed was XAMPP, a cross platform Apache/MySQL/PHP stack. While I know that MAMP is very popular on Mac, I have been using XAMPP for many years so I thought I’d stick with what I know.

Installing XAMPP was a snap, but when I came to create my own Apache VirtualHosts things started getting fiddly. Here are the steps I followed to get everything running smoothly.

Continue reading