Quick and easy WordPress development using Docker

TL/DR: Head over to this GitHub repo for a handy way to develop WordPress plugins and themes using Docker.

I recently decided to create my first public WordPress plugin which provides basic FitBit stats for your blog.

This was on a fresh laptop (the one handily provided by Automattic, my new employer), so I had the opportunity to try something new in terms of my development environment.

I decided to try out Docker and the new Docker Compose tool (installation instructions – or just brew install boot2docker and brew install docker-compose).

Continue reading “Quick and easy WordPress development using Docker”

The Power of Prototyping

This is the first in what will be a series of blog posts for the Mozilla-Knight Journalism Challenge. This week we heard from Aza Raskin, former creative lead for Firefox and head of user experience for Mozilla, talking about the power of prototyping for understanding problems and building momentum behind your solution.

Continue reading “The Power of Prototyping”

Experience importing an existing Drupal site to Aegir

(Cross-posted from the Aegir group on Drupal.org. Aegir is a brilliant new framework for managing web sites built in Drupal – upgrading, migrating, enabling, disabling and so, SO much more.)

Hi all,

I just wanted to share my experience migrating an existing site to Aegir, in the hope that others will find it illuminating and it will help them avoid some of the pitfalls I encountered.

Firstly, I made sure my site was completely checked into Subversion, and then checked it out on the Aegir host in the platforms directory as “mysite-1.0”. I had decided after reading the available documentation that the best way to bring an existing site into Aegir is to import the whole Drupal distro as a platform and then migrate the “default” site into another existing platform (the latter step isn’t really necessary, but I wanted to avoid having dozens of platforms for all my existing sites – defeats the point of Aegir somewhat).

Secondly, and before I imported the site, I renamed the “sites/default” directory to “sites/mysite.client2.gravityrail.net”. Aegir ignores the “default” site. I then created a symlink, “sites/mysite.com”, because that’s how Aegir does it.

Third, I imported my database. Of course.

Now it was time to import the platform in Aegir. I crossed my fingers, toes and eyes (then uncrossed my eyes because I needed them to see the screen… and my fingers because I needed to type… so at this point only my toes were ensuring good luck came my way, and clearly toes aren’t enough because…)

BAM! It worked!



Time to import the site. Breathe. Breathe. It can’t be this easy, can it?

It wasn’t.

Okay, here I’ve hit my first problem. I wanted the site to have a generated alias to mysite.com, but I think I either forgot or didn’t see the entry box because this wasn’t baked into the generated Apache config in config/vhost.d, and my site (I later found out) wouldn’t appear when the DNS got changed. Whoops!

Lesson 1: Make sure you enter your domain aliases when you import the site in Aegir.

Secondly, the import task failed because of a missing file on a mysqldump, “/dev/fd/3”. Turns out on Debian Lenny you need to make sure you’ve got udev installed so the smart mysql script can create temporary devices containing mysql credentials.

Lesson 2: On Debian, make sure you have udev installed.

But my script was halting at another point now. It was complaining that I wasn’t using a password for MySQL! That’s weird… checked my settings.php, all seems well. Turns out the issue is that my password started with a “#” symbol. Turns out one of our components here doesn’t like certain punctuation in passwords. Similar problems will occur if your password contains } or ) or various other symbols that could be interpreted as PHP/shell/MySQL delimiters of various kinds.

Lesson 3: Don’t include punctuation in your passwords, for now. Hopefully this will be fixed shortly.

Ran it again. Got a bunch of permissions errors on files, typical stuff and I fixed it.

So, finally I got the migration script to run but, critically, by this point I was running it from the command line so I could see this debug output. This has ramifications later.

When the migration script completed, there were a lot of errors to do with missing packages. See, I’d assumed that drush or provision or one of the other smart tools underlying this system would detect the modules in the source platform and, if they were missing in the target platform, it would automatically download them.

Whoops, nope, turns out that’s not the case, for a whole bunch of really good reasons.

