I Made a WordPress Plugin from Scratch: A Noob’s Diary of Success and Failure

I Made a WordPress Plugin from Scratch: A Noob’s Diary of Success and Failure

I really should have titled this post “Oh no, what did I do?!” That would have been a more apt description of what the experience of building a plugin was like.

This isn’t going to be a “how to make a plugin” post. I am definitely not the right person to write such a tutorial. I can tinker with code, sure, but developer I am not. And because of that, I’ve been reluctant to try my hand at creating my own plugin.

Until now, that is. And to be honest with you? It didn’t go all that great. I think I’m going to stick with my day job of writer. But that doesn’t mean you can’t learn from my slightly haphazard experience of trekking through PHP. And it doesn’t mean you can’t learn (or point and laugh, if you’d rather) at my attempts to build something.

So without further ado, won’t you take my hand as I walk you through my daily journal of attempting to create a plugin. It didn’t turn me into a developer, but I certainly learned a thing or two. Enjoy!

A Word About the Format

I was only able to tackle little bits of the coding process each day, so I’ve broken it up accordingly. That might result in a bit of a choppy read, but I figured this was the best way to relay how creating plugins really went down.

Think of it as a peek into my diary minus the angst.

Tools and Tutorials I Used

If you wish to follow along with me in my sordid plugin creation tale, I’ve put together a little list of the tools and tutorials I had on hand to make it possible.

Tools

You don’t actually need very much by way of tools. All I needed were the following:

FTP client: I used Cyberduck, but any would work.

Sublime Text: A handy code editor for Mac that keeps your code neat and tidy and signals you if something’s amiss.

MAMP: A nifty app that allows you to set up a remote server onto which you can install a local version of WordPress for development purposes.

WordPress Code Reference: Great to have on hand in case you need to search for what something is, what it means, or how it works.

Day 1: I Can Do This!

Filled with naive enthusiasm and a positive attitude, I opened up a tutorial and set to work. It’s objective was to add Facebook Open Graph tags to the header of your site. The first step in Daniel’s tutorial requires creating a folder in your WordPress installation in the wp-content/plugins/ directory called my-facebook-tags.

I created a folder on my server, first.

Next, I needed to create a PHP file to go into this folder.

The PHP file goes in the folder, of course.

And from there, I just had to copy and paste some code from the tutorial into this file. I opened it up and slapped that code in there quick.

Going pretty smoothly so far.

Okay, that went surprisingly well. Let’s head over to my dashboard and see if the plugin showed up.

I can’t even begin to describe how exciting this was, guys.

Oh my gosh. It’s totally there. Am I a developer now? Okay, I think I’m getting ahead of myself. But still. As someone who only makes slight tweaks to themes now and then, this is pretty exciting.

I activated the plugin as per Daniel’s instructions. It doesn’t do anything yet, but it’s a live, functioning plugin.

From there, the tutorial goes on to discuss hooks. I’m not going to repeat everything Daniel talks about because that wouldn’t be a good use of our time here. However, I will say that the concept of hooks is surprisingly straightforward. If terms like these have been off-putting to you in the past, don’t let them scare you away.

Day 2: Let’s Make This Plugin Do Something, Shall We?

After reviewing what hooks are and how they work, I embarked on the next part of Daniel’s tutorial, which adds a function to the wp_head hook in each page of your site. When adding a function to this hook, you end up outputting something in the head of the page. Apparently there are action hooks and filter hooks but the tutorial assures I don’t really need to understand all that to finish making the plugin so in the grand tradition of doing the bare minimum, I understood that to complete adding the Facebook Open Graph tag to the header of my site, I needed to add a function to wp_head for calling on these meta tags.

The rest of the code is a simple copy and paste job into that my-facebook-tags.php file created earlier.

The Facebook Open Graph code is pretty straightforward.

As you can see, the my_facebook_tags function has been added to the wp_head hook. This code snippet uses the basic tags outlined by Facebook and defines them using WordPress Template Tags to call up post info like the post title, site name, URL, post description, and post type. The only modification Daniel made is to use the conditional tag is_single() to ensure the meta tags are only added to the header when a single post is displayed.

While there’s no way to see what this looks like on my site, I can hop over to the Open Graph Debugger and see what things look like.

I’m no expert, but that doesn’t look good.

Oh no. Things went horribly, horribly wrong. So, I opened up my website to see what it looks like. Maybe the plugin broke something…

Oh yeah. I definitely broke something.

Oh dear. No one ever wants to see nothing by a white screen when they load up their website.

Before I started to hyperventilate, I backtracked to figure out what the heck I did that made this all go awry. I copied and pasted Daniel’s code into my plugin file again, saved it, and reloaded my site. Things are back to normal, but the Debugger is still showing errors. This time, it says I have multiple OG: URL values. Hmm.

I did a bit a Googling and it looks like I have a plugin in conflict with my current plugin creation. Deactivating my plugin reveals a decent Open Graph output. Further investigating shows that the SEO plugin I have activated is interfering with the My Facebook Tags plugin, since it includes Open Graph info, too.

