How to Approach Modern WordPress Development (Part 1)
It’s no secret that the WordPress codebase is a mess. Personally, every time I go through it, all I want is to curl up and cry. On the other hand, WordPress is way ahead of its competition. An easy-to-use and powerful CMS is an enormous undertaking, and WordPress remains popular because it delivers this.
So why would we care about the quality of code in WordPress core? It works, right?
Yes, it works, and the 15-year-old codebase is unlikely to be completely refactored by its volunteer maintainers. Unfortunately, this means it also functions as an example of coding “the WordPress way,” excusing numerous developers for not following best practices and modern development techniques. So many WordPress plugins and themes have infamously bad code, and blindly following legacy practices only continues the trend.
But who cares about bad code that still does its job? Well, nothing is free, and someone pays for a badly done job. With the WordPress codebase itself, its maintainers pay with their time, thankfully. But with your own code, it’s your client who pays.
For any even moderately complex system, the cost of initial development is insignificant compared to the cost of maintaining it, and maintenance also means adding new functionality. Hiring a developer to fix poorly designed and implemented software is going to cost several times more than developing it properly from the start.
Cheap solutions are always the most expensive ones in the long run. Or they get abandoned after running out of budget. We actually save clients’ money when we follow proven software design principles and practices. These methods are not some hyped-up fad, nor change for change’s sake. The wisdom here is born from collective developer experience, and following it really does pay off.
Obviously, this doesn’t apply to truly simple tasks like adding a few lines of CSS or a couple of custom posts and rewrites. But slapping together a few plugins (or more commonly several dozens of plugins) or churning out a Visual Composer-powered site isn’t software engineering, anyway.
Modern WordPress Development Workflow
In general, quality code is:
- Readable. It is easy to understand what code does and why.
- Modular. Small blocks of code with a clear purpose are easy to understand, develop, and test.
- Reusable. Re-using already developed modules for solving similar problems significantly speeds up development.
- Maintainable. Modifying old functionality or introducing new features is easy.
The main results—lower cost of development and ownership—have many spinoff benefits that I won’t get into here.
Instead, I’ll focus on which development techniques and best practices can help you to produce quality code. Let’s start with version control.
Use Version Control
This means using Git. Sadly, “cowboy coding” on production over FTP is pretty much still a thing. Just recently I worked for a UK-based agency and they had files with names like these all over their codebase:
functions copy 2.php
The very first thing you should do when taking on a WordPress site is to put it under version control. Tanking Servers is a fun retrospective of WordPress development mistakes. It would have been very easy to amend those—and similar mishaps that have probably happened to everyone—using Git.
Made a mistake in your code and the whole site went down?
git reset gets everything back the way it was. New version update broke everything?
git reset works as a time machine. Some malicious code appeared from nowhere?
git status shows any new files, deleted files, or changes to any tracked files. Then you just
git checkout, restoring the originals.
BEWARE OF EXPOSING THE
OK, it’s clearly important to use Git. But when you do, it’s just as important to avoid exposing your Git repository to being hacked. The problem comes when you have
.git folders exposed and store your credentials in them.
A standard WordPress installation fully lives in a public web folder, and the
.git folder is very likely to be there as well. Obviously, no login credentials should be stored in the Git repository, but it so happens that most repositories do contain some sensitive information that shouldn’t be leaked outside.
So public access to the
.git folder should be blocked. If you are using Apache, adding the snippet below at the top of the
.htaccess file will block access to the
.git folder and to the log files as well. Log files often contain sensitive information, so it’s wise to make them unavailable as well. For different web server setups, please ask your DevOps expert for help.
RedirectMatch 404 /\.git RedirectMatch 404 ^.*\.log
Use Separate Environments
Do not do development on live sites—this is a recipe for downtime and unhappy clients. OK, but how should you set it up?
Ideally, there should be three development environments, with code always going in one direction: local → staging → production. This is a proven method for avoiding collisions. All core, plugin, and theme updates are first done locally, then tested on staging, and finally deployed to production.
For example, the server-specific configuration could be stored in a separate file. You can create a
wp-config-local.php for each local and staging environment. (Don’t forget to add it to your
.gitignore file!) Then add the following snippet to
if (file_exists(dirname(__FILE__) . '/wp-config-local.php')) : // use local settings require_once(dirname(__FILE__) . '/wp-config-local.php'); else : // production settings endif;
Often the best way of setting up different environments is using environment variables. If you’re not familiar with this concept, I would advise using a complete modern solution like Roots.
The WordPress command-line interface (WP-CLI) is an extremely useful tool for administering WordPress installations. Having access to WP-CLI means having the ability to run virtually any WordPress API function. For example, you can add, remove, and edit users and their passwords with WP-CLI. Useful if you’ve just inherited a site and the owner has locked themselves out.
Another example is that initial deployment is a breeze with WP-CLI. These can be accomplished with few commands:
- Downloading core, themes, and plugins
- Searching and replacing in the database
- Adding an admin user
Moreover, these actions can be scripted and automated.
Use Advanced Deployment Options
Speaking of automation, it’s worth learning some deployment technologies and processes like:
- Continuous integration/continuous deployment/delivery (CI/CD)
- Automated testing (including front-end regression tests)
Granted, going from not using version control to dealing with Docker is a huge leap to make and will likely be overwhelming for a typical one-person WordPress project. Some options may not even be possible depending on your hosting provider. But advanced deployment is a must-have for teams and for larger projects.
For projects of any size, though, linting is a boon to most developers. Linting means automatically checking your code for errors. A fully-featured IDE such as PHPStorm already does that out of the box; however, simpler editors such as VSCode or Sublime Text need a dedicated program called a linter. One way of setting this up is configuring your editor to run a linter whenever you save a file.
PHP_CodeSniffer is the de-facto linter for PHP. In addition to checking for syntax errors, it can also check if your code follows style guidelines such as PSR-2. This greatly simplifies following coding standards.
A powerful use case here is incorporating linting into a CI/CD build pipeline so all code is automatically validated before being deployed.
Modern WordPress Front-end Development Techniques
With a proper workflow now set up for your overall WordPress project, let’s dive into best practices for the front end.
Use Modern Tooling: Sass and ES6+
The front-end development world is ever-changing and always in motion. Once we thought that Sass was the best tool for writing CSS—and for pre-Gutenberg WordPress development, it still is—but then everyone began talking about CSS-in-JS and styled components.
Even WordPress couldn’t resist and picked up a few of those new technologies. Gutenberg, the new block editor, is built on React and a REST API.
You should definitely get up to speed with these core front-end technologies:
- ES6+. The WordPress documentation calls it ESNext and even encourages using it.
- Sass. Used by WooCommerce and the best way to write CSS if you are not into the CSS-in-JS thing yet.
- Webpack. Even WordPress core uses Webpack and Babel now.
Transition from jQuery to Vue.js or React
The WordPress core and almost all WordPress plugins depend on jQuery, so you can’t just stop using it. Actually, it doesn’t make sense to stop using it for simple tasks such as hiding a couple of
<div>s or doing a one-time AJAX request when you are used to doing it that way. jQuery is going to be loaded anyway, and it’s simple and easy to use.
Complex apps are where jQuery struggles: Hard-to-follow logic, callback hell, global variables, and no HTML templating. This clearly calls for a different way of organizing the front-end app.
Modern front-end libraries such as React use object-oriented programming (OOP) principles and organize front-end app architecture into modular, reusable components. A component contains all the code, markup, and “component state” (variables) for a particular element. An element could be almost anything: A button, input field, user form, or a widget that displays recent posts from the WordPress REST API back end. Components can contain other components, forming a hierarchical relationship.
With the complexity of web pages nowadays, organizing an app into components is a proven way of building maintainable, fast web apps of any complexity. Components are highly reusable, isolated, and thus easily testable “bricks,” so it really pays to learn this concept.
React throws you into the deep end by using ES6 features, classes, proprietary JSX syntax, and Webpack build pipeline straight away. The learning curve is quite steep.
Vue.js, on the other hand, is much more beginner-friendly, and can be used by just dropping in a
After working through a few Vue.js projects, you’ll be better prepared to dive deep into React. Not that it’s always needed, but Gutenberg development, for example, does require it.
Use the WordPress REST API
WordPress’ REST API is just a standardized interface for remotely requesting and modifying data from WordPress. It’s more a software architecture thing than a completely different way of coding. The same old jQuery AJAX snippets could be used with slightly different parameters.
The most important benefit? Since the WordPress REST API standardizes communication between the back end and front end, it’s a major step towards modularity, reusability, and readability in your code. Those terrible templates with HTML and PHP mixed together and some SQL thrown into the mix have to go. Once templates are just HTML with placeholders for data passed as parameters, there is no major difference between passing that data in PHP or via a REST API to a front-end app.
You may also want to look into WPGraphQL. It may or may not eventually replace the WordPress REST API, but it’s gaining traction fast.