Lesson 4: Make sure you have all the required packages installed on your target platform before you migrate.

At this point I decided to flex my Unix command-line muscles and concocted a simple command line to port and enable the packages. As we’ll find out, I’m not as smart as I thought I was.

cp -R source-platform/sites/all/modules target-platform/sites/all
ls target-platform/sites/all/modules | xargs -y enable

See, this assumes there is just one module per directory name, and that the name of the module is the name of the directory. As y’all in Drupal-land know, this just ain’t so. Chalk one up for Java-guy-learning-Drupal.

So, thinking I was done and readying my martini, monocle, slippers, and wallet for the inevitable glory and prestige, I pointed my browser at the site: mysite.clientX.gravityrail.net.


I dropped the martini, the monocle fell out, and my crossed-toes drew blood inside my tartan slippers as I surveyed the damage. Missing images, ill-rendered Javascript, formatting completely gone, fonts in TIMES NEW BLOODY ROMAN. This was no good, no good at all. I was building a professional site, not MySpace. Back to the typing-board.

Okay, time for a few more lessons:

Lesson 5: Copy the themes, not just the modules. I had forgotten that my site’s theme was a Zen subtheme, and you can’t have a subtheme without the super-theme.

Lesson 6: As above, enable all the modules you need. Though this shouldn’t be necessary if the modules are actually present in the target platform when you migrate – Aegir was clearly making a good-faith effort to enable everything when I ran the migrate script.

Lesson 7: If you don’t migrate using the web interface, then your site will be copied as the Aegir user, not as www-data. Then you’ll find that suddenly imagecache can’t create thumbnails of your images, for example. At the very least, do a “chgrp -R www-data sites/mysite.com/files”. Hopefully this will be enough.

Lesson 8: There are plenty of Drupal modules that hate having their site renamed. ImageAPI / ImageCache is one of them. Moving from “default” to “mysite.com” meant that I had to go into the database (shudder) and do an “UPDATE files SET filepath = REPLACE(filepath,”sites/default”,”sites/mysite.com”);” so imagecache could find the files. This is a design flaw in the way that Drupal or this module handles files, and multi-site should be fixed to handle it. I strongly believe no files should have their paths stored relative to the system root in a multi-site framework, for obvious reasons.

So, after fixing permissions, filepaths, enabling required modules, testing and re-testing, I had my site imported and migrated onto Pressflow 6.14.56 and working well.

Then my client changed their DNS, and the site didn’t appear, and they got angry and changed their DNS back. Because on my final successful migration, Aegir rewrote my apache configuration without the Site Alias of mysite.com.

We re-launch today. Second time lucky. Aegir still has some rough edges for newbies, but I feel really excited that I finally have a consistent way of managing all my sites. Migrating your existing sites into Aegir is totally worth it, and I hope that my lessons above help a few people to get into this wonderful new world.

Git in one minute

Based on notes from a recent BarCamp, here’s my one-minute introduction to Git, a distributed revision control system (a system for managing collaborative changes to files, usually used for software development). This is probably only useful to someone who’s already a programmer and already trying to use git, as a kind of cheat-sheet.

git notes


Step 1: Create a directory with files in it. Done? Good. Let’s proceed. “cd” into the directory and…

$ git init <- initialise repo

$ git status <- tells you which files are / are-not in version control

$ git add … <- add files to repo, do it for each “meaningful change”

$ git commit <- commit new files to repo

$ git commit -am “Feature 1” <- commit all changed files to repo, -m “message” sets message without loading $EDITOR

$ git log <- shows recent changes

$ git config user.email “me@mydomain.com” –global <- configure email notifications

$ git branch feature1 <- create a “branch” for feature1. You should branch for each feature

$ git branch <- list branches. “*” indicates current branch

$ git checkout feature1 <- switch to branch “feature1”

$ gitk –all <- horrific-looking but useful GUI