I deactivated the SEO plugin briefly and tested my new plugin in the Debugger again. This time, I didn’t receive any errors but some weirdness happened with my social share buttons in the site’s header. Since I can’t really deactivate the social buttons (because they’re attached to a lead generation form) I’ve got to call this test “good enough.”

So, that was kind of a mess. And I feel a little dumb for forgetting I had a plugin installed already that adds Facebook Open Graph data. And forgetting to do this whole thing on a test server.

But I did learn a few things from this experiment:

How to create a plugin folder and file.

How to structure a PHP comment.

How to add a function to a hook.

A basic introduction to conditional tags

So, it wasn’t all for naught. But I’m not satisfied with this test. I want to make a plugin that actually works on my site where I don’t have to declare the effort “good enough.”

Day 3: Starting Over

A new day, a new attempt at making a plugin. I’m straight up determined to get something to work here. That starts by eliminating all possible plugin conflicts. I should’ve done this in the first place, but you live, you learn.

I started the day by opening up MAMP and re-installing WordPress on the localhost. I’ve done this before, which is why I’m surprised I didn’t think to do it in the first place. If you need help, here’s a full tutorial. Mostly, I wanted to show what plugin development would look like on a live site but no one in their right mind would do that, so here we are at square one.

Have I mentioned I’m incredibly forgetful? I digress.

Today’s plugin work started with finding a new tutorial to use. Funnily enough, a quick Google revealed another tutorial by Daniel Pataki, this time one he wrote a few years ago at Smashing Magazine. It walks you through all the basics of how to create a plugin. The plugin he creates is one that records how many times a post is viewed then outputs this information to the user. It uses hooks, of course, so after a quick read through I was ready to get started.

I created a folder called popularity_tracker and then a file called popularity_tracker.php within it in my site’s plugins folder. Then I pasted in the usual meta data first thing.

This plugin started off just like my first attempt.

From there, I pasted in code that establishes the function that occurs when a post is viewed. In this case, the goal is to record each time the post is viewed. I didn’t want to tinker with the code much in fear I’d mess something up again, so a simple copy and paste did the trick.

The only bit of customizing I did was on the name of the function. Then I pasted in the action. This one is set to run when wp_head loads, just as with the first plugin I tried to make.

Okay, so now that the plugin is all set up to record each time a post is viewed, the next step is to display this information by retrieving the number of views for a post. There are a lot of variables in this next code snippet that ensure it displays the view count smart. For instance, if there is only one view for a post, it would use the phrasing “1 view” instead of “views,” which would be awkward. This sort of stuff is optional on the functional level, but it’s certainly a nice touch. It’s actually pretty cool to see how you can account for so many different factors in such a small space.

The tutorial goes on to add even more functions to this plugin but I figured this was a good place to stop and test it out.

Success!

Oh my gosh, it activated. Woot!

But I still needed to implement the plugin in my theme. I decided I wanted the view count to appear in the post footer meta right between the comment counter and the Edit link. To do this, I just pasted <?php poptrack_show_views(); ?> into my theme’s content.php file. It’s not the ideal implementation method, but it works, I tells ya. It works!

I had to kind of dig through the file to figure out where to place this bit of code, however. While I’ve certainly modified child themes before, I wasn’t totally sure where this bit of info would look best on output. There was definitely some trial and error involved.

The number of views sort of looks like it belongs there, doesn’t it?

But now every post I create has the lovely view counter on display. Neat!

Day 4: One More Time for Posterity

My first two attempts at creating plugins went okay but were mostly mired by rookie mistakes. Granted, I am a rookie, but I want to do a good job here. So, I sought out one more tutorial to follow today to see if I can do better this time around.

The tutorial I’m using is from Elegant Themes and its objective is to create a plugin that adds a custom post type to a website. Sounds useful. So I got started just as I did the previous days by creating a folder and a PHP file in my site’s plugins folder. I’ve chosen to create a custom post type for book reviews so I’ve called it custom-book-review. The tutorial is for music reviews, but I figured I’d stick with books because—well—writer. The tutorial says that the custom post type we’re going to create includes a featured image, excerpt, rating, and genre type, all of which apply to books, too.

I copied and pasted in the standard plugin header info with appropriate parameters. I activated the plugin to make sure all is well on the parameter front and then proceeded to add the function the tutorial describes.

Now, I’m not well-versed in PHP so when I saw the block of code for this plugin my eyes glazed over a bit.

But after breathing into a bag for a few minutes, I calmed down enough to look at it line by line. I needed to make some modifications to suit the book review custom post type I wanted to make. So I got to work on that first by going through line by line and swapping out any mention of “music review” for “book review.”

That’s probably an unnecessary step in terms of doing the tutorial. I could’ve just as easily copy and pasted the code and been done with it. But I wanted to make a small change that forced me to look at every single line of the code. Again, I don’t know PHP so this was a good way to get a feel for what parameters make up a custom post type.

