Managing the WordPress core with Composer

Hello there!
In this blog post I will talk a little about installing the WordPress core using Composer, and why you would want to do that.

First of all, installing WordPress in a separate directory is something you really should do. Find more info about it in the Codex.
Why? The most important reason is that you always want to keep your own code clean and separated from all third party code (Composer to the rescue!), even the WP core. Installing it in a separate folder gives us that opportunity.
The absolutely first step down this road would of course be to install the third party plugins this way since most of the”pollution” would come from this. Read my previous blog post about that here.

Alright, let’s do this!

The steps below are inspired by the WordPress Skeleteon project and

Step one: make sure Composer is installed and is working as expected.
Follow the instructions over at

Step two: setup your composer.json
You most probably already have a composer.json in the root of your project. Make sure to add the config beneath.

"repositories": [
    "type": "package",
    "package": {
      "name": "wordpress",
      "type": "webroot",
      "version": "3.9.1",
      "dist": {
        "type": "zip",
        "url": ""
      "require" : {
        "fancyguy/webroot-installer": "1.1.0"
"require": {
  "wordpress": "3.9.1",
  "fancyguy/webroot-installer": "1.1.0"
"extra": {
  "webroot-dir": "wp",
  "webroot-package": "wordpress"

The fancyguy/webroot-installer is used to move the WP core files from the vendor folder to the directory specified at extra / webroot-dir.

Step three: create the correct folder structure
The structure would look something like this:

    wp/ #Will contain the WordPress package
    wp-content/ #Will contain all my themes and plugins
 composer.json #This is in the root of the project

You could also take a look at the WP Skeleton project for inspiration to the folder structure.
Please note that we are not using Git submodules (since it can cause a lot of headaches) and that our content folder is called wp-content instead of content (keeping it simple!).

Step four: Modify index.php and wp-config.php
The index.php in the wordpress folder should look like this:

 // WordPress view bootstrapper
 define( 'WP_USE_THEMES', true );
 require( './wp/wp-blog-header.php' );

Note that we are including wp-blog-header.php via the wp folder specified in the steps above.

The wp-config.php also needs some updates since we have a custom directory for both core files and the wp-content (plugins, themes and uploads). First of all, add information some info on where to find wp-content:

// ========================
 // Custom Content Directory
 // ========================
 define( 'WP_CONTENT_DIR', dirname( __FILE__ ) . '/wp-content' );
 define( 'WP_CONTENT_URL', 'http://' . $_SERVER['HTTP_HOST'] . '/wp-content' );

Great – content will now be loaded from the correct directory. More info on changing folders for content, plugins, themes and uploads can be found in the Codex:
A word of warning: poorly written plugins and themes might break down on you when using custom folders for wp-content.

Now find this lines:

/** Absolute path to the WordPress directory. */
 if ( !defined('ABSPATH') )
 define('ABSPATH', dirname(__FILE__) . '/');

And change it to this (notice the /wp that has been added to ABSPATH) to make WordPress load your core files from the wp folder:

// ===================
 // Bootstrap WordPress
 // ===================
 if ( !defined( 'ABSPATH' ) )
 define( 'ABSPATH', dirname( __FILE__ ) . '/wp/' );

Step five: install and celebrate!
Now we are almost good to go! Just open up your favourite terminal, go to the root of the project and type composer install. If everything is working as expected you should see something like this:

Loading composer repositories with package information
 Installing dependencies (including require-dev)
 - Installing fancyguy/webroot-installer (1.1.0)
 Downloading: 100%
 - Installing wordpress (3.9.1)
 Downloading: 100%
 Writing lock file
 Generating autoload files

Open your WordPress installation in your favourite browser to verify.

This part should now of course be added as a step in your deployment procedure. At Aftonbladet we are using Vlad the Deployer and have a task for running composer install just before symlinking deployed directory to the Apache working folder.

(optional) step six: modify .htaccess
Depending on your setup, you might not need this step. If images seems to be broken, javascript from WP can’t be loaded or any other strange problem occurs, change your .htaccess (in the wordpress folder) to this:

RewriteEngine On
 RewriteBase /
# add a trailing slash to /wp-admin
 RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
 RewriteCond %{REQUEST_FILENAME} -d
 RewriteRule ^ - [L]
 RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) wp/$2 [L]
 RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ wp/$2 [L]
 RewriteRule . index.php [L]

If you already have modified .htaccess, these changes would probably be in the last section of the file replacing the standard rewriterule created by WordPress.

That’s all!
Hopefully you will as well see the potential of using Composer to install WordPress core to a custom folder, keeping your own code, neat, lean and clean.

Next blog post up: creating your custom packages from zip archives or directly from GitHub.
Soon in a blog near you.

A Holistic View on Developer Productivity

What does developer productivity mean, really? Is it churning out more code or less code? Is it to have less bugs in production or shipping code more often? Is it doing a lot of things or just one thing? Let’s think about this for a moment. I believe developer productivity is about getting more things […]

Improving the usability of Aftonbladet Video-clip pages

We have recently started the process of improving the usability of video-clip pages. In order to get an idea of where Aftonbladet stands compared to other world-class online video/news providers, we conducted an online test answered by 110 visitors of Aftonbladet TV. In this test we compared their perception of an Aftonbladet TV video-clip page […]

Schibsted’s 1st iOS Deployment Meet-up

Schibsted’s 1st iOS Deployment Meet-up Thursday, 28th of April 2016: getting to know each other, guests arrive Friday, 29th of April 2016: the meet-up date We here at Aftonbladet had been planning on having a meet-up with iOS developers across various Schibsted companies for many months. We had a range of topics in mind for […]

Hackday: The Future of Storytelling is social, engaging and rewarding

We gathered students, journalists, developers and designers to get together and conceptualize something new for the news industry. This was our first organized hack event – The Future of Storytelling Hack. The hack was a team-based, news-media-focused prototyping and experimentation event within storytelling over two days at Kungsbrohuset, Schibsted and Aftonbladets headquarter in Stockholm. A good story used to […]