by Tom Millard

Return the time since a file was created in PHP


I needed to work out the time in minutes since a file was created in PHP.

PHP provides us with some basic file function, one of which is filectime() which will return a unix timestamp of when the file was created.

We can take this value and then get the difference by using time().

function getFileAge($file){
        return false;

    return ceil(( (time() - filectime($file)) / 60 ));
by Tom Millard

Ternary in Handlebars

javascript - handlebars

I recently started using Handlebars for an internal project. A fresh install of handlebars gives you very little to work with. With the help of Handlebars helpers we can expand on the core functionality and mold the library into something which better serves our needs.

Ternary helpers

function ternary(value, yes, no){
    return value ? yes : no;

This is the basic function we want to run, we can then tell Handlebars about this helper:

Handlebars.registerHelper("?", ternary);

Finally we can use it in our template like so:

{ ? true 'then this' 'else this'}
by Tom Millard

WordPress Plugins that do not suck


It's a minefield when it comes to WordPress plugins, I would say that over 70% of all WordPress plugins are awful, some are even dangerous. Horror stories of a WordPress plugin destroying your site or opening up a major vulnerabilities is nothing new.

So what can we trust in the world of WordPress plugins,


Advanced Custom Fields is pretty much a must on any WordPress site looking to grow beyond a simple blogging platform. Its easy and simple to use and allow you to add custom fields to pretty much any post type. Definitely a must have for building up a complex CMS solution with out the need to write allot of CRUD.

Ok so this next one is definetly not a plguin but will go along way to mitigating the use of plugins. I use this mainly to generate custom taxonomies and custom post types. The advantages to using actual tangible code is pretty obvious - version control.

EWWW Image Optimizer

With the web ever increasing in size the option to one click optimize your images is a winner. This seems to be the only plugin I have found which does exactly what it says on the tin. A fast website is a happy website and a happy website ranks well.

WP User Avatar

This is more for running a blog or managing a large user base. WordPress runs on gravitar... or something. Anyway you need this plugin in order to support avatars for your users. Simple.


Sending emails? this simple plugin makes integrating with Mandrill smtp server a painless experience. Sendgrid also has something similar which is just as easy to set up.

XML Sitemap Generator

Again another wp-plugin which does exactly what you need it to do and that's generate an xml sitemap for your site


Comment managing is a pain in WordPress, if your not getting spammed every 5 minuets by Justin Bieber selling you UGG boots then your dealing with users forgetting a login. Disqus is 3rd party comment management application which adds another level of social media to your site. I personally don't use the plugin and instead choose to integrate it straight into the site. However the plugin does allow you to migrate comments back into your site. Lovely.


It's always good to keep on top of your social media publishing and with buffer we can have all our new content automatically distributed over several social media channels at a time we choose.

So that's what I have so far, no slide-show plugins, no form generators and no SEO plugins. Nothing which will add bloat to the head/footer of our site.

Have a suggestion, want to make the list. Send me a tweet.

by Tom Millard

Templating with PHP block statements

php - html-2 - templating

PHP templating languages have be come a stable when working with an MVC system. Extensions such as smarty, twig and blade can be found in most PHP frameworks or can be implemented with ease.

Templating engines simple to work with and force your team into an MVC approach by removing the ability to handle logic in the view.

If you don't have access to a templating engine, or you feel it may add another level of complexity to your application.. or your working on an old system but want to separate your code from the spaghetti that exists, then block statements might be worth implementing.

I'm a huge fan of block statements when it comes to WordPress and find that it gives the necessary separation I need in my templates.

<?php foreach(get_posts([args]) as $p) : ?>
     <div><?php echo $p->post_content; ?></div>
<?php endforeach ?>

This example is basic but from the out set you can see how it would help with a complex HTML view. If we compare the above to the norm we can see one clear advantage, and thats readability.

<?php foreach(get_posts([args]) as $p) { ?>
     <div><?php echo $p->post_content; ?></div>
<?php } ?>

We have access to allot of control structures alternatives, here are a few:

<?php if(x == y) : ?>
<?php endif ?>

<?php while(true) : ?>
<?php endwhile ?>


What about short codes?

I was a huge fan of short codes, however over the years people have moved away from using them. And in my opinion best practice always wins.

Echoing out HTML


by Tom Millard

Super fast WordPress set-up

wordpress - nginx

WordPress has always suffered from the stigma of being slow, its something I have always had trouble with.

You can do all the front-end optimization you like and install all the caching plugins in the world, but speed will always be an issue until you get down and dirty with your server.

Server providers like wp-engine boast fast WordPress hosting, so how can we achieve the same with an out the box VM, and reduce that $29 a month per instance cost into a $10 a month cost with no restriction (okay, maybe some restrictions if your getting millions of hits a month).

Below I will go over what you need to make a beefy WordPress server. I host all my sites on Digital Ocean as hardware also makes a huge difference to your sites speed - SSD's or bust.


Apache has always been the old faithful of server admins, its well documented and achieves what you want - a server. However its slow at handling incoming requests and tends not to scale well. Nginx however is the opposite:

...nginx offers a higher transfer rate compared to Apache, but also has less of a wait time between receiving the request and passing a response back. I also noticed that nginx can handle more requests per second, and is able to ramp up as the load increases, however apache remained pretty static on this front.

This will help our server handling incoming request, however your will be missing you precious .htaccess file. Which you shouldn't be using anyway.

It's not a WordPress specific improvement, nginx as a whole can bring some much needed speed to any site.

How To Install Linux, nginx, MySQL, PHP (LEMP) stack on Ubuntu 12.04


Memcached is all the rage lately and will help to add some much needed speed to your WordPress site by caching object in RAM to save us making another annoying trip to the DB this plugin will help us to achieve an easy implementation of the library.

Redis is also an option but it's something I have yet to implement. Redis has more functionality than memcached and so might be worth looking at for future installations.

(Personally I despise WordPress plugins, I have a few exceptions; but as a whole I hate them.)

PHP also now comes with built in caching, OPcache. OPcache is relatively easy to install and with a simple change to your php.ini file. You can get the benefits of pre-compiled PHP scripts.

OPcache improves PHP performance by storing precompiled script bytecode in shared memory, thereby removing the need for PHP to load and parse scripts on each request.

Simple CDN

Distributing your site across the world should not be a pain in the arse, I use Cloudflare. I simply point all my domain names to use their name servers then turn it on and away we go.


Finally and I can't stress this enough, write efficient code.

by Tom Millard

Better PHP debugging using the error log

php - unix - errors - debugging

I have worked with some difficult systems, PHP can be a nasty language when it wants to be. But one thing which remains consistent is the error.log.

As long as PHP is set up to pump all its errors into this file we can get on the fly PHP error reporting with the following command line.

tail -f error.log | sed 's/\\n/\n/g'

Error logs are normally kept in /var/log then depending on the OS and Server it can be httpd, nginx, apache etc.

Logs are normally set up my default in the server conf unless they are overridden in the sites .conf file. Always worth looking in the /var/log first, or checking the php.ini file.

by Tom Millard

Getting started with PHP, Composer, Git and Vagrant on Windows

php - git - windows - vagrant

Recently I have found myself back on a windows machine after a 3 year stint with Macs, I seem to have gone full circle.

Its interesting to see how easy it is to install some of these thing on to my Windows box so I thought a break down of everything i'm going to install and how to get things up and running.


The type of development environment i'm looking to run is quite lean, and instead of using the windows box to do the majority of the grunt work I will be leaning on Vagrant to do all the heavy lifting. So you wont find any reference to xamp.

This blog post is meant as a guide, it requires some basic knowledge of the innards of a Windows machine. If you have no idea what I'm talking about when I say 'PATH' you might want to read something more detailed (Please don't break your machine doing this).

The major pit fall is a lack of a half decent terminal, i'm sure the windows shell(?) is just the best for someone somewhere but unfortunately I have no interest in learning another command line tool.

Luckily git gives us a rather lovely terminal with git bash

Once this is installed we have access to a terminal, which seems to translate allot of the native functionality you might be use to on Linux on to Windows.

Note: You might want to run 'ssh-keygen' in the terminal, this way we can generate some ssh keys.


We need PHP for composer and its just generally nice to have it on your machine. I chose to install PHP manually by downloading the zip file

Once downloaded I placed the PHP folder into the root of the machine AKA C://php

This way things are pretty easy to handle, I found that allot of these tools fall down with the way Windows names folders so this way we avoid having to navigate too far when we identify paths.

I found that allot of these tools fall down with the way Windows names folders

Once this is done you will need to edit the php init class to include any extensions you wish to install. First make sure the extension_dir is pointed to the PHP extensions file.

extension_dir = "C:\php\ext"

Then turn on all the extensions you wish to use, some of them will cause issues with how php runs so best to only turn on the ones you need when you need them.

Finally will hook up php to the PATH var in windows so we can use it in our shinny git-hub terminal.

My computer -> right-click -> properties -> (on the left) Advanced system settings -> Environment Variables

Then click Path and click edit. We want to add the following to the end of the text in the 'Variable value:' box.


Do not DELETE anything and save.

We should now have php running in git-bash, simply type 'php -v' and you should get the version details back. Bingo we are done.


Composer can be run locally within a project, but in this instance we will be installing it globally. Because its windows we can install this using the exe file. Simply follow this and composer will be installed and added to your PATH var, again you can do it manually and all you would have to do is point your path var to the composer exe.


I have always found vagrant tricky to set up and maintain on windows, incidence where virtual boxes have been lost or destroyed after your machine goes into sleep have happened on more than one occasion. However this problem seems to have been fixed on windows.

As of writing this Vagrant does not seem to work on Windows 10

First will need to install virtualbox.

Once this is installed will need to install Vagrant, hopefully vagrant will install with out a hitch but to make sure. Ensure that vagrant is install in the root of the C drive. Again you will find the software has trouble with the way Windows names files.

If you are having trouble sometimes its worth declaring the VAGRANT_HOME variable, this can be found here - My computer -> right-click -> properties -> (on the left) Advanced system settings. Then add a System variable called VAGRANT_HOME and point it to were you install vagrant home dir. Typically this is 'C:\Vagrant\home\' if you followed my above suggestion.

To save sometime I normally get my vagrant boxes generated from the rather lovely open source project - puphpet. For the purest of you this probably wont be accurate to your current live site, so you will have to go about building a vagrant box.

SSH Keys

If you managed to read all this and didn't get lost I assume your aware of ssh keys, they work in exactly the same way on windows except you might need to also generate some ssh keys with putty for windows specific programs which rely on the software.

This post will be followed up by a list of windows tools.

Currently I have spent about a month working on windows and although its a fine platform I find myself working slower than if I was working on Uinx environment.

by Tom Millard

Completely Remove .sass-cache From Your Repo

bash - git - sass-2

Every-time I start a project I forget to remove '.sass-cache, then I end up committing allot of rubbish. In order to fix your mistake do the following:

$ echo ".sass-cache" >> .gitignore
$ git rm -r --cached.sass-cache
$ git add . 
$ git commit -m "DIE SASS-CACHE DIE!!!!"

and done.

by Tom Millard

Setting up Models in Lumen

laravel - lumen

Getting started with Models in Lumen.

Firstly we need to uncomment the '$app->withEloquent();' in the bootstrap/app.php file.

Laravel 5 seems to have a stance of "whatever", when it comes to the location of your Models. Some peasants have started placing model's in the app folder letting them run free. However I come from a strict household and expect things to be in certain places. So I went ahead and created a Models folder in my app folder.

(at this point I have no idea where the 'generators' place the generated models from things like artisan:make, this is simply because I have yet to use laravel 5 and lumen does not come with this built in)

This is your basic Model bootstrap:

<?php namespace App\Models;


use Illuminate\Database\Eloquent\Model;

class Files extends Model {
    protected $table = 'files';

Notice the namespace references the location of the class, we use this when we wish to use this Model in a controller or a seeder.

Like so:

use App\Models\Files

or we can use it directly in the code like so


Note: Remember to sprinkle around some composer dump-autoload, throw it around like fairy dust.

by Tom Millard

Setting up Ghost on Nginx, with Forever

node - ghost-tag - nginx

To start with I'm going to make the following assumptions,

  • Your using Ubuntu
  • Node is installed and working
  • Nginx is installed and working
  • Ghost has been uploaded into a directory and 'npm install' has been run

Lets go,


Forever is an npm package which is used to keep your ghost site up in the background of your OS. You will need to start by installing Forever globally (-g).

````language-bash sudo npm install -g forever

##Setting up Nginx as a proxy
Now we need to create a server block, which will point to our local server running ghost, go ahead and create a config file in /etc/nginx/site-avalible 

cd /etc/nginx/site-avalible && touch

[, is my naming convention, you can name the file whatever you like just remember to be consistent]

Then go ahead and open that bad boy up with nano, or if your a pro vim and copy the following in. Remember to replace [my-site-url] with your url.

````nginx server { listen 80; server_name [my-site-url]; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $http_host; proxy_pass; } }

[Note: By default ghost runs on port 2368]  
We now need to symlink up the server block to '/etc/nginx/site-enabled/'

ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

Forever and ever

To start our node server - Ghost blog. First we need to navigate to the location of our index.js file. Then we need to run the following command ````language-bash node index.js

Yep that's not forever, im just testing to see if its working.
If that's all good, go ahead and terminate.
Then run:
sudo forever start index.js

and finally reload nginx

service nginx reload

If everything went to plan we should have a ghost blog.

ctrl+c Forever

To stop Forever simply run

sudo forever stop 0

This will terminate the first instance of forever running on your server, if you have multiple version you will need to list them out and terminate the corresponding index.