Other than changing every mention of “music” to “book” I also needed to change the dashicon used that appears in the Dashboard menu for this post type. The tutorial’s code was set to dashicons-format-audio, which obviously wouldn’t make sense for a book review. So I went to the WordPress Developer Dashicon resource and found a nifty little book icon that’ll do the job quite nicely. The code for it is dashicons-book-alt.

The book icon seemed more appropriate.

After all of this tinkering, I popped back into my site’s dashboard and took a look.

It worked! On the first try! Pardon me while I break down into a happy dance. Sorry, I’m just glad third time’s a charm and I’m getting a handle on the structural process of creating a plugin. Also, I’ve officially hit my exclamation mark limit for the rest of this post. Sorry. I’ll try to contain myself from this point forward.

The next part of the tutorial adds a taxonomy called “Genre” to the custom post type. This is relevant to books, so I went ahead and added it. It’s a new function that helps to extend what the plugin is capable of.

I saved my progress here and tested the plugin again. All looks good, and I now have a custom taxonomy called “Genres” for categorizing my book reviews.

And here’s the Genre taxonomy in action.

The final coding task in the tutorial is to add a function that automatically creates a page called “Book Reviews” when the plugin is activated. I added the function and code to initiate the function.

The last step is to create a sample book review. I’m reading The Shining right now, so it seemed an appropriate choice.

A quick sample post.

I input some content, selected a genre, and added a featured image. I threw in a rating and price, too.

The output looks nice and is totally functional. But I would love it if I could add a template to this post type, so I don’t have to manually create those rating and price sections and so they could be automatically styled in some way. For this, I hopped over to a different tutorial to finish things up but the task of creating a template is a bit beyond the scope of my little experience here. Hey, maybe next time?

I published the post but it didn’t appear on the front-end. To fix this, I deactivated and reactivated my new plugin. Doing this added a “Book Reviews” page to my site that outputs any reviews I’ve written. None of this shows up on the homepage so I needed to add the Book Reviews page to my primary navigation.

Upon reactivation, the “Book Review” page appeared.

It showed up just fine, but my review of The Shining is nowhere to be found. What happened? After scratching my head over it for what felt like days, I finally figured out that I needed to change the permalinks structure to post-name on my test site. This is, of course, something I always do when setting up a new site but it slipped my mind when configuring the local site. Still, it would’ve been nice if this detail were mentioned in the tutorial, especially since post won’t output into the right place without this required settings change.

It ain’t pretty, but it worked.

In any case, with the permalinks modified, the book review showed up exactly as it should on the newly auto-created “Book Review” page. Cool!

A Recap of Four Days of Plugin Dev Dabbling

Everything is surprisingly logical when creating a plugin. That probably sounds silly to seasoned developers but for a newbie like me, I was a bit shocked. Of course, I’ve created widgets before, created simple sites in HTML, and created theme modifications using child themes. But for some reason, the task of creating a new plugin has been something I’ve avoided.

I guess I feared it would be super complicated. I’d yet to truly cross the PHP hurdle. And while completing a couple of tutorials hardly a developer makes, it’s still a start and should go to show that if this writer can do it, even brand new WordPress users can do it. More importantly, it’s definitely not something to fear and is a skill that can come in quite handy when putting together future sites.

What I’d Do Differently Next Time…

While I’m overall pleased with how this experiment went, there are several things I’d do differently next time. Here’s my basic rundown of how I think all of my future plugin development adventures should go:

Take a class in PHP: Sure, I could copy and paste code here and tinker with it but I don’t have a solid understanding of how it all works. And that’s something I just don’t think you can get by without knowing. So, if I were to try to build a plugin again, I’d first spend some time learning the ins and outs of PHP. I’d need to at least know the basics so I’m not having to Google terms I don’t know every five seconds.

Do everything on a local server: I figured this out mid-way through this experiment, so it’s something I’d do before starting any plugin development project in the future.

Make a plan: Winging it is definitely not an option. I’d make a detailed list of everything I want a plugin to do before even opening the text editor.

Have resources open and ready: Anything that might need to be used as a reference material (I’m looking at you WordPress Developer Resources) would be open in a tab and ready to go.

Now it’s your turn. Did I leave anything out of my list? Also, if you’ve held off on plugin development before, are you convinced you should try? Or will you stick with out-of-the-box solutions? Either way, I’d love to hear your thoughts in the comments below.

Brenda Barron is a freelance writer from Southern California. She specializes in WordPress, tech, business and founded WP Theme Roundups. When not writing all the things, she's spending time with her family.

And one big lesson:
Never use legacy PHP to “just run”, always hook your PHP code to a WordPress action or filter, this way a hacker first needs to bypass WordPress’ security before going through your code.

Hope this helps :D

I could give you a link to a very bad, and public, example of code that can be hacked easily. But I won’t :D Sorry <3. D:

A really nice article by you. You’re going good enough. You made me remember my days of working on WordPress plugins :D . I also created a WordPress plugin and but lost interest in WordPress later and stoped maintaining it and then later switched to Core PHP because i wanted to enhance my PHP Skills.