Lessons Learned From Maintaining a WordPress Plug-In

Advertisement

Recently I released a WordPress plugin for Google Analytics that adds a tracking code and dozens of various pieces of meta data to blogs. Since the release of version 4, I’ve updated it 6 times, to the point where it’s now at version 4.0.6. In this article I would like to share with you my experiences in maintaining this and other WordPress plug-ins and common good practices that I’ve distilled from that work.

The updates that I released had a couple of purposes, ranging from bug fixes to new features and fixes in documentation. While all of these are nice to talk about, the bug fixes are the ones you’ll learn the most from, so let’s start by going through these.

Website and Account Configuration

Almost as soon as I released the plug-in, people who updated were telling me that it worked wonderfully, and others were telling me that it didn’t work for them. Turns out I hadn’t tested the plug-in with a Google Analytics account that has only one website registered; I expected the websites to be an array. Fixing this bug was easy, but determining that this was the problem took a while.

Being able to log into a few hosts of people who gave me access to their back end and FTP so that I could test my fix proved invaluable. This enabled me to release 4.0.1 within an hour of the 4.0 release.

Another mistake I made was forcing everyone to reconfigure the plug-in. I assumed it wouldn’t be too much work for people, and it wanted to be sure the settings were clean, but it turns out quite a few people didn’t want to reconfigure. With 4.0.2, I came up with a way to inherit some of the settings and clean up the mess I made, and in 4.0.4 I made a change that I will add to all of my plug-ins:

1
Large view2

Good practice #1: Don’t assume anything about people’s websites and external accounts.

Versioning Option Arrays

As a seasoned WordPress developer, I store all of the options for my plug-in in one option in the database, which is basically a big array. Why I hadn’t ever added a version number to these options is a mystery to me. Doing so makes it possible to do some very cool things: I can now add new features and set a default for these new features as soon as a user upgrades; I can show the user different messages based on the version they had before they upgraded; and more.

Good practice #2: Add a version number to your option arrays.

I’m still not using the WordPress option API stuff (check out this post3 by Ozh to learn all about it), which I probably should, but for now I find it easier to handle the saving and validation of options myself.

Don’t Release Too Soon

If you’ve got a bug that’s bugging a lot of your plug-in’s users, you’ll probably want to release a bug fix as soon as possible. I know I do. This caused an issue with my 4.0.3 release, though, because I didn’t properly test some of the code I introduced, causing me to have to release 4.0.4 just two hours later to fix a stupid mistake I’d made with booleans. Nothing is as painful as 500 people downloading a version of your plug-in that doesn’t actually work.

Good practice #3: Test, test, test before you release, even when you’re in a hurry.

Know Which Version People Are On

Over the past two weeks, I’ve been helping several people who said they were on the latest version of my plug-in but in fact were not. To remedy this, I’ve started outputting the version number in the comment that the plug-in outputs before the tracking code. Problem is, if people run a plug-in such as W3 Total Cache4 (which everyone should use by the way) or anything else that minifies their output, that comment will get lost.

There’s a solution for that, too: I’d already wrapped the script in <CDATA> tags, to help with Strict XHTML validation. Minifying will not occur within those CDATA tags, so I moved my “branding” comment to the CDATA section, and I can now always see, first, that my plug-in is active and, secondly, which version of the plug-in they’re using.

Good practice #4: Make sure you can see which version of your plug-in people are running.

URLs in WordPress

One of these things that can generate pretty awful bugs is a blog’s URL. Whether it’s due to people running their entire blog on https or “simply” running their blog in a sub-directory, it can cause headaches. It did for me in version 4.0.2 when I added URL sanitization: all relative URLs in posts and text widgets starting with a / were made absolute, in order to properly track these URLs. Tiny issue: I forgot about blogs in sub-directories, so a tiny portion of people would end up with links that used to go to /home but that now went to http://example.com/blog/home. I know, that was stupid; but that’s why I’m telling you: so you don’t make the same mistake.

Good practice #5: Make sure all URLs you use will work in all circumstances, whether WordPress is in a sub-directory, on a subdomain or just in the root.

Writing to the Root Directory

Somewhat related to the last issue, although I encountered this while developing my WordPress SEO plug-in, not the Google Analytics plug-in: if you write a file — say, an XML site map file — to the root of a website, and the website is actually a WordPress multi-site installation, things can go horribly wrong.

