Automating Local WordPress Site Setup with Scripts Part 3: Automating the Rest

In my last post in the Automating Local WordPress Setup series, I created a WP-CLI package for quickly installing and uninstalling WordPress. I’ve been using this package for a while now, and have been itching to make it more useful for a typical development workflow.

I recently switched from using a single virtual host to hold all of my development sites in subdirectories (i.e. http://localhost/example) to using a dedicated virtual host for each development site. There are several advantages to having it setup this way, but I had been using subdirectories to avoid having to manually manage each virtual host.

I also still catch myself doing things that I know should be automated. Things like deleting unnecessary data, removing the default themes/plugins, and installing new plugins, are things that can be automated to make development easier. In this post we’re going to take a look at some ways to make all that possible.

Working with Virtual Hosts

If you’re not using them already, there are two main reasons for switching to virtual hosts for local development:

  • You can have a different environment for each host, with each site running a different version of PHP
  • The URLs look cleaner – i.e. http://example.dev as opposed to http://localhost/example

Luckily, if you use MAMP Pro, it’s incredibly easy to create new virtual hosts via the command line, which means we can script them!

#! /bin/bash

if [ $# -ne 1 ]; then
    echo $0: usage: Destination Name
    exit 1
fi

DEST=$1

/Applications/MAMP\ PRO/MAMP\ PRO.app/Contents/MacOS/MAMP\ PRO cmd stopServers
/Applications/MAMP\ PRO/MAMP\ PRO.app/Contents/MacOS/MAMP\ PRO cmd createHost "$DEST" "~/Sites/$DEST"
/Applications/MAMP\ PRO/MAMP\ PRO.app/Contents/MacOS/MAMP\ PRO cmd startServers

The above shell script will automatically stop Apache and MySQL, add a new virtual host, and start the servers again so that the new host is accessible right away. To use it, just save it as “add-virtual-host.sh” to a path that is executable and make sure it has the proper permissions. If you’re not sure how to do that, the first article in this series briefly covers creating and executing shell scripts.

Taking things a step further, it’s easy to have the WP Installer package (from part 2 of this series) run this command for you when creating a new site. I added an optional parameter —after_script to the wp installer install command, and use that to fire off any custom shell scripts that should be run after the install:

if ( isset( $assoc_args['after_script'] ) ) {
    WP_CLI::launch( $assoc_args['after_script'] . ' ' . $args[0] . '&>/dev/null' );
}

Now you can update your WP-CLI config file to pass the --after_script parameter by default so you don’t have to type it every time you run the command:

# WP Installer default args
installer install:
  base_path: ‘/Users/Example/Sites‘
  base_url: http://localhost/
  dbuser: root
  dbpass: root
  dbhost: 127.0.0.1
  admin_user: test
  admin_password: test
  admin_email: test@example.com
  after_script: add-virtual-host.sh

With that in place, running wp installer install example.dev will install WordPress and create the virtual host to make the site available at http://example.dev. Pretty snazzy!

Cleaning Up the Install

The first thing I do every time I log into a site is delete the extra themes, plugins, and clear out some of the default data that is generated when installing WordPress. There’s no reason to do that more than once, so let’s automate that as well.

/**
 * Cleanup any unnecessary data after install.
 *
 * ## OPTIONS
 *
 * <dest>
 * : The site to clean up
 *
 * [--after_script]
 * : A custom script to run after the cleanup.
 */
public function cleanup( $args, $assoc_args ) {
    $base_path = isset( $assoc_args['base_path'] ) ? $assoc_args['base_path'] : getcwd();
    $site_path = $base_path . '/' . $args[0];

    WP_CLI::log( 'Removing extra themes...' );
    WP_CLI::launch( \WP_CLI\Utils\esc_cmd( 'wp --path=%s theme delete twentyfifteen', $site_path ) );
    WP_CLI::launch( \WP_CLI\Utils\esc_cmd( 'wp --path=%s theme delete twentysixteen', $site_path ) );

    WP_CLI::log( 'Removing default plugins...' );
    WP_CLI::launch( \WP_CLI\Utils\esc_cmd( 'wp --path=%s plugin delete hello', $site_path ) );
    WP_CLI::launch( \WP_CLI\Utils\esc_cmd( 'wp --path=%s plugin delete akismet', $site_path ) );

    WP_CLI::log( 'Removing sample data...' );
    WP_CLI::launch( \WP_CLI\Utils\esc_cmd( 'wp --path=%s db query "TRUNCATE TABLE wp_posts; TRUNCATE TABLE wp_postmeta; TRUNCATE TABLE wp_comments; TRUNCATE TABLE wp_commentmeta;"', $site_path ) );
    WP_CLI::launch( \WP_CLI\Utils\esc_cmd( 'wp --path=%s user meta update 1 show_welcome_panel "0"', $site_path ) );

    if ( isset( $assoc_args['after_script'] ) ) {
        WP_CLI::launch( $assoc_args['after_script'] . ' ' . $args[0] . '&>/dev/null' );
    }
}

The above function clears out that data so we can get started on development without distractions. Like the wp installer install command, it also accepts an --after_script parameter in case you need to run any additional scripts after the cleanup.

Installing Frequently Used Plugins

If you work with a lot of development sites, chances are at least some of them will share some plugins. We can easily create a command to read a list of plugins or themes and install/activate them as necessary:

/**
 * Add plugins from the provided file.
 *
 * ## OPTIONS
 *
 * <dest>
 * : The site to add plugins to.
 *
 * [--plugin_list]
 * : The path to the file containing the list of plugins to install.
 */
public function add_plugins( $args, $assoc_args ) {
    $base_path = isset( $assoc_args['base_path'] ) ? $assoc_args['base_path'] : getcwd();

    if ( isset( $assoc_args['plugin_list'] ) && file_exists( $assoc_args['plugin_list'] ) ) {
        $plugins = file_get_contents( $assoc_args['plugin_list'] );
        $plugins = explode( PHP_EOL, $plugins );

        foreach ( $plugins as $plugin ) {
            $cmd = 'wp --path=%s plugin install %s';
            $cmd = \WP_CLI\Utils\esc_cmd( $cmd, $base_path . '/' . $args[0], $plugin );
            $result = WP_CLI::launch( $cmd, false, true );
            WP_CLI::log( $result );

        }
    } else {
        WP_CLI::log( 'Plugin list not found' );
    }
}

The above command will loop through a provided file and run wp plugin install for each plugin in the file. Now you can create a simple text file containing the names, paths, or URLs to plugins that you want WP Installer to install, as well as any optional parameters:

better-search-replace
wp-migrate-db 
wp-offload-s3 --activate

And add the path of that file to the WP-CLI config file:

installer add_plugins:
  plugins_list: ‘/Users/Example/Sites/plugins.txt’

Now running wp installer add_plugins example.dev should loop through the plugins that you have defined in your plugins file:

Final Thoughts

That wraps up my series on automating local WordPress site setup. I’m sure there are things that I’m missing that I’ll want to include down the road. For now, being able to use one command to install WordPress and set up the virtual host has definitely helped cut down the amount of time I spend on setting up dev environments.

What are you doing to automate your local workflow? Do you have any suggestions for a better way to handle any of the functionality above?

About the Author

Matt Shaw

Matt is a WordPress plugin developer located near Philadelphia, PA. He loves to create awesome new tools with PHP, Javascript, and whatever else he happens to get his hands on.

  • DeryckOE

    I Matt,

    Great post by the way. I´m wondering how can I install the command. I try but I can´t. Here the output and no work.

    $ wp package install 10up/mu-migration
    Installing package 10up/mu-migration (dev-master)
    Updating /Users/deryck/.wp-cli/packages/composer.json to require the package…
    Using Composer to install the package…

    Loading composer repositories with package information
    Updating dependencies

    and… that´s it, nothing else happens. Of course when I try to run wp installer install wpname I get a “Error: ‘installer’ is not a registered wp command. See ‘wp help’.”

    Thanks in advance.

    • jasonyingling

      My process was stopping at the “Updating dependencies” step as well. It’s apparently a memory_limit issue with composer. https://make.wordpress.org/cli/handbook/common-issues/#php-fatal-error-allowed-memory-size-of-999999-bytes-exhausted-tried-to-allocate-99-bytes

      I’m using MAMP Pro and for whatever reason the php.ini I was accessing by going to File > Edit Template > PHP (php.ini) > (My version of PHP) wasn’t taking. Instead I ran the code to find the correct php.ini file from that link and then updated it through terminal. This code worked to do that:

      `# Find your php.ini for PHP-CLI
      $ php -i | grep php.ini
      Configuration File (php.ini) Path => /usr/local/etc/php/7.0
      Loaded Configuration File => /usr/local/etc/php/7.0/php.ini
      # Increase memory_limit to 512M or greater
      $ vim /usr/local/etc/php/7.0/php.ini
      memory_limit = 512M`

  • Interesting article, thank you.

    I’ve got some bash scripts using WP-CLI aliases that I use to pull production/staging databases down to a local development site, push local databases to staging etc:

    https://gist.github.com/davemac/8890e1fd7bffa79862f9234ad963aa35

    https://gist.github.com/davemac/c7e3697ba162efb45a2a318a01a67f2e

    After reading this article, these might be more portable and reusable as WP-CLI packages.

  • lynch452646@mail.ru

    There are lot of people are want to make word press site. So this is the best useful article for them to make the better website. Thank you so much for write the best helpful content for us.

  • parr53763@mail.ru

    There are lot of people are want to make word press site. So this is the best useful article for them to make the better website. Thank you so much for write the best helpful content for us.