How to Create Your Very First WordPress Plugin

If you want more control and flexibility over your WordPress site and are ready to get your hands dirty with some code, one of the first things you’ll probably want to know is how to create a WordPress plugin.

I remember being there just four years ago and how frustrating it was to find a ground zero, geek proof tutorial that showed me the very basic anatomy of a WordPress plugin.

So I’ve decided to create this one, and you can apply these steps even if you know nothing about programming and are just getting started. While you might never become a master programmer, you can learn to make small corrections which can be helpful if you don’t have the budget to hire a webmaster.

Let’s start with a few disclaimers…

Five Official “Cover my Butt” Statements

  • At the time of this writing, the most up to date WordPress version is  3.4.1 It might be different by the time you read this .
  • I’m assuming you already know how to install a basic WordPress site, if you’re unsure please see their www.wordpress.org
  • To any experienced programmers reading, I’m aware that there are many other important things the reader will need to know in order to create live plugins. This is strictly for the people who are starting from ground zero and need to get some traction.
  • Please do NOT attempt this on one of your live WordPress sites. Rather, set up a subdomain and a brand new WordPress installation to use for plugin testing purposes only.

Step #1: Prepare Your WordPress Testing Site

First, I’m including an example source code to follow along with this tutorial. It will be good practice to copy this once we get around the coding steps:

****************************************

