7 Deadly Sins of WordPress Development

There’s a lot of freedom in WordPress development to extend the platform to just about anything you could imagine. However, when you develop for WordPress you have to make sure your theme or plugin can play nice with other WordPress extensions. Coding in a vacuum is inexcusable and can cause you or someone else a lot of trouble down the road. Here are some of the major things to look out for:

1. Loading your own copy of jQuery

C’mon man…Seriously? Loading your own copy of jQuery is a great way to just ruin everything.

Novice plugin and theme developers sometimes make the mistake of loading their own copy of jQuery for whatever reason. In many cases they de-register the one that comes with WordPress, which looks something like this:

 if( !is_admin()){
wp_register_script('jquery', ("http://cdn.jquerytools.org/1.1.2/jquery.tools.min.js"), false, '1.3.2');
//wp_register_script('jquery', ("http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"), false, '1.7.2');

De-registering WordPress’ copy of jQuery and loading another has the potential to break all kinds of javascript in other themes and plugins.

The Solution? Don’t be THAT guy. Just use the copy included with WordPress.

2. Not loading JS/CSS files properly

This deadly sin includes two smaller sins. The first is adding inline script and stylesheet tags via your header file. Pasting them right into the header can cause them not to load at the right time and will also have them loading on every single page.

What’s the remedy? Use wp_register_script/wp_enqueue_script.

Adding scripts the right way will load them on the right pages at the right time with the proper dependencies.

A second related deadly sin is loading custom Javascript and/or styles on every page, instead of conditionally loading it when necessary. Loading your script on every page is often not necessary. This can cause your site to slow down significantly.

The solution: Load your scripts only when necessary to keep your site lean and fast.

Here’s a very common example of how to do this, courtesy of Phil Banks’s tutorial on conditionally loading plugin scripts in WordPress.

add_action( 'wp_print_scripts', 'deregister_cf7_javascript', 15 );
function deregister_cf7_javascript() {
    if ( !is_page(15) ) {
        wp_deregister_script( 'contact-form-7' );
add_action( 'wp_print_styles', 'deregister_cf7_styles', 15 );
function deregister_cf7_styles() {
    if ( !is_page(15) ) {
        wp_deregister_style( 'contact-form-7' );

Essentially, this script stops the contact form script from loading on all pages and load only on the contact form page, using the page ID. It takes a bit of time, but you can use this same method to fine tune your WordPress site so that it’s not always loading unnecessary scripts.

3. Not escaping user input in SQL and not encoding user input on output

Leaving yourself vulnerable to SQL injection attacks can be deadly for your WordPress site
SQL injection attacks are one of the most common ways to exploit web application vulnerabilities. Not escaping user input in SQL can leave you vulnerable to these kinds of attacks. This mostly pertains to plugin development but should also be a concern for regular WordPress users who may be installing a plugin from an untrustworthy source.

The solution: Make sure to sanitize user input in order to protect against SQL injection and then encode it on output for display to prevent XSS vulnerabilities. The WordPress codex has a section on Data Validation and WP Tuts has an excellent reference that goes into more detail:
Data Sanitization and Validation With WordPress.

4. Incorporating too many 3rd Party Services

Overloading your site with social buttons and third party services is a bad idea
The only place where a third party registration or login plugin makes sense is if a significant number of your user base, or potential user base, is active on that social network. The connection is then a convenience for your users and helps to get more people in the door. However, if you are offering the ability to register and log in via Twitter, FB, G+, and more just to cover your bases, then something is wrong. It’s simply not necessary and can actually bring your site to a crawl while loading all of those third party services.

The Answer: Include third party services sparingly and only if they are absolutely necessary.

5. Expecting too much from shared hosting

Don’t be sucked in by all-you-can-eat shared hosting plans
Shared hosting sucks. End of discussion. Don’t ever fall prey to the all-you-can-eat shared hosting buffets. You can actually waste a lot of your own time by expecting too much from shared hosting. When your server gets oversold and your site slows down, you can spend hours trying to sort this out with your host. It’s a mistake to think that you can add all kinds of media, plugins and social aspects to your WordPress site on a shared host and have it all running smoothly.

Recommendation: Purchase better hosting than you need, especially if you are expecting your site to grow. Cyber Monday is a great time to find excellent deals on VPS and dedicated servers. Take the time to do some research and you’ll be able to find an affordable host that can accommodate anything you want to do with WordPress.

6. Using “admin” for a username with an insecure password

Using “admin” for your administrator username and “password” for your password is a hacker’s dream come true. There are actually evil bots that go around looking for installations that have done this in order to exploit them.

The Solution: Give your site’s a unique admin user name and use a strong password. You can even add a plugin to force users to select strong passwords.

7. Adding tons of plugin-type functionality to a theme’s functions.php

Overloading your functions.php file makes it difficult to troubleshoot plugin conflicts

Why is this bad? There are a number of reasons that you want to avoid this as much as possible. For the sake or organization it’s best to keep your presentation separate from your functionality, especially if you have other developers working on the same site.

Also, it can be a nightmare to troubleshoot conflicts and problems after upgrades. For example, let’s say you’ve added a ton of functionality to your theme’s functions.php file but there’s no easy way to turn each part off one by one for determining the culprit when your site is having problems. If all of this functionality existed in separate plugins, you’d be able to more easily troubleshoot them and find the part that needs to be updated or removed.

Solution: Create a “functionality plugin” every time you are wanting to paste something into your functions.php file. It takes just a little more time but you’ll be grateful for it later.

Are these the deadliest WordPress development sins you know? What would you add to the list?

photo credit: DigiTaL~NomAd via photopin cc

28 Responses

    Mathew - ThinkingMedia

    “Not escaping user input in SQL”

    No one should still be escaping SQL input! If you have to escape your input then you’re doing it all wrong.

    PDO uses parameterized values for SQL statements that separates the input data from the query. It’s not possible to perform a SQL injection if PDO is used properly.

    “not encoding user input on output”

    It is easy for a hacker to break out of encoded data. Once they figure out what encoding is being used. The only safe thing to do is strip special characters out of input all together.


      WordPress uses its own $wpdb database object. I tend to use the DB solution provided by the framework, instead of introducing my own.

      The $wpdb object has plenty of methods for preventing SQL injection.

    Patty J. Ayers

    I just found out the hard way that VPSs often are *less* powerful and no more secure than shared hosting. A Hostgator manager specifically explained this, stating that the higher cost and the word “private” doesn’t mean what it sounds like in terms of security, and the only real distinction from their shared accounts is that you have root access, and that the company has little obligation to help manage resources – whereas they do have to manage resources on shared servers. So although shared hosting may suck, VPSs unfortunately can suck just as much.


      My website’s load time improved from 7 seconds to 3 seconds after switching from shared to VPS. http://d.pr/i/LwKi That’s good enough for me to recommend VPSes.

        Patty J. Ayers

        Chris, that’s obviously an up-side, at least to your particular VPS and the way you’re managing it, and that’s great. What I wanted to point out is that a VPS is *not* automatically better than a shared server in terms of security or resources, and that in many cases they can be worse in those respects.


          Patty, I totally agree with you. Looking at the system logs, one may be surprised by the large number of attackers who try to break in your server. If you plan for VPS, you need to plan for a good system admin to tighten up the security for you. Otherwise, pay for some high end shared hosting may be a better choice. For those hosting plans at a few bucks a month, a website may share with up to 400 or 500 other sites. Then sometimes when you have good lucks, those sharing sites may not have heavy traffic or misbehaving apps that can bring down the server from time to time.


    #8 Using jQueryUI with your own custom theme and not isolating it with a unique class – the “CSS scope” option when using the Theme Roller.


    Re: 1. Loading your own copy of jQuery

    C’mon man…Seriously? Loading your own copy of jQuery is a great way to just ruin everything.

    Actually, I know you don’t want to hear me say this but this one is a strike against WP. It’s a widely used universal library over a legit CDN (which does have added benefits, see point #5) and WP can’t handle it? Does that sound right to you?

    C’mon (wo)man…Seriously?

    I understand not messing with the Admin side but the front-end should be architected to as “open” as possible.


      I totally agree. Other than the fact that the code in the example is bad, what’s the problem with loading from a CDN? Especially if you load the same version….


        There isn’t any, except for the fact that you might need to babysit it more. I tend to use the bundled version of jQuery until I have a reason not to for that particular project.

        But, I agree… I don’t think of this as absolutely a bad thing.


          If you want to look at WP as a CMS in a box – activate a theme and a couple plugins and away you go – then it makes sense. There needs to be some rules.

          However, if you want to look at WP as a framework then putting the kibosh on jQuery via CND is a major snafu. A framework should extend and make easy best practices, etc. Sure you can use the local copy but if I feel there’s a want / need to use an industry standard library in an industry standard way that should not be a problem. In fact, it should be encouraged.

          What should be #1 is:

          1. Lack of meaningful commenting, documentation and variable names in plugins and themes.

          Good code isn’t good code if there are no comments. For the love of God, it’s 2013, and we’re still living in the Dark Ages? WTF? Open Source is not “Look at me, I have a repo on GitHub.” Open Source should be “I wrote this not just for me, but for others to use too. Look! I made that easy for them.”

          IMHO plugins and themes without adequate commenting should not be allowed on WP.org. It’s time to stop viewing the WP product as simply code and functionality, and broaden the product to include the whole end to end experience with that product.


          I’d be happy if people just universally unregistered the copy of jQuery that was loaded before loading their own. I cringe when I load a plugin and look at my sources only to find 2 copied of JQ loaded.

          When you get down to the standard user who might not think to check and has a bunch of site candy loaded, there could be 3-4 copies of JQ floating around.

      Josh Broton

      There are really good reasons to use WordPress’s jQuery. No conflict mode is VERY important when using plugins, as $ is not reserved to just jQuery, but MooTools and a few other libraries that plugin devs could use all use $.

      The only benefit anyone here has mentioned is speed of loading from a CDN. While that’s *technically* accurate, there’s a Shop Talk Show episode with Alex Sexton that dispells that myth. It’s actually faster to concatenate and minify your local jQuery with your other scripts than it is to serve it up from a CDN. (source: http://shoptalkshow.com/episodes/061-with-alex-sexton/?t=54:39 )

      My suggestion is to work within the best practices of the environment you’ve chosen to use, and if you dislike how it’s supposed to work, find another or fork WordPress and roll your own. The community is built on the assumption you’re not breaking it by going against convention.


    Seems to me that commenting out a section of your functions.php is a heck of a lot easier than having to turn plugins on & off in the dashboard.


      Yeah, potentially, but I think the author’s goal is to help make your code more modular.

      Also, the more plugin functionality that is in your theme, the tighter your integration becomes with the theme, and you can eventually be a slave to your theme. Shortcode abuse comes to mind here.



        The majority (too many?) of themes are no longer themes, they are custom (typically) single-purpose applications. In some cases, this is fine. For example, when the “theme” is for *a* client. However, in many cases, it is not.

        If you can’t just switch themes (read: presentation) then that’s not a theme. Period. End of story. Call it whatever you want, but it’s not a theme. It’s time we start using language that make it easy to differentiate between the two. It would help if Automattic did the same on WP.org.


    So as a newb, does this mean I have to register jquery with wordpress if I want to use it? If so, how?


      No, jQuery is already a registered package. Registering is basically declaring a package, and where the file location is. After a file is registered (which jQuery is by default), you then have to load it. You load jQuery using the wp_enqueue_script() function.

      You can learn all about it and better understand the whole flow here: http://codex.wordpress.org/Function_Reference/wp_enqueue_script

      Good luck :)


        Correct me if I’m wrong but I believe wp_enqueue_script() takes care of registration as well. That is, you don’t have to do both steps. Some people do it out of habit, but I’m 98% certain you can just jump straight to wp_enqueue_script(), skip the register step and not have any ill effects.

        Or did I misread something somewhere?


    I’m not totally convinced by the idea of loading javascript conditionally. Unless you have an enormous amount of javascript, it’s better to have it concatenated, minified and gzipped into a single file. That way, you will have only a single HTTP request, which will improve the speed much more than shaving off a small bit off the file.

    Added to that the entire file will be cached by the browser, meaning it only gets downloaded once, and I would have thought that this is a more efficient method for your site than downloading separate files for different pages.

    The only exception, I think, would be if you had a *very* large js file that wasn’t needed everywhere, and then you might want to load it separately, but it would have to be pretty big. A comment form script wouldn’t seem a good choice.


      And that also makes the argument for using a CDN. For example, if the previous site used Google’s jQuery then the browser can might be able to use that.

      You’re right. With bandwidth what it is, it’s probably less of a concern. That being said, loading stuff that’s not necessary is asking for an unexpected conflict somewhere.


    What if you’re wanting to leverage something in a later version of JQuery than WP uses? What’s the best way of going about leaving the shipped version in place and using a later version for whatever customization you’re doing in a theme or something?


    As a plugin developer, I really, really, really wish more people would follow #1 and #2 more often.

    I just spent 2 days unhooking, unregistering, dequeueing, and re-implementing a bunch of CSS and JS loads. The site performance went up by like 18%.

    If you could add a #8, it should be “check and see if your plugin is going to need to run everywhere, if it doesn’t, don’t load all the scripts & css.”

Comments are closed.