Powerful Must-Have Tools for Every WordPress Developer

While developing for WordPress we frequently get into situations that call for specialized plugins and tools to make our lives easier. Importing test posts, regenerating images, automation of WordPress reinstallation, creating options pages – just a fraction of an endless list.

In this article I’ll showcase some tools that I use personally to make my workflow a lot better and a lot faster. Some will be more advanced than others. Take your pick and remember that you can always create your own tools, and there is always room to grow.

  • Developer

    Developer's featured image in the repository
    A very well-known plugin for developers, it recommends and installs plugins related to your development area. You can be sure that all the included modules are trustworthy since Automattic’s name is associated with is.

    There is a great article about it here on WPMU DEV by Sarah Gooding.

  • Monster Widget

    A monster hiding in a tree in the swamp
    The first thing I used to do whenever I finished the widgets section of a theme was assemble a widgetized area consisting of all built-in widgets. This is a tiring and monotonous task, especially if you have to repeat it on more than one test site.

    Monster Widget alleviates the pain by providing a single widget which you can add to any sidebar. This single widget actually displays all the default ones shaving a good 5-10 minutes of fiddling-around-time off your day.

    If you’re developing for WooCommerce don’t miss the WooCommerce Monster Widget plugin which does exactly the same thing for WooCommerce – it shows all its widgets.

    Interested in Monster Widget?

  • RTL Tester

    RTL isn’t important, right? After all, how many people use it? Well it turns out, quite a lot. I can’t say I’m a linguistics expert but if you just look at Arabic, it is the fifth most spoken language used by over 200 million people. Arabic is just the largest group a whole host of other languages use right to left script.

    If this weren’t enough, RTL support is just so easy to add there really is no excuse for excluding over 200 million people from enjoying your product. The only difficulty is simulating an RTL environment, but RTL Tester comes to the rescue. With a handy button in the toolbar you can switch from LTR to RTL in a jiffy.

    I don’t particularly like to use the admin toolbar on the front-end so I usually have it disabled. Luckily I can add ?d=rtl to the URL to change into RTL mode. To change back you have to add ?d=ltr, simply dropping the query string is not enough.

  • Regenerate Thumbnails

    While thumbnail sizes should be planned out in advance, somehow I always seem to need to add a few pixels, or shave a couple off. If a thumbnail needs to be 600×320 pixels you should never use a larger image. Any sort of resizing uses processing power and decreases image quality.

    Regenerate Thumbnails looks at your defined image sizes (built in and custom) and creates a version of your images for each. You can let it run loose on your media to go through all of them, or you can target a specific image and regenerate that.

    Interested in Regenerate Thumbnails?

  • Theme Check

    Theme Check is a must have for every theme developer. Even if you have many themes under your belt, are you absolutely sure you have no hidden files in there? Are you sure there’s no .svn folder? Are all the stylesheet tags from the official list? Have you implemented all required features? There aren’t any depreciated functions and you’re not using bloginfo('url') are you?

    Theme Check looks over your shoulders and makes sure that anything that can be automatically checked is checked. While it doesn’t replace unit tests and user testing it’s a great tool for conforming to submission guidelines and best practices.

    Interested in Theme Check?

  • User Switching

    I don’t usually need to develop for different WordPress roles but when I do it’s sure great that User Switching is around. Just select a user from the users table and click “Switch To.”

    One feature which would make this plugin even more useful is the ability to switch to any user from the admin toolbar. You currently have to go to the users table to do so. You can switch back via the admin toolbar though.

    Interested in User Switching?

  • Advanced Custom Fields

    It’s rare that I use a plugin for actual coding but Advanced Custom Fields (or ACF) is one of them. This plugin allows users to create custom fields and add them to different areas of the admin. You can create options for posts, pages, users; even taxonomies and separate options pages.

    You can set advanced display logic and conditions for each separate field; showing them for specific user levels, when on option is set to a specific value and so on. There are a bunch of input types to choose from by default and more are available via additional community plugins.

    ACF has a premium version which allows you to create repeater fields, galleries, content builders and options pages. With the new ACF pro you can get all of them for $25, or $100 for a developer licence. This is a hefty price, but it has been worth every penny to me personally.

    What’s great about ACF is that it can be hidden from view and options can be imported/exported easily. Just export to PHP and build the options right into your theme/plugin. It also comes with extensive documentation making our lives as developers a lot easier.

    One of the biggest downsides of ACF is that the developer licence does not allow adding the pro version to free products, only premium ones. This prevents me from using the repeater and gallery fields for example, or at least forces me to write my own versions of them.

    Interested in Advanced Custom Fields?

WP-CLI

WP-CLI is just so dang useful it deserves its own section with lots of examples to show you just how awesome it is.