<?php
/*/
Plugin Name: Basic
Plugin URI: www.sethczerepak.com
Description: Demonstrates how a WP plugin works
Version: 101
Author: Seth Czerepak
Author URI: www.sethczerepak.com
/*/
function basic_content_replace ($text){
$text = str_replace(‘Old’,'New’,$text)
return $text;
}
add_filter(‘the_content’,'basic_content_replace’);
add_filter(‘the_title’,'basic_content_replace’);

********************************************

Next, go to your WordPress test site and create a post with the Title:

Old Title

Then, fill in the post content with:

Old content.

Don’t add any punctuation and keep the title cases exactly as they are above. When you’re finished, the front page of your WordPress site should display the basic “Old Title,” post like so:

Our goal will be to create a very basic WordPress plugin that changes the title text from “Old Title” to “New Title” and the content body from “Old content” to “New content.”

Step #2: Get Your Plugin Info to Displayed in the WordPress Dashboard

Plugins are built out of files or groups of files which are stored in the WordPress “plugins” folder. *

*In programming, folders are also called “directories.”

Think of these files like the files on your computer that you open and read. Only with WordPress plugins, WordPress opens the files, reads the commands in them and then performs the commands that require action from the computer.

So the first thing you’ll need is to create a file for your plugin and put it in a place where WordPress will recognize it as an actual plugin. This is the “plugins” directory which can be found inside the “wp-content” directory:

Once you open the “plugins” folder, create a new file and name it “basic.php.” The letters “php” at the end tells you what kind of file you’re creating, just like the file extension “doc” in word tells you that the file is a Word file.  This is very important because WordPress doesn’t speak English. It speaks PHP, which is a programming language.

So you need to give the file a .php extension like in the graphic below*:

*In some more advanced cases, you can get away with other extensions such as html, but it’s best to just stick with php extensions for now.

Next, at the very top of your file, you’ll need to tell the computer that you’re about to talk to it in PHP code. You do that by including this at the top of your “basic.php” file:

<?php

You might remember the Star Trek shows where the characters would say:

“Computer!”

And then give the computer a command in English. That won’t work with WordPress, you have to speak PHP. The “<?php” command is basically saying “hey computer, let’s talk some PHP.”

NOTE: This command must have no lines or spaces ahead of it and must be on a line by itself in order to avoid “header already sent” errors (trust me, they’re annoying).

On the next line, we’re going to do what I call “hitting the pause button” on the php language. We do this by adding the characters:

/*/

So now your “basic.php” file should look like this:

<?php

/*/

Programmers call the above action “commenting out,” “escaping PHP” and a bunch of other geeky terms. I just think of it as hitting the pause button on your PHP. In other words, you’re saying to computer:

“Hang on computer, let’s put the PHP on pause while I make a few notes about this script”

In many cases, the notes inserted would only be visible to the programmer. But in a moment I’ll show you where these notes will show up in WordPress why they’re important. So once you’ve paused the programming language, you’ll need to include some required details about your WordPress plugin.

I’ve included a sample below from the source code for this tutorial:

/*/

Plugin Name: Basic

Plugin URI: www.sethczerepak.com

Description: Demonstrates how a WP plugin works

Version: 101

Author: Seth Czerepak

Author URI: www.sethczerepak.com

/*/

Notice that I used “URI” instead of URL. That’s important for some geeky WordPress reasons we won’t get into right now. I’ve also called the version “101.” If I were to go back and add something new to the plugin, I’d update that to 102 or possibly 101.1 depending on the logic I was using for naming my upgrade versions.

Notice also that I “hit the pause button” again to make sure that the computer understands that we’re done taking notes and ready to talk PHP again. If I’d not done this, the computer would have tried to read the block of code between the “/*/” characters in PHP and you’d get all kinds of cryptic errors when using the plugin.

Next, you might want to replace my name with yours, and replace my site with either yours or “example.com” so you can feel all proud and stuff when your plugin shows up in the dashboard like this:

You’ll also notice that the plugin needs to be activated, so go ahead and do that while you’re in there beaming with pride about having your name in the WordPress plugin dashboard.

Now that you’ve been officially published as a WordPress plugin creator, it’s time to make your plugin actually do something…

NOTE: It’s very important that you create this file in a text editor like Notepad. Word processing programs make subtle changes to characters like ‘ and , and “ which are not understood in the PHP language.

Step #3: Get Your Plugin to Send Commands to WordPress

After you’ve included your plugin information, you need to add some php commands. In php, you do this using “functions.” Simply put, functions do things to data. A function consists of a name and a set of parentheses, with the data to be manipulated inside the parentheses. For example purposes, I’m going to use some everyday actions so you can get the idea of how functions work:

run();

That function was named “name” but I could have named it “walk”:

walk();

Or “sit”:

sit();

Notice that there’s nothing in the parentheses, but that’s normally where the data would go. Remember, a function does something to data, and we’ll talk how that happens in a moment. But it’s important to know that the data which the function is manipulating goes in the parentheses like so:

run($legs);

…I’m telling “$legs” to run.

walk($shoes);

…I’m telling “$shoes” to walk.

sit($dog);

…I’m telling the dog to sit.

Now, you might notice that there’s a dollar sign in front of the data.

That dollar sign is identifying that data as a “variable.” In PHP, a variable is something you use to “store data,” but I like to think of it as something that represents something else. In essence, you can use variables to translate from text to PHP and back again.

For example, if I wanted the variable “$dog” to represent my dog Rocky, I’d tell the computer that $dog equaled Rocky, like this:

$dog = “Rocky”;

NOTE: When you “store” plain text in a variable, you need to put the text in quotes. You also need to end the entire line with a semicolon (;) as you’ll see in the source code file.

Or I could have named the dog “Max” like this:

$dog = “Max”;

That’s a basic approach to defining variables.

As for functions, in php, you have two types. You have functions you create within your program applications (plugins) and you have those which are “native” to the php language or to WordPress. In your “Basic” plugin, we’ll create a function by including the word “function” just before the function name and the data which the function will be working on, like so:

function basic_content_replace ($text)

Now, php knows that “basic_content_replace” is a function which will do something to a variable called “$text”. Notice that the function uses underscores in between the letters of the name. This is because function names cannot include spaces, hyphens and quite a few other characters which you’ll learn about in later coding adventures.

The only problem now is that the function has no command attached to it, and that’s your next job. The commands which a function perform are defined within the “{}” brackets, like so…

function basic_content_replace ($text) {

$text = str_replace(‘Old’,'New’,$text)

return $text;

}

The two lines of code you see between the {} brackets tell php what the function is actually doing to the “$text” variable.

The first line…

$text = str_replace(‘Old’,'New’,$text)

…is telling the computer what “$text” actually stands for, only this time we’re including another function called “str_replace” to help define the text variable. The “str_replace” function simply replaces a string of data. Then the data in parentheses tells you exactly what data gets replaced and what data will replace it.

Remember your blog post title “Old Title?”

See if you can figure out what the “str_replace_function” will be doing to the word “Old:”

$text = str_replace(‘Old’,'New’,$text)

In this case, the () characters are surrounding three pieces of data. “Old,” “New” and “$text.”

In the first set of italics, we’re including that data which we want to replace (‘Old’).

In the second set of italics, we’re including the new data which will replace the old data (‘New’).

Finally, we’re including our $text variable “$text” which will define the new piece of data which is produced by “str_replace.”

Then, the very next line of code completes the “basic_text_replace” function by telling it the result we want the function to return:

return $text;

So if we wanted to translate this entire function:

function basic_content_replace ($text) {

$text = str_replace(‘Old’,'New’,$text);

return $text;

}

We would be telling the computer:

“Computer! When we run this “basic_text_replace” function, we’ll replace the word ‘Old’ with the word ‘New’ and the result will equal the $text variable, so go ahead and return the result to me when you’re done.”

The computer now knows that “basic_content_replace” means it should follow the commands represented above to manipulate your $text data. “So your entire new “basic_text_replace” function would look like this:

function basic_content_replace ($text) {

$text = str_replace(‘Old’,'New’,$text)

return $text;

}

And we’ve just built a function.

Now all we need to do is program the function to run by itself.

That’s right, building a function doesn’t cause it to do anything. You’re simply telling php what you want the function do when you do decide to actually run it.

To make that happen in our “Basic” plugin, we’re going to use the “add_filter,” function…a function which is already native to WordPress and PHP. For example, look at the code below the basic function in your “basic.php” file:

add_filter(‘the_content’,'basic_content_replace’);

add_filter(‘the_title’,'basic_content_replace’);

In both of the above uses of the “add_filter” function, you’re adding a filter to the first piece of data within the () characters. Then, the second piece of data “basic_content_replace,” is the name of the function we just created.

And what does that function do?

Right, it replaces the word “Old” with the word “New.”

So in the first “add_filter”, you’re adding the filter to  a piece of data called “the_content” and in the second “add_filter” you’re adding a filter to a piece of data called “the_title.” Remember the simple blog post you created:

Old Title

Old content.

The commands within your “Basic” plugin are now telling WordPress to pass “the_content” and “the_title” through a filter, and that filter is the function which replaces the word “Old” with the word “New.”

So here’s what will come out on the other side of those two filters:

How did WordPress know to do this?

WordPress has a predetermined set of data which represents the title of a blog post (the_title) and one which represents the content of a blog post (the_content). So by adding the above filters, you’re telling WordPress:

“WordPress! Filter the titles and the content of your posts and wherever the world ‘Old’’ occurs, replaces it with the word ‘New.”

And you’ve just built a WordPress plugin.

Three Things to Experiment With On Your Own

1.       Create a second blog post and edit the “Basic” plugin to replace a different word this time.
2.       Edit the plug in to replace two words instead of just one
3.       Add a second “str_replace” into your “basic_text_replace” function and replace two words using two separate functions

This example might not appear very useful on a real WordPress site, but it will help you get comfortable with how to perform some basic PHP commands and use them to make changes to WordPress.

I’ll likely be posting more tutorials on this, but if anyone has questions please leave a comment, I do check them every day.

Best,

Seth C

Comments (17)

  1. Thank you for the tutorial. I do not know how much the ‘seasoned developers’ would appreciate this but for a non developer or someone new to programming this makes a lot of sense and I can see the hard work put it.

    Well done Seth!

    Seth what is your twitter handle?

  2. One error though.

    At some places the code reads “$text = str_replace(‘Old’,’New’,$text’)” and at others it is “$text = str_replace(‘Old’,’New’,$text);” and non programmers will flip for sure!

    Another question I had was that it seems that most of the WordPress plugin files with the php extension have the starting php tag () is missing. Can you please explain why?

    • Good catch my man. For anyone reading, the single quote after the $text variable does not belong there.For the starting tag () question, I’m not sure what you’re asking. Can you copy a sample of what you’re talking about?

      • Ok I will try again.

        For the plugin file there is opening code for PHP which is “”. I had read that a PHP file should have the starting tag .

        Therefore according to me the code in the file should have been

        while it is

        <?php
        /*/
        Plugin Name: Basic
        Plugin URI: http://www.sethczerepak.com
        Description: Demonstrates how a WP plugin works
        Version: 101
        Author: Seth Czerepak
        Author URI: http://www.sethczerepak.com
        /*/
        function basic_content_replace ($text){
        $text = str_replace(‘Old’,'New’,$text)
        return $text;
        }
        add_filter(‘the_content’,'basic_content_replace’);
        add_filter(‘the_title’,'basic_content_replace’);

        I hope this makes more sense.

        Thank you for the patience.

  3. The editor on this comment form appears to be editing out some html characters. There are special characters in html which can be written in a plain text format as well. Sometimes the format is automatically changed by the editor you’re using or the device you’re reading on. For example, the left arrow is sometimes written as the & sign followed by “rarr.” PHP files should open with that left arrow, followed by a question mark and the letters “php.” If you’re not seeing that it could be that the editor or reader you’re using is translating the special characters or removing them altogether.

  4. I put the code in exactly as it was on top, after getting errors doing it myself, and it doesn’t work at all. It actually keeps the entire page from loading, and dreamweaver also pops up error messages on the code as well.

  5. hi,
    your code works perfectly,your tutorial is without a doubt the best on the net,
    but i have a question that deals with ‘actions’ rather than ‘filters.’

    ok, so lets say i wanted to do exactly what you’ve mentioned here, but on – publish_post.
    the problem is , it simple does not work if i try to use it with the action trigger.

    here is my code, and I’d appreciate any help that you can offer, since all the documentation on publish_post is very sketchy.

    my plugin file carries this code(i didn’t include the stuff about plugin name etc here , but yeah i have got that covered) –

    ok, its not exactly what you have been explaining, but i read your tutorial and then i decided to move on to ‘actions’ and this was my first attempt.

    something interesting — if i use ‘init’ instead of ‘publish_post’ , the whole thing works perfect.

    thanks,
    these ones and those ones…

    • sorry, but my code doesnt show up in the comment, i guess the comment system is blocking code.

      well anyways – all im doing is combining the action publish_post with a function that echoes a line of text. it doesnt work.

  6. I use php but knew nothing about wordpress and plugins so far.
    Your short tutorial was for me as useful as ‘The C Programming Language’ / Kernighan and Ritchie above 20 years ago !
    I viewed more than 10 websites and just you explained it in clear and simple way.
    Thank you very much, best regards
    Jacek

    PS
    Can you look at Step#3:
    run();
    That function was named ‘name’ == That function was named ‘run’

Participate