$ git merge feature1 <- merge changes on feature1 into current branch(example assumes you're on a different branch)

If you get a merge conflict, it will look like this:

Auto-merged file1
CONFLICT (content): Merge conflict in file1
Automatic merge failed; fix conflicts and then commit the result.

Hope this helps someone else as much as it helped me…

Synchonising Google contacts with your OS X Address Book without an iPhone

So, I lost my iPhone a while ago and that was annoying.

Then my annoyance doubled when I realised that my Google contacts were no longer being synced to my OS X Address Book. It turns out that Apple will only let you synchonise Google contacts when you have an iPhone connected to the system.

This would have to be the most brain-damaged mis-feature I’ve seen in years. It’s not like my laptop has to access Google through the iPhone. It’s just a completely arbitrary co-dependence of two otherwise utterly unrelated features of the computer.

Luckily there’s a workaround for those who no longer have an iPhone but enjoyed the Google Contact syncing. It’s a short script, so only really useful to those willing to get their hands dirty in the shell.

echo "Syncing Contacts with Google"
/System/Library/PrivateFrameworks/GoogleContactSync.framework/Versions/A/Resources/gconsync --sync com.google.ContactSync
echo "Sync Complete"

There – done! I suppose you could turn it into a launchd script if you’re really keen, but I’m happy to just run it by hand from time-to-time. Eat it, Apple!

Guest Appearance on Byte Into It

Last week on Melbourne’s 3RRR, Georgia Webster, Andrew Fish, Keren Flavell and myself discussed Windows 7, TinyXP, iPhone security, defamation, video games, the seeming success of the Australian ‘net filtering trial and my experiences at the Open Video Conference.

It was a really fun experience and reminded me how much I miss radio. There’s something very liberating about such a simple live medium, and you don’t have to worry about whether you’ve got food on your shirt. Radio is kind of a nerd’s dream, because it’s closer to “pure thought” than all the live visual media.

You can download the MP3 here.

Brix Rules

Ok, so I’ve been playing with Brix, a CMS toolkit from the creators of Apache Wicket that uses Apache Jackrabbit as its content repository.

And it rules.

Jackrabbit (a JCR implementation, i.e. a hierarchical repository for all sorts of content) is maturing fast, with 1.5.0 hot off the presses. It’s performance is really quite good in my simple tests (most page loads creating just one highly optimised database hit).

Wicket is also about to take a great leap, thanks to 1.4’s generics helping everyone keep their code type-safe.

Brix’s own architecture is fascinating. It currently has a very simple GUI, but don’t let that fool you – there’s a lot of hidden power underneath, and the code is very clean and well-factored (if under-commented in parts…)

The combo is a winner, so I’m actually switching the bulk of my own CMS over to Brix as of today. Lots of work, but I get the feeling it’ll all be worthwhile.

Sending HTML Email with Wicket part II: Converting links

In my previous post, I showed how you can use Wicket‘s HTML rendering engine to render HTML emails by faking a request/response cycle.

In this post, I’ll show you how to use an IVisitor to change image and anchor URLs to be absolute instead of relative. This is absolutely essential in order to make your HTML email work – otherwise all your images can’t be found, and your links point to your own mail server.

The trick is to use Wicket’s IVisitor to add a TransformerBehaviour to all the Images and Links that uses a regex to transform the URL after render but before the page is returned.

The code for the IVisitor is below:

private final class RelativeToAbsoluteUrlVisitor implements IVisitor {
        private final String requestPath;
        private Pattern urlPattern;
        private Class<? extends Component> componentClass;

        private RelativeToAbsoluteUrlVisitor(String requestPath, Class<? extends Component> componentClass, String attributeName) {
            this.requestPath = requestPath;
            this.componentClass = componentClass;
            urlPattern = Pattern.compile(attributeName+"="(.*?)"");

        public Object component(Component component) {
            //if this component is of the specified class, update the URL attribute to be absolute instead of relative
            if(componentClass.isInstance(component)) {
                component.add(new AbstractTransformerBehavior() {

                    public CharSequence transform(Component component,
                            CharSequence output) throws Exception {
                        log.warn("Transforming component output: "+output);

                        Matcher m = urlPattern.matcher(output);

                            String attributeValue = m.group(1);
                            int start = m.start(1);
                            int end = m.end(1);

                            //convert relative to absolute URL
                            String absolutePath = RequestUtils.toAbsolutePath(requestPath, attributeValue);

                            log.warn("Got absolute path '"+absolutePath+"' from relative path '"+attributeValue+"'");

                            //construct a new string with the absolute URL
                            String strOutput = String.valueOf(output);
                            String finalOutput = strOutput.substring(0, start)+absolutePath+strOutput.substring(end);

                            log.warn("Returning updated component: '"+finalOutput+"'");

                            return finalOutput;

                        return output;
            return IVisitor.CONTINUE_TRAVERSAL;

Then we override the onBeforeRender() routine to traverse the component hierarchy and add this behaviour to the appropriate elements. Note that I haven’t shown how you get the current absolute request URL, as in my system this is proprietary. There’s plenty of example code floating around on how to do that, anyway.

    protected void onBeforeRender() {

        final String requestPath = MyCustomWebRequestCycle.get().getCurrentUrlAsString();

        IVisitor imageVisitor = new RelativeToAbsoluteUrlVisitor(requestPath, Image.class, "src");
        IVisitor anchorVisitor = new RelativeToAbsoluteUrlVisitor(requestPath, Link.class, "href");

        visitChildren(Image.class, imageVisitor);
        visitChildren(Link.class, anchorVisitor);

So there you have it! All the bits and pieces to create HTML email with Wicket. There’s one more catch though: You have to generate these emails in the same process as the Wicket Application. Calling Application.get() outside of the main process results in an error. In my system, I get around this by generating the HTML email source every time the user saves my Newsletter bean, which means that when it’s finally sent (in the background), it just sends the pre-generated HTML. Easy!


Render a Wicket page to a string for HTML email

Something that’s very desirable to do in Apache Wicket is create HTML emails using Wicket’s brilliant component-oriented markup.

I’ve been working on this problem on and off for ages — it’s tricky because of teh way that markup rendering is so deeply tied to the requestcycle, which in turn is deeply dependent on the httpservletrequest — with good reason, too. That’s where Wicket gets its autoconfiguring magic from!

So in order to use Wicket to create HTML emails, we need to fake the request/response cycle. I wrote this convenient method that renders a bookmarkable page (pageclass + pageparameters) to a string:

protected String renderPage(Class<? extends Page> pageClass, PageParameters pageParameters) {

        //get the servlet context
        WebApplication application = (WebApplication) WebApplication.get();

        ServletContext context = application.getServletContext();

        //fake a request/response cycle
        MockHttpSession servletSession = new MockHttpSession(context);

        MockHttpServletRequest servletRequest = new MockHttpServletRequest(
                application, servletSession, context);
        MockHttpServletResponse servletResponse = new MockHttpServletResponse(

        //initialize request and response

        WebRequest webRequest = new WebRequest(servletRequest);

        BufferedWebResponse webResponse = new BufferedWebResponse(servletResponse);

        WebRequestCycle requestCycle = new WebRequestCycle(
                application, webRequest, webResponse);

        requestCycle.setRequestTarget(new BookmarkablePageRequestTarget(pageClass, pageParameters));

        try {

            log.warn("Response after request: "+webResponse.toString());

            if (requestCycle.wasHandled() == false) {
                requestCycle.setRequestTarget(new WebErrorCodeResponseTarget(

        } finally {

        return webResponse.toString();

One other thing that’s desirable to do is change all relative links in the email to absolute URLs — something that Wicket makes super-easy, if you know how. That will be the subject of my next post.