WP-CLI is a set of command-line tools for managing WordPress installations. You can update plugins, set up Multisite installs and much more, without using a web browser. – wp-cli.org

One of the most common things I use WP-CLI for is to mirror sites from my localhost to an online setting in about 20 seconds. This actually consists of a whole database migration which is pretty impressive. I also use it to create fresh installs of a site for testing what my plugins and themes do upon activation. This includes the automatic installation of plugins, themes and even test content like WPTest.io

Installing is extremely simple on Mac or Linux, just follow the instructions on the home page. if you’re on Windows take a look at the alternative installation methods on Github. Once you have it up and running you can start making some magic happen. I will be referring to the “terminal” and other OSX specifics, but the methods should be the same for Windows.

Installing WordPress

With WP-CLI you can replace the famous 5-minute install with a (less famous) 10 second install. Create a database and a directory for your WordPress installation and navigate to the directory in the terminal. Using the following lines should get WordPress up and running:

1
2
3
wp core download
wp core config --dbname=yourdb --dbuser=yourdbuser --dbpass=yourdbpass --dbhost=youdbhost --dbprefix=yourdbprefix
wp core install --url=yoursiteurl --title=sitetitle --admin_user=username --admin_password=password --admin_email=youremail

If your environment is set up correctly you can even create the database via the command line using wp db create once you’ve set up the config.

This can be further simplified by creating a bash script of course. You can store the values as variables and modify them as needed for each project. For a full list of what you can do, take a look at the core and db command documentation.

Maintaining WordPress

The WordPress core, plugins and themes can easily be maintained with WP-CLI. Here are a few lines that will update all of these:

1
2
3
wp core update
wp plugin update --all
wp theme update --all

You can of course opt to only update specific themes and plugins, you can even do a “dry run” to preview what would be affected before doing the real thing. Take a look at the core, theme and plugin command documentation for more.

Migrating WordPress

The most difficult part of migrating WordPress is getting the database just right. You’d think that a simple search and replace would work but it doesn’t, due to serialized arrays. Moving the files themselves is a simple copy-paste matter so I won’t go into detail here.

One thing I recommend is using a cloud service like Amazon S3 to store your media. If you use the Amazon S3 and Cloudfront plugin your media will be mirrored to, and loaded from, your S3 server. This not only speeds up your site but you’ll never need to worry about moving media files ever again.

Anyway, back to WP-CLI. Once the files are in place you need to take care of the database. The first step is to make sure you have SSH access to your server and WP-CLI is installed. SSH access is a bit out of the scope of this article, but all major hosts have guides for this and support staff will surely help you get this set up. Setting up WP-CLI on your server requires the same procedure as on your computer, refer back to the installation guide for help.

Let’s go ahead and export the database on our local installation.

1
wp db export db.sql

The second step is to upload this to your server. You can upload the file via FTP, your control panel, or any other means. I prefer using SSH to do it. if you’re using Mac or Linux you can use the scp command.

1
scp db.sql user@domain.com:/path/to/wordpress/db.sql

If you SSH into your server and go to the WordPress directory you should be able to import the database using the following command:

1
wp db import db.sql

The last step is to make replace all instances of your local URL with the site URL of the installation you migrated to. WP-CLI has you covered, all you need to do is the following:

1
wp search-replace oldurl.com newurl.com

WP-CLI re-serializes any arrays these values may have been in, preserving your database integrity beautifully.

Creating Install Scripts

Using a simple bash script, you can install WordPress with literally just one command. Here’s a simple one I use, explanation ensues!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/bin/bash
# Setup Variables

DBNAME=mydatabase
DBUSER=databaseuser
DBPASS=dnpass
DBHOST=localhost
DBPREFIX=9239jej9md_

URL=http://urlofsite.com
TITLE=SiteTitle
ADMINUSER=danielpataki
ADMINPASS=mypassword
ADMINEMAIL=myeamil

REPOPLUGINS="wordpress-importer theme-check"

# Remove Current Installation
wp db drop --yes;
wp core download;

# Install WordPress
wp core config --dbname=${DBNAME} --dbuser=${DBUSER} --dbpass=${DBPASS} --dbhost=${DBHOST} --dbprefix=${DBPREFIX} --extra-php <<PHP
define( 'WP_DEBUG', true );
PHP

wp db create
wp core install --url=${URL} --title=${TITLE} --admin_user=${ADMINUSER} --admin_password=${ADMINPASS} --admin_email=${ADMINEMAIL}

# Delete Base Plugins
wp plugin delete hello
wp plugin delete akismet

# Install Repo Plugins
wp plugin install ${REPOPLUGINS} --activate

# Misc Cleanup
wp post delete 1
wp plugin delete hello-dolly
wp rewrite structure "/%year%/%monthnum%/%day%/%postname%/"
wp rewrite flush

