At several of the WordCamps I attended earlier this year, the topic of individual WordPress development processes seemed to come up often—whether it was in regards to version control, coding standards, or just getting your feet wet as a new dev. As well, folks like Tom McFarlin, who wrote a great series about Professional WordPress Development, have been contributing to the discussion around this at length. I’ve heard encouragement from other devs several times to share “the way you do things”.
The following is the way I set up, develop, test, and deploy, currently. Two quick notes:
- A process like this is never final, and should only get better over time. This is a snapshot of a process I’ve found useful.
- I’m not suggesting that this is the right way to do things—it’s just the way I do them. Feel free to leave a comment if you have a suggestion or want to share yours!
Local Development Environment
I’ve been using MAMP/MAMP Pro for quite some time, with very little issues. I like that it’s self-contained, allowing me to use the native MAMP stack on OS X for something completely different, like working on Pardot.
Git‘s entered ubiquity within my workflow. Between all of its own features and the availability of needed resources (like WordPress itself on GitHub), it’s quicker and easier for me to let Git do the work. Although I do love GitHub, I use BitBucket for my development because of the pricing structure: GitHub’s is based on private repositories, whereas BitBucket’s is based on users. Since I’m really the only user for now, I can set up unlimited private repos on BitBucket for free.
Put on some Led Zeppelin and let’s dig in by creating a new WordPress site from scratch, using the command line (which is your friend).
We’re going to use the official, public Git repository of WordPress to download the files instead of clicking through folders. Why? It’s faster, and you can stay in the command line to get things done. For what it’s worth, I’m sure you could create a sort of shell script from these lines.
Let’s assume you have MAMP/MAMP Pro installed. Hop into that directory via Terminal:
Now, we’ll clone WordPress, checkout the latest version, and remove version control from that directory. Note that you should replace items in brackets (i.e. [project directory]) with whatever works for you. Just make sure it stays consistent throughout this process.
git clone https://github.com/WordPress/WordPress.git [project directory] cd [project directory] git checkout 3.5.1 rm -rf .git
Now, let’s create the new database and give permissions using the command line as well.
../../Library/bin/mysql -uroot -p CREATE DATABASE [DB name]; GRANT ALL ON [DB name].* TO 'root'@'localhost'; exit
Now, go create a new repo on BitBucket. It can be private or public, but grab the repo’s URL. We’re going to set up the
wp-content folder as our local Git repo, since anything we’re doing to a WordPress installation should be done within this folder. Don’t hack core. Let’s set it up, make our first commit, and push:
cd wp-content git init git remote add origin [Bitbucket Repo URL] git add . git commit -m "Initial Commit" git push -u origin master
Well done, friends! Now, go to the URL of your [project directory] (i.e. http://localhost:8888/[project directory]), and run the install. With a few clicks, you should be off to the races.
Now, let’s do a couple of useful things before proceeding.
Automated DB Backups
Git hooks are fantastic tools and can be used for nearly anything. The most vital use in this environment, to me, is an automated DB backup that runs before a commit and adds the ‘dump’ file to a directory within
wp-content. This keeps our local DB backed up (which is always useful), but also ensures easy access to that file for initial deployment.
Let’s make this pre-commit script, based on Ben Kulbertis’s:
touch .git/hooks/pre-commit sudo nano .git/hooks/pre-commit
Now, copy and paste the below into the pre-commit file that just opened, replacing the items in brackets with the appropriate string. If using Nano in Terminal really freaks you out, type in
open .git/hooks, right-click the pre-commit file, and open it with TextEdit,
echo "Pre-commit started." #!/bin/sh /Applications/MAMP/Library/bin/mysqldump -u [MySQL user] -p[MySQL password] --skip-extended-insert [DB name] | gzip -9 > /Applications/MAMP/htdocs/[project directory]/wp-content/db-backups/[DB name].sql.gz cd /Applications/MAMP/htdocs/[project directory]/wp-content git add db-backups/[DB name].sql.gz echo "Pre-commit finished"
Then, correct the permissions, add the new directory for your backups, add, and commit:
sudo chmod +x .git/hooks/pre-commit mkdir db-backups git add . git commit -m "Add DB Backups" git push -u origin master
This is certainly not required, but I don’t use the Hello Dolly plugin or the TwentyTen theme that comes with WordPress, so I remove them. Make sure if you do this, though, that you keep the TwentyEleven (or TwentyTwelve with 3.5) theme—the best way to debug a massive issue is always to disable all plugins and use the default theme.
git rm -rf plugins/hello.php git rm -rf themes/twentyten git add -u git commit -m "Remove Hello Dolly and TwentyTen" git push -u origin master
Themes & Child Themes
This part of the process depends entirely on what theme you want to use and how you can get to it. You’ll likely have to download, unzip, and copy the theme over to your
Speaking of child theming, for the sake of your sanity, make sure you’re using this capability instead of hacking existing themes.
If you’re using Standard and would like to roll my child theme, it’s publicly accessible via GitHub. I keep it updated, and it’s got some great extensions like Bootstrap shortcodes and Font Awesome. If you’d like to roll it and forget it using the command line, make sure you’re in your
wp-content folder and run:
git clone https://github.com/logoscreative/logos-child themes/logos-child rm -rf themes/logos-child/.git rm themes/logos-child/.gitignore
Make sure you commit after adding your theme(s)!
You could also roll this as a Git Submodule if you like the child theme as-is and want to be able to pull updates:
git submodule add https://github.com/logoscreative/logos-child themes/logos-child
Sweet! You’re all set to develop locally. Add plugins and such as you see fit.
With BrowserStack, you can test your local sites in pretty much any conceivable browser. There’s really no explaining to do here: pay and use it. I don’t know of any better option whatsoever, short of actually having those machines and environments present physically.
Depending on your live hosting environment, you can often set up a place to
git push your files. In a shared hosting environment, you may be able to follow Arlo Carreon’s instructions with some tweaks, or you may be using WPEngine (which I highly recommend, therefore, that’s an affiliate link), and they have their own awesome Git setup. Either way, if you can get this set up, you can push directly to the server with:
git push [remote URL]
It will change your life if you’ve solely been using FTP to move things to a live server.
Once our files are uploaded, we’ll need to get the database updated. The way to do this varies wildly depending on your hosting, but you want to import the latest file in your
See how useful that is? It’s already there and ready for you.
Once you import, you’ll need to make sure all the URL’s in the database get changed from your local URL to your live one, or else your site will, um, not work at all. This is not as easy as a simple search and replace query because of serialized arrays and such, so I use the amazing Search Replace DB script, an open source piece of magic that does this for you. Upload it to your main parent directory (the one with
wp-config.php) on the live server and follow the instructions. Remember to delete it once you’re done! Otherwise, you’re giving someone pretty terrible access to wreak havoc on your DB.
Keep Working Locally
The next time you need to fix a bug or add a feature for the client, just overwrite your local files with what’s on the live server (if they’ve updated any of them) and do the same database-search-and-replace as above, but replacing the live URL with your local one. Do the work locally, test, and re-deploy. This keeps useful backups of everything for you and the client on a third-party server, as well being a useful emergency tool. Did a client accidentally break something editing a file? Push your most recent working commit from Git to get the site back up!
Do you have something you’d like to add? Have a question for me? Did I miss anything, or type anything incorrectly?
Let me know in the comments. Happy developing!