Skip to content

Instantly share code, notes, and snippets.

@cullylarson
Last active July 13, 2021 08:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cullylarson/264340236ccff2405c1c2a0a7e38124a to your computer and use it in GitHub Desktop.
Save cullylarson/264340236ccff2405c1c2a0a7e38124a to your computer and use it in GitHub Desktop.
Installing Wordpress as a dependency

Wordpress as a Dependency

How to install Wordpress as a dependency in your project, without including the WP install in version control.

Rationale

In the spirit of The Twelve Factor App, we want to "explicitly declare and isolate dependencies". Wordpress doesn't really promote this idea out of the box, so we have jump through a few hoops to do it. This document describes a simple method to include Wordpress as a dependency in this way.

General Idea

We'll define and manage WP as a dependency using Composer. We also want to keep Wordpress out of version control (because it's a dependency). The things we do want to keep in version control will likely be the theme or plugin we're creating. The default Wordpress directory structure doesn't lend itself to keeping these two things separate, since the wp-content folder (where themes, plugins, etc. live) is actually inside the Wordpress install folder.

We could simply make a build script to create symbolic links to our theme, plugin, etc. However, we would need to manage these links when deploying, updating, etc. and it would end up being a bit of a pain. The good news is that Wordpress allows us to host the wp-content folder in a separate folder than the default. In this way, we can install Wordpress in its own folder, which we tell our version control system to ignore, and host our project code in its own folder that our VCS tracks.

Directory Structure

This is what the directory structure of your web folder will look like, after following the steps below.

composer.json	
index.php
wp-config.php
/content			# plugins, themes, etc.
/wp					# this is where Wordpress is installed

Steps

  1. Create composer.json in the web folder of your project:

    {
        "repositories": [
            {
                "type": "package",
                "package": {
                    "name": "wordpress",
                    "type": "webroot",
                    "version": "4.5.2",
                    "dist": {
                        "type": "zip",
                        "url": "https://wordpress.org/wordpress-4.5.2.zip"
                    },
                    "require" : {
                        "fancyguy/webroot-installer": "1.0.0"
                    }
                }
            }
        ],
        "require": {
            "php": ">=5.5.0",
            "wordpress": "4.5.2",
            "fancyguy/webroot-installer": "1.0.0"
        },
        "extra": {
            "webroot-dir": "wp",
            "webroot-package": "wordpress"
        }
    }
    

    This tells Composer to install Wordpress in the wp folder (relative to composer.json).

  2. Install Wordpress:

    $ composer install
    

    To update Wordpress, you would just change the version number in composer.json and run composer update.

  3. Since Wordpress is installed in the wp folder, we need to copy index.php out of it, and into the same folder as composer.json. This will allow Wordpress to load itself.

    $ cp wp/index.php .
    
  4. We also need to make one small change to index.php, to include wp-blog-header.php from the wp folder. The entire index.php can look like this:

    define('WP_USE_THEMES', true);
    require( dirname( __FILE__ ) . '/wp/wp-blog-header.php' );
    

    I like to keep index.php in version control, since it's actually specific to my project (it's not the same index.php file as the one installed by Wordpress).

  5. Create a folder named content in the same folder as composer.json. This is where your themes, plugins, etc. will go. Initially, it's easiest to just copy the wp-config folder from the Wordpress install.

    $ mkdir content
    

    OR

    $ cp -R wp/wp-content ./content
    

    If you create the folder by copying from Wordpress, be sure to delete any themes or plugins you don't want in your project.

  6. At this point, we need to configure Wordpress and tell it where our content folder resides and where Wordpress is installed. We don't want our wp-config.php file to be clobbered every time we update Wordpress, so we need to move it out of the wp folder and into the same folder as composer.json.

    $ cp wp/wp-config-sample.php ./wp-config.php
    

    Wordpress is smart enough to find it here.

    Remember to tell your version control system to ignore wp-config.php since system-specific configuration should not be tracked in version control.

  7. Now, edit wp-config.php and set the following constants, to tell Wordpress where the content folder is and where Wordpress is installed: ABSPATH, WP_SITEURL, WP_HOME, WP_CONTENT_DIR, and WP_CONTENT_URL. I've found it useful to create a HELPER_BASE_URL constant and use it for the web-related constants. For example:

    define('HELPER_BASE_URL', 'http://localhost'); // no trailing slash
    if ( !defined('ABSPATH') ) define('ABSPATH', __DIR__ . '/wp/'); // trailing slash
    define('WP_SITEURL', HELPER_BASE_URL . '/wp');
    define('WP_HOME', HELPER_BASE_URL);
    define('WP_CONTENT_DIR', __DIR__ . '/content');
    define('WP_CONTENT_URL', HELPER_BASE_URL . '/content');
    

    With this configuration, I only need to change the HELPER_BASE_URL constant. Everything else is defined using other constants.

    Of course, you still need to set all of your other Wordpress configuration stuff.

  8. Now you can have Wordpress install itself in the database. The admin area URL is e.g.: https://yourprojecturl.com/wp/wp-admin

  9. That's it!

Notes

Installing Wordpress Again

After going through the steps above, to install Wordpress again on another machine, all you have to do is:

  1. Clone your repo.

    $ git clone path/to/myproject.git
    $ cd myproject
    
  2. Install Wordpress.

    $ composer install
    
  3. Set up wp-config.php

    $ cp wp/wp-config-sample.php ./wp-config.php
    $ vim wp-config.php
    
  4. Install the database at e.g. https://yourprojecturl.com/wp/wp-admin

Automated Database Setup

If you want to automate the installation of Wordpress into the database (e.g. as part of an automated build process), you can use a great tool called WP-CLI. After you install wp-cli (when I install it, I name the executable wp), you can run some commands like this:

$ wp core install --path=./wp --url="<base url to site>" --title="Site Title" --admin_user=<username> --admin_password=<password> --admin_email=<email>
$ wp option update blogdescription ""
$ wp option update permalink_structure "/%postname%/"
$ wp option update timezone_string "America/Los_Angeles"
$ wp option update start_of_week "0"

This example has some options that I like, but you can set any Wordpress options you want using these commands.

Setting up Wordpress using a build script like this has a few advantages:

  1. It saves you the trouble of manually going into the Wordpress admin area and installing Wordpress into the database.
  2. You don't need to remember all of the options you want to set.
  3. It keeps you from making mistakes or forgetting something, since the setup is automated.
  4. A script like this serves as documentation of your setup process. If you ever forget how your site is set up, just look at your build script.

Plugins/Themes in Composer

If you want to add wordpress.org plugins/themes as dependencies in composer.json, check out https://wpackagist.org/. It manages wordpress.org plugins/themes as a Composer repository.

To add private/third-party plugins to composer.json, check out WordPress Plugins with Composer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment