WordPress Development for Beginners: Building Plugins

Interested in creating your own plugin for WordPress from scratch?

Coding your own plugin if you haven’t done it before may feel like you’re venturing into no man’s land, especially if you’re not super confident about your PHP skills. The challenge is knowing how to get started – and being open to making mistakes along the way.

Plugins allow you to add all kinds of functionality to WordPress, from adding a simple contact form to a page to beefing up your security and adding eCommerce capabilities. If you can dream it up, there’s probably a plugin that can do it – or an idea for a plugin you can build yourself.

This is the final post in our five-part series for beginners, teaching you the fundamental concepts of WordPress development so you can take the leap from tinkerer to developer. By the end of the series, you should be able to create your own rudimentary themes and plugins, and flesh them out with your own features.

In this tutorial, you’ll learn how to code your own plugin so you can modify the functionality of your WordPress site, third party plugins and even themes.

Note: For this series, it’s important that you already have a thorough understanding of HTML and CSS as both of these languages are essential building blocks when working with WordPress.

Let’s get started!

Missed a tutorial in our WordPress Development for Beginners series? You can catch up on all five posts here:

Hooks, Actions and Filters

Before we get stuck into making an actual plugin, let’s take a detailed look at hooks, actions and filters. It’s these elements that the whole plugin system is based on and will help you fully understand the behind the scenes of how WordPress actually works.

Let’s have a look at an example.

What if you wanted to create a plugin that added some analytics tracking code to your site? Tracking code is typically placed at the bottom of a webpage right before the closing <body> tag. It must remain in place if the theme is switched and it must work on any WordPress install. So, if you don’t have control over themes directly, how do you do this?

Remember back in WordPress Development for Beginners: Building Themes I mentioned the wp_head() and wp_footer() functions and how you must add these to your theme? Our example above is exactly why these must be present. The wp_footer() function can execute other functions defined by plugins.

Let’s break it all down. Firstly, I wrote a function that simply echoes the tracking code. It isn’t used anywhere, it’s just a function sitting there in my plugin. Then, using the add_action() function, I told WordPress when to execute my function.

Whenever WordPress gets to the wp_header() function it finds all other functions, which are hooked to it using add_action(). It then executes these functions one-by-one, echoing the tracking code as a result.

This is the basis of hooks but we’ll delve into them in a bit more depth later in this tutorial so you can learn about and use their power. Before moving on, I want to mention a slight correction. The wp_footer() function in the footer of themes is not actually a hook, it’s a simple function that contains the hook somewhere within its code. A hook is called like this: do_action('wp_footer'), but this really wasn’t important for the first example, you’ll understand more about this soon!

Terminology

Now that you’ve had a taste of what’s to come, let me properly explain the terminology you’ll read about in this tutorial before we move on.

Hooks are a part of the WordPress Plugin API. Actions and filters are two different types of hooks. Actions allow you to add functionality, you basically define a function that is run whenever the hook is processed by WordPress. A filter works similarly, but instead of adding functionality, it modifies existing functionality. For example, WordPress has a hook which determines the length of the excerpt: 55 words. You can use a filter to modify it to different word count.

All About Actions

Now that we know the basics, let’s look at the add_action() function in more detail to understand it better. The function takes four arguments, which are:

Name of the hook

Name of our hooked function

Priority

Accepted arguments

We’ve already looked at the first two, which are the only required ones. They identify which function should be executed and where it should be run.

The third parameter determines the order of the functions that are executed. This is useful when there are multiple functions tied to the same hook. It’s entirely possible that you want to add multiple tracking codes to a website. Using the priority argument you can control when your function is run.

The accepted arguments simply tells WordPress how many arguments the hooked function accepts. You’ll need to look in the WordPress Codex for each hook to see if you need to add something here. Some functions take more than one argument, in which case you’ll need to specify it here. Take a look at the example below and you’ll see why this is the way it is when creating our own hooks a bit later.

Example Action

WordPress doesn’t just offer actions in themes but also in the backend admin and within the context of specific user actions. The publish_post hook is run whenever a post is published, allowing you do something at that point.

The need for arguments becomes apparent here. If I add a function to this hook, how do I know which post was published and what the details were? Looking at the hook documentation, you can see that the function is passed the post ID and post data as two arguments.

For example, let’s send an email to the post author when a post is published:

All About Filters

As I mentioned earlier, filters work in much the same way but modify data so you’ll mostly be returning within your hooked functions. To add filters we use the add_filter() function, which takes the same arguments as add_action().

Example Filters

A good example to start with is modifying the more string at the end of excerpts which is “[…]” by default. To modify this you could do something like this:

Note that I have not specified the priority and the accepted arguments. This will make the priority 10 and the accepted args 1. I’m not using the argument passed (the default more text) at all, I’m just returning a string.

You could use the same method to embed an advertisement within the first paragraph of your single post content. Take a look:

With a little CSS to float the ad to the right, you could have a standard ad block within your content in a just few seconds.

Defining Hooks

Learning about how hooks are defined and how to create our own can greatly aid in the understanding of the system. Let’s say you’re creating an eCommerce plugin and you’re adding the functionality to list products, you could do something like this:

You’ve essentially hard-coded that you want to show 10 products. What if someone is creating an extension for your work and wants a view where only three products are shown? If you write your code cleverly, you can allow others to modify it. Let’s use a hook to allow developers to tap into our work.

By using the apply_filters() function we’re telling WordPress that we have a hook named “product_count” and we want to run all functions hooked to it. In any other plugin, someone could change this value to three with the following method:

The Basics of Plugin Creation

Now that we know all about hooks we need to know where to put them. Let’s take a step back and look at plugins in general.

Plugins reside in the main plugins directory of your WordPress site, which is usually found in wp-content/plugins. As an example, let’s create a plugin that adds a tweet link below posts.

First, create a folder in your plugins directory and name it tweet-plugin-tutorial. Create a file within this folder and name it tweet-plugin-tutorial.php. Open the file and paste in the following code:

This information is displayed in the backend admin of your site in the plugins section. Once you save the file you should see your new plugin listed; you’ve just created a perfectly functioning plugin. It doesn’t do anything just yet, but it can be activated. Go ahead and do that now.

We’ve actually done 90% of the work. All we need to do now is find a way to add our link to the end of the post content. You can think of this as modifying the post content by appending some text to it. This means we’ll need to use the the_content hook, like before:

This will add a link after our content, which will allow users to tweet and the link will already be filled in the tweet box.

Tweet link in Twenty Sixteen

That’s actually all there is to know about plugin creation. All plugins are a mixture of functions and hooks that determine where these functions are executed. From now on, all you need to focus on is learning various sub-systems like the Options API, Metadata API and so on.

Adding Theme Options to Plugins

There are many ways to add options to your themes. Let’s look at the default way that is contained in the WordPress Codex.

We’ll start off by creating a page in the admin that will hold the form:

The tweetlink_settings_menu() function is hooked to admin_menu. According to the Codex, this is how menu entries must be created. The bulk of the work is done by the add_menu_page() function, which takes a bunch of arguments to create a top level page. The arguments in order are:

Page title – used in the title tag

Menu title – used in the left-hand menu

Capability – sets the minimum capability for visibility

Menu slug – slug used in the URL

Function – the function that controls the output

Icon – An image URL or a dashicons string

Position – Item position within the menu

Here’s what our options page looks like so far on the front-end:

Our new options page

While this may look cool and all, it’s overkill for our small plugin and just clutters the interface. Always consider placing your options pages inside an existing menu. This page would be best placed within the Settings section using the add_options_page() function.

The next step is to let WordPress know about our tweet settings. This consists of using the register_settings() function inside a function hooked to admin_init(). Here’s what the code for this looks like:

All done. The final step is to add a form that uses our options. Use the following code as a template to create your own settings. Don’t forget to use the settings_fields() and do_settings_sections() functions to ensure WordPress saves your data for you.

Further Reading and Study

That concludes our series on WordPress development for beginners. In this article, we learned how to create a basic plugin and hopefully you feel psyched about making your own!

As cliche as it sounds, this is just the start of your journey as a WordPress developer. If you’ve followed along the series since it started five weeks ago, you now having a greater understanding of:

How WordPress core, themes and plugins work,

A basic grasp of PHP, the foundational language of WordPress,

How to put together your own basic theme,

How to add features like widgets and menus to themes, and

How to start building your own plugins

As I mentioned back in part one of this series, I can’t stress enough how important it is not to be discouraged. Everyone has to start somewhere and no one is perfect. You will make mistakes along the way, struggled with understanding concepts, and get frustrated when code doesn’t work like it ought to. Just remember, determination separated the good coders from the bad.

While this is the last post in this series, it doesn’t mean you should stop learning. I would encourage you to review the tutorials in this series, as well as the accompanying further reading that comes with each post, and continue experimenting with PHP and building on the theme and plugin you started building. It’s only through experimentation and persistence that developing for WordPress will get easier and you will graduate from tinkerer to developer.

Did you find this tutorial helpful? Why do you want to learn WordPress development? What do you want to know more about? Let us know in the comments below.

Hello, I'm Daniel and I make things for the web. I'm the CTO at Kinsta and I write for a number of amazing publications like WPMU DEV and Smashing Magazine. In my spare time you'll find me playing board games or planning the next amazing office game like the not-at-all-destructive Megaball.

Get fresh WP updates directly to your inbox.

13 Responses

Nice intro article about how to code a plugin. I think a nice follow up tutorial to this is how to get your plugin into the WordPress Plugin Repo. It’s a confusing process to undertake if you’re not familiar with the tools or methods they require.

This is a great start! Finally someone has enough common sense to stop using the stupid “Hello World” sample in their coding. This is a perfect example of how coding examples should be, something that is useful and knowledgeable at the same time. I would love to see a lot more coding instructions like this as they really do teach you something useful right off the bat!

Many thanks for the simplicity of this article. I’m having an issue getting the final step to work. Should I be creating a new php page called settings-content.php and adding that code? When I try to add it to the tweet-plugin-tutorial.php page I get a 500 error. My apologies as I’m still a php newbie.

A negative feedback output, not about the article’s content, but about the article’s display.

Context: my Firefox browser is set at a default zoom level of 133%, because with my 24 inches monitor, most texts look too small to be read comfortably. I’ve had to set the Windows 7 fonts in 125% DPI, and ask my web browser to embiggen everything. Otherwise, my eyes are dead tired by the end or the day.

Nature of the negative feedback: your blog’s theme has a broken way of scaling to window size, and actually SHRINKS the characters at some point, nullifying the interest of zooming in.
Rather than a thousand words, look at this screenshot comparison I made, with comments:
With Firefox: http://imgur.com/eitzjRz
With Chrome: http://imgur.com/zmtTeyH

I hope you fix it some day, it’s a pain for the eyes otherwise.

Sincerely, the only guy on the internet to whom it happens, given the double 125% DPI and zoom level toying I made :D

Could you do an awesome tutorial on how to use filters? Simple, effective, to the point.
I see you’ve partially already have done so in this article, and with your authority I believe many will benefit :D.