# Install WPTest.io
curl -OL https://raw.githubusercontent.com/manovotny/wptest/master/wptest.xml
wp import wptest.xml --authors=create
rm wptest.xml

First thing’s first, make sure to set the variables to whatever you need. Notice that my database prefix is not wp_, it’s total mumbo-jumbo. This is a security measure, using non-default values for everything is always a good idea.

Next the db is deleted if it exists. I use this to make sure I have a completely fresh install if I am specifically trying to test what plugins and themes do when first activated.

Then we make sure WordPress is downloaded and extracted and configure the core as needed. Note the --extra-php parameter which allows me to add some custom content to the config file. In this case I am defining the WP_DEBUG constant as true, something which should always be done when developing.

In the next section the database is created and WordPress is installed. Using the value of the REPOPLUGINS variable multiple plugins can be added. You may want to install a lot of testing plugins (like the ones mentioned previously). You can also install plugins from outside of the repository by providing the URL to a zip file.

The cleanup section removes the Hello World post, the Hello Dolly plugin, sets the permalink structure to something nice and regenerates the rewrite rules to make sure they work.

Finally, a test suite of posts and pages is installed, I prefer WPTest.io. This is the only part of the process which takes a while since images need to be downloaded. Without this part the whole process is over in about 10-20 seconds, depending on how many plugins you install. Importing the test data takes about 30-35 seconds.

Code

There is a lot you can do to develop better and faster using some simple coding methods.

Analyzing WordPress Queries

This one is especially useful when building large sites, or sites with very specific functionality. By analyzing all the queries run during a page load you can make coding choices based on real data.

  • Do I need to use a custom loop with WP_Query?
  • Should I write my own SQL or use a WordPress function?
  • Have I written wasteful queries?
  • Are all my queries necessary?

The way to figure this out is to set the SAVEQUERIES constant to true and print out the result at the end of a page. In your wp-config.php:

1
define( 'SAVEQUERIES', true );

You can add the following anywhere, but to get a complete list I recommend putting it just before the closing </body> tag.

1
2
3
4
global $wpdb;
echo "<pre>"
print_r( $wpdb->queries );
echo "</pre>"

The result of this will be a long list of data showing each query separately. This data includes the query itself, its execution time and the function that called it. The sample output below shows how WordPress grabs all the autoloaded options.

1
2
3
[0] =&amp;amp;gt; SELECT option_name, option_value FROM wptest_options WHERE autoload = 'yes'
[1] => 0.00097298622131348
[2] => require('wp-blog-header.php'), require_once('wp-load.php'), require_once('wp-config.php'), require_once('wp-settings.php'), wp_not_installed, is_blog_installed, wp_load_alloptions

Debugging

I hope I don’t have to tell you how important it is to always develop with the WP_DEBUG constant set to true. You can catch PHP warnings, depreciations and other easy-to-miss things which make your code dirty and will likely result in a rejection from WordPress or a marketplace you intend to use. Simply set this constant to true in wp-config.php.

1
define( 'WP_DEBUG', true );

This is fine for PHP but what if you’re trying to help out the good folks at WordPress by fixing some Javascript in the core? Javascript is concatenated automatically making error-catching virtually impossible. The config file has you covered yet again!

1
define( 'CONCATENATE_SCRIPTS', false );

This is a handy tidbit if you see broken admins on your local servers. For some reason admins break for me (and some others) on MAMP. By defining this constant the error disappears!

Another common task is figuring out what hooks where. Rarst’s contribution to WpRecipes is a great little function to have in your tool-belt, it lists all hooked functions, or all functions hooked into a specific tag.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function list_hooked_functions($tag=false){
	global $wp_filter;

	if ( $tag ) {
		$hook[$tag] = $wp_filter[$tag];
		if ( !is_array( $hook[$tag] ) ) {
			trigger_error( "Nothing found for '$tag' hook", E_USER_WARNING );
			return;
		}
	}
	
	else {
		$hook = $wp_filter;
		ksort( $hook );
	}

	echo '<pre>';
	foreach( $hook as $tag => $priority ){
		echo "<br />>>>>>\t<strong>$tag</strong><br />";
		ksort($priority);
		foreach($priority as $priority => $function){
			echo $priority;
			foreach($function as $name => $properties) echo "\t$name<br />";
		}
	}
	
	echo '</pre>';
	
	return;
}

Here’s what the function displays if we instruct it to look at the hooked functions for `wp_head`:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>>>>>> wp_head
1	wp_enqueue_scripts
noindex
2	feed_links
3	feed_links_extra
8	wp_print_styles
9	wp_print_head_scripts
10	rsd_link
wlwmanifest_link
adjacent_posts_rel_link_wp_head
locale_stylesheet
wp_generator
rel_canonical
wp_shortlink_wp_head
wc_products_rss_feed
000000004e22773900007f4d332077c5recent_comments_style
000000004e2276fb00007f4d332077c5addMetaData
twentyfourteen_header_style
_custom_background_cb