Check out the following scenario:

  1. User 1 writes and publishes a post on example.com/blog-1/.
  2. An updated XML site map for example.com/blog-1/ is generated, and example.com/sitemap.xml is updated.
  3. User 2 writes and publishes a post on example.com/blog-2/.
  4. An updated XML site map for example.com/blog-2/ is generated and example.com/sitemap.xml is overwritten.

See what just happened? The XML site map now contains only the posts from blog-2… This is exactly why the wp-content directory was created. There’s hardly ever a need to put a file in the root of an installation, and by not doing so, you make it far easier to run your plug-in in a multi-site/WordPress MU environment.

Good practice #6: If you’re generating files, generate them in the wp-content directory of your blog. Do not write files to the root directory unless you absolutely, positively have to. And if you do have to do it, make sure it doesn’t go wrong when your plug-in is active on multiple blogs in the same multi-site instance.

Rethink Your Filters

On the day that I released 4.0, I got quite a few feature requests, ranging from very simple to somewhat more complex. One that came in quite rapidly and caught my eye happened to be quite simple: the user wanted the same outbound link that in my plug-in tracks the content of an article to track in text widgets. Because I don’t use text widgets that much, it never occurred to me to do this. It was a valuable lesson, though:

feature request5
Large view6

Good practice #7: If you’re filtering content, try to filter it in as many places as you can, so that users get consistent results all over WordPress.

Never Assume

It’s true for everything, I guess, but especially true for WordPress developers: never assume. The seven best practices above mostly boil down to abandoning all assumptions about states, URLs and locations, and even about people knowing which version of a plug-in they’re using. Take all these matters into your own hands; your plug-in will be the better for it!

(al)

Footnotes

  1. 1 http://www.smashingmagazine.com/wp-content/uploads/2010/07/re-authenticate.png
  2. 2 http://www.smashingmagazine.com/wp-content/uploads/2010/07/re-authenticate.png
  3. 3 http://planetozh.com/blog/2009/05/handling-plugins-options-in-wordpress-28-with-register_setting/
  4. 4 http://wordpress.org/extend/plugins/w3-total-cache/
  5. 5 http://www.smashingmagazine.com/wp-content/uploads/2010/07/conversation.png
  6. 6 http://www.smashingmagazine.com/wp-content/uploads/2010/07/conversation.png

↑ Back to topShare on Twitter

Joost is a seasoned WordPress developer and SEO, who has developed several very popular WordPress plugins. You can hire Joost for custom plugin development, or bug him about one of his plugins not working through his blog yoast.com.