Finally, just a quick tip, create snippets for printing things out. I use the following pattern fairly ofter to debug and just check my progress:

1
2
3
echo '<pre>';
print_r( $some_variable );
echo '</pre>';

Most editors support snippets so creating one which allows you to type all that up with 2-3 keystrokes is a huge time saver.

Symlinks

Symbolic links (also symlink or soft link) are a Godsend for developers who work with version control like SVN or git. Your WordPress plugin’s repository doesn’t just contain the plugin. It has a trunk, tags and branches folder and your current version probably resides in the trunk. If you use Github you may have all sorts of other setups.

Due to this you can’t just check out your repository into the wp-content/plugins folder. Let’s presume that you’re not putting your work in the official repositories and you create an SVN repo which mirrors a plugin exactly, it can be pulled into the plugin directory as is.

Even in this case you are faced with issues if you want to use the plugin in multiple sites. You’ll need to update the working copy in each installation when there is a change. Surely there’s a better way? Enter symlinks!

These are “a special type of file that contains a reference to another file or directory in the form of an absolute or relative path and that affects pathname resolution.” – Wikipedia. What this means is that you can store a plugin anywhere (even outside the WordPress environment) and add a symlink to it in the plugins directory of each WordPress installation you need it in. Here’s how:

Let’s presume that I have a central place where I keep my SVN repositories: /Users/danielpataki/svn on Mac or C:\svn on Windows. I also have a test installation of WordPress running, the files for which can be found at /Users/danielpataki/Sites/wordpress/ on my Mac C:\xampp\htdocs\wordpress on Windows. I check out Pile Gallery – a plugin I made – via SVN. The folder which houses the usable plugin is the trunk folder.

Now that I have that on my computer I just need to go into the plugins directory of my WordPress install and create a symbolic link from there, to the trunk directory. Open up the terminal or command prompt and navigate to the plugins folder of your WordPress install and enter the following:

1
2
3
4
5
# For Mac/Linux
ln -s /Users/danielpataki/svn/pile-gallery/trunk pile-gallery

# For Windows
mklink /D pile-gallery C:\svn\pile-gallery\trunk

For a more detailed guide to symlinks take a look at the complete guide to symlinks on How To Geek.

Frameworks and Boilerplates

The main difference between a framework and a boilerplate is that a boilerplate is meant to be modified and shaped to your product, a framework is usually used as-is, included in a project but never modified. I favor boilerplates in WordPress development. I find that products are usually too varied for a framework to be worth it although there are exceptions of course and there most certainly are great frameworks!

WordPress Plugin Boilerplate

The plugin boilerplate main image and logo

The Plugin Boilerplate is something I stumbled on fairly recently and I’ve been using it like a madman ever since. It brings some much needed object oriented perspective and convention over cleverness to plugin development. It forces a certain pattern on you – in a good way.

The download contains a boilerplate plugin which is very modular, built to WordPress code standards and is heavily documented. It standardizes hook calls, makes sure you separate the admin and front-end of your plugin and that you put all your resources and dependencies in the correct place.

Underscores

The underscores main header image and logo

The Underscores website explains what a boilerplate is astutely:

Hi. I’m a starter theme called _s, or underscores, if you like. I’m a theme meant for hacking so don’t use me as a Parent Theme. Instead try turning me into the next, most awesome, WordPress theme out there. That’s what I’m here for. – Underscores

Underscores is actually a fully-functioning theme devoid of any additional features – or styling for that matter. It covers all the bases so you don’t have to. The 404 page is there, the comments page is fully coded, headers, footers, sidebars – the lot.

By using Underscores you can focus on what really matters: creating a unique product and a great experience for your users.

Underscores is built and maintained by Themeshaper, Automattic’s theme division. Since they are in on all the most recent development action of the WordPress core and the new default themes you can be sure that you are in good hands!

Frameworks

As I mentioned, I don’t use frameworks too much, I find they usually bring too much bloat to the table. It all depends on your needs of course. In some of these cases it is difficult to pinpoint if they are boilerplates or frameworks, many are edge cases.

Free Theme Frameworks

Commercial Frameworks

Personally, my biggest issue was always creating options. Once options are in place, creating the functionality is not that difficult. The previously discussed Advanced Custom Fields allows me to do this so I suppose it can act as a kind of framework as well.

Conclusion

Compared to two-three years ago, the number of tools we have at our disposal is amazing. I don’t suggest jumping on each and every bandwagon that comes your way but there are some amazing things being made which can make you a better programmer and a faster programmer – use them!

I’d love to hear some of your favorite plugins, tips, tricks and insights. Please share in the comments below.

(by Daniel Pataki)

Leave a comment