Advertising
  1. 1

    Too many times (especially since the release of 3.0) sites developed with wordpress either break or just go wrong because a plugin is no longer compatible. It is at the point that if it is simple enough, just hardcode it. I’ve found myself pulling plugins out, just to find that to get the result I wanted it was easier to code it myself.

    Plugins are great for less advanced users or simply the end user, but keep in mind that these people are not as savvy as you or I so it needs to be simple, easy to use and of course, updated on a regular basis.

    Nobody wants to be the developer who released a great plugin only to fail at keeping it updated and working. Then you’re the developer who caused working websites to throw errors.

    Great post!

    0
  2. 2

    Joost, excellent article!

    Ironically, I just installed your plugin for the first time last night, how future-proof is the plugin now that you’ve made all these updates/fixes?

    1
  3. 5

    Brilliant article! I’ve always wondered what it would be like to release a plugin. There are some valuble lessons to be learned here. Thanks for the advice.

    0
  4. 6

    Thanks, Joost,

    I’ve been looking at dipping my toe into the WordPress plugin and theme arena. This post is right on time! I’m gonna make sure to bookmark this one. I also get your newsletter so keep it coming.

    0
  5. 7

    Hey thanks for a great and interesting post!
    And allso for pointing out some nice plugins! =D

    0
  6. 8

    Great article Joost. If I’d known the first 2 or 3 of these, my last plugin would have been better and less painful to maintain.

    0
  7. 9

    Great article Joost. I’ve certainly been caught out by having WordPress installed in a subdirectory and plugins breaking on several occasions. Like the useful tip regarding versioning – will be sure to include that next time I develop a plugin. Thanks.

    0
  8. 10

    There’s been talk of “core” plugins that should follow strict guidelines. I wonder if/when WP will roll this out.
    Also, if you need admin icon for your plugins, email me-I design the default admin icons you see when you log into wordpress.

    0
    • 11

      The experiment that “core” plugins are has taken longer to come to fruition than we hoped.

      However I hope to have one or two of the first candidate core plugins out soon.

      0
  9. 12

    Thank you SO MUCH for pointing out Good Practice #6. :) More plugin devs will need to take this into consideration.

    0
  10. 13

    Interesting article, an almost «live» report from the inside of plug-in development. Thank you very much, Joost.

    0
  11. 14

    Yah, I remember the last time I hardcoded some sitemap plugin. Chosen the simplest one I could find because I was too lazy to analyze thousands lines of code (none of selected plugins did what I wanted them to).

    Thanks for #2 and 6!

    0
  12. 15

    Why are all web-related sites always singing praises of WordPress. Quite honestly I hate WordPress. It’s slow and the code doesn’t follow any particular model. Just a mash-up of “Oh-Yeah!, That’s a great feature. Let’s tack it on and not follow a programming model. Hooray!”.

    I know this article doesn’t exactly “sing praises” and focuses more on the plug-in, regardless, I’m pissed of. The reason why I’m making this comment is so the web-community as a whole can help to extinguish the popularity of WordPress and we wouldn’t need these articles.

    I don’t see how a piece of junk software (Yes junk! Administrative interface is trash, its slow, and full of useless options that a site might not need) can become so popular. Is it because it’s easy to use piece of software or is it because the web-developing community just doesn’t want to invest in building their own CMS that does the job and gets it right. No useless features!

    I truly am all for open-source technologies. It just bothers me that an advance piece of software, such as Drupal, could and is overlooked.

    Another thing is, look at the plethora of useless sites that exist on the web because of WordPress. I am able to download a free theme or buy a high-quality one and start a site that takes up a quality domain and is filling the web with useless jargon.

    -1
    • 16

      I have to disagree with your comment. In fact, it really doesn’t seem related to the post, rather an attempt to get people to hate on WordPress. You don’t like WordPress, that’s fine. I don’t like Drupal, but it doesn’t mean I go around posting on Drupal plugin articles complaining. Time and a place for everything right?

      0
    • 18

      why not create all those plug-ins first than talk!

      0
    • 19

      Anonymous, you ask “Is it because it’s easy to use piece of software or is it because the web-developing community just doesn’t want to invest in building their own CMS that does the job and gets it right.”

      The only thing that “gets it right” every time is a custom-coded CMS for each specific project, but that brings with it another problem: countless hours of extra development for the original creator and even more hours of pure and utter frustration for those who end up maintaining the end result.

      There is no single panacea for any and all website needs, and using a custom-built solution will make development costs for most sites skyrocket – up to the point where many customers simply can’t afford it.

      WordPress might be far from perfect, but it’s easy to deploy, easy to maintain, and flexible enough to support a wide range of different kinds of websites. Sure, it’s slow, but caching plugins can ameliorate that. Sure, it lacks functionality in some areas, but plugins can provide most of that. Sure, it’s bloated, but disk space is cheap anyway.

      Yes, Drupal is probably better. But it also significantly increases development time and thus customer costs. And even then, the end result is harder to use for most website owners.

      It’s easily possible to create a unique, professional-looking site with WordPress in a single day, and the average computer-illiterate person will be able to use and maintain it with next to no training. All without spending a single dime. For a vast majority of website owners, that’s absolutely great.

      0
  13. 20

    Insolite du Geek

    July 30, 2010 11:16 pm

    Interesting article, but I would have appreciated a few lines of PHP code to explain that.

    0
  14. 21

    Thanks for the quick information. I regularly read your blog and it is quite helpful for me to keep updates with latest trends.

    0
  15. 22

    I’m writing my first WP plugin and never would I’ve thought to use storing the version. This will help me a great deal working out the bugs. Thank you!

    0
  16. 23

    Tip #8: Include plugin specific CSS/JS *only* on pages that need them. Also, give the option to allow page specific includes for these types of files. Don’t force new code to show up on every page/post even if those pages/posts don’t need these files.

    0
    • 24

      This is hard to do when your plugin is activated by a shortcode and can be shown on any page. Theoretically, you could do this if your JS/CSS could be loaded in the footer, a la wp_footer(), but if you use wp_enqueue_script(), I’m not sure that is even an option since it would have to be called after the_content in order to know whether it is needed or not.

      One workaround might be to update an option that records which pages/posts the shortcode is used on, but that seems to be a bit of a hack and would always cause a failure the first time the post was loaded (until it was added to the shortcode queue).

      If there is a good way of doing this, I wish someone would update the Codex and drop some knowledge on us.

      0
      • 25

        Byron, I understand the plugin architecture isn’t as efficient or documented as it should be but it’s totally possible for plugin authors to only include these files *only* on pages which require them. The most notorious but widely used plugin that suffers this problem is NextGEN photo gallery. I use this one constantly but am annoyed that I can’t turn off the scripts and stylesheets on pages which don’t use the plugin!

        While shortcode includes are great for many things, plugin authors really should embrace wp_enqueue_script() to include their scripts! It’s much better for users and allows for these scripts and styles to be turned off using the functions.php! If you use shortcode, it’s much harder to turn these inclusions off.

        0
  17. 26

    I was pleasantly surprised to find the author of one of my most used WP plugins, penning an article on my favorite site (Smashing) for web information.

    Great tips and great read, Joost. Much thanks.

    0
  18. 27

    Great tips! :D

    1) It’s hard to pretend how other ppl config their environment when we’re distributing free software under GPL. It’s their duty to help us… reporting bugs, with bugfix, offering code to enhance the software, etc. We can’t just give everything ready, even more when all our needs are already satisfied.

    2) I add version to my configs :) I don’t relember exactally how it’s done because I developed a framework and it deals with everything for me, but it always check if version is different and when it is it calls a function where I can make proper changes.

    4) Are u sure about that? I always thougth it was useless. It’s boring to update version in many places everytime a new version is done, and if I fogot it will break all its purpose. There’s a way to get plugin version from WP, but I still don’t use it.

    Again, it’s our users responsibility to keep updated, WP already has features to inform about it. If they wanna remain in old versions, it’s better to report the reason and help us satisfy them in latest version then stay stuck in the outdated world.

    5) Always use site_url() and children and u’ll be good.

    WordPress is a CMS, and nothing is static in it. We’re lucky it almost always offers functions to deal with dynamic resources, so always use its API functions to refer to its resources, instead of assuming every site puts its files in the same place you do.

    6) content_url() or some function like that, and for upload folder use upload_dir(), or some name like that :P

    7) Better yet, leave your filter function publicly available! That way they can add ur filter anywhere they want, even in custom or other plugins hooks.

    And add to that: add hooks everywhere you want, and make everything possible to allow your users to customize your plugin and filter your content without needing to edit your files!

    0
  19. 28

    Thanks for the useful Resource :)

    0
  20. 29

    Oliver Gehrmann

    August 2, 2010 2:37 pm

    Funny that I installed your plug-in today and now I stumble upon this post. I’m curious to see the plug-in in action and I’m looking forward to future insights. This was very helpful and entertaining at the same time. :)

    0
  21. 30

    Mark @ Alchemy United

    August 4, 2010 11:23 am

    Thanks! As someone who has is just starting to dip my toes into plug-ins this was great. Is there a community anywhere just for WP plug-in developers to share ideas, help each other, etc? I ask because I’ve posted to the WP forums a couple of times and don’t get replies as often as one would probably hope. Maybe I’m barking in the wrong place?

    0
  22. 31

    I am planning to write plugins for wordpress. It was all helpful.

    0
  23. 32

    thanks………

    0
  24. 33

    oh god, version number in settings AND somewhere where you can read it on someones blog without needing their log in details!! that has saved me much trouble.

    you say don’t assume? I say ALWAYS assume! assume that the user will do something they’re not supposed to, even if it says in big bold, underlined letters ,”you do not need to change these values unless…” then, of course, they will change them!

    oh, escape everything and trim spaces from values and plenty of validation error explanation!

    great article, made me happy to see someone go through what I went through :-)

    0
  25. 34

    Eagerly waiting for your 2011 list!

    0

↑ Back to top