This is a followup to my how to get your plugin in the WordPress repository post.
While code isn’t outright rejected for being ‘bad’ code (only security holes and guideline violations), a lot of plugins are doing the easy things wrong. These plugins will get approved, but they won’t work with all setups, they’re more likely to have issues with Multisite, and they’re just not thinking forward. They aim to solve a, singular, problem, without looking beyond. Primarily I see this when people are trying to bring in some js code into their plugin. Heavens knows I do it, and I’ve done it wrong too. But as I see more and more plugins, I’m starting to get better and better at knowing what’s wrong when I see it.(“I know it when I see it” thanks to United States Supreme Court Justice Potter Stewart)
The easiest way to show you is to give you some really bad examples and go through some of the steps to fix it. The best part is that I’m actually going to use real plugins I’ve seen. Only the name has been changed to protect the innocent.
Ready? Here’s what we’re doing wrong.
Not using functions to define locations
The very bad code:
echo '<script src="/wp-content/plugins/myplugin/myscript.js"></script>';
I wish this was something I made up. Worse, I’ve see it more than once. Recently.
This install is assuming WordPress is installed in the root of your HTML folder (i.e. domain.com). This is not always the case, as many people install WordPress in subfolders. We’ll need to fix that first with home_url().
echo '<script src="'.home_url('wp-content/plugins/myplugin/myscript.js').'"></script>';
Now it’s a little better, as by using home_url() we’re letting WordPress define where ‘home’ is. Great! This has two pretty obvious problems, however. First, if I have WordPress installed in a folder, like /public_html/wordpress/, but I’m running it out of the main domain by giving it its own directory, this won’t work. Your code would point to http://example.com/wp-content… when mine is in http://example.com/wordpress/wp-content.. instead! The ‘easy’ fix is to change home_url() for site_url(), but what if I’m not using wp-content? You didn’t know we could Move wp-content? We can. So let’s address that.
echo '<script src="'.content_url('plugins/myplugin/myscript.js').'"></script>';
By using functions to determine plugin and content directories, we can make this much more flexible. That works, but it could be better. What if we didn’t have to define the plugins or myplugin folders? We could just do something simple like this.
echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';
Now we have a simple, flexible, functional script embed of js. Except there’s one, minor problem. We’re not including the script correctly.
Not enqueuing files
This isn’t ‘wrong’ really. I mean, if I put this in my plugin, it would echo out the script, and that’s what I want, right?
echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';
But let’s say I want to put it in my header:
function my_scripts_method() {
echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';
}
add_action('wp_head', 'my_scripts_method');
And now I want to include my CSS so it looks pretty:
function my_scripts_method() {
echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';
echo '<link rel="stylesheet" type="text/css" href="'.plugins_url('myscript.js',__FILE__).'" media="all" />';
}
add_action('wp_head', 'my_scripts_method');
Oh, wait, no, I wanted my JS in the footer:
function my_scripts_method_foot() {
echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';
}
function my_scripts_method_head() {
echo '<link rel="stylesheet" type="text/css" href="'.plugins_url('myscript.js',__FILE__).'" media="all" />';
}
add_action('wp_head', 'my_scripts_method_head');
add_action('wp_footer', 'my_scripts_method_foot');
And really, this will work. But it’s not efficient, I’ve got extra actions, and I’m not considering any jquery dependencies anymore. By using wp_enqueue_script is better. Weblog Tools Collection did a series on how to properly add scripts (note that it’s a bit out of date with the use of WP-CONTENT constants). From that we can extrapolate to use just this to include our js and css:
function my_scripts_method() {
wp_enqueue_script('my_script', plugins_url('myscript.js',__FILE__) );
wp_enqueue_style('my_script', plugins_url('myscript.css',__FILE__) );
}
add_action('wp_enqueue_scripts', 'my_scripts_method');
What enqueue does is put your code in the best possible location and can be extended to load dependencies. wp_enque_scripts has a lot of power, and because it’s a WordPress function, it’s got options that make it more flexible. Like when I look at my above code, I remember, oops! I wanted to run my js out of the footer! Not a problem. Look at my options.
wp_enqueue_script('handle', 'source', 'dependencies', 'version', 'in_footer');
The ‘handle’ is what I want to name my script, it should be unique. If I register my script, I can call the handle over and over again. We’re using my_script right now. The ‘source’ is where my file is located. We’re lifting that from our other code, the bad code, because it works. Your ‘dependencies’ are the other js files yours needs to function. If I put in array('jquery', 'scriptaculous') then both jQuery and Scriptaculous would get loaded before my script. Curiously, you don’t actually need the ‘version’ option, as you can leave it blank and WordPress will automatically add a version number equal to the current version of WordPress you are running. So every time you upgrade WP, it will get updated and force a re-download. This is good, since if you have dependencies to scripts included in WordPress, and they change with a new version (which is the only way they can change), then you get updated too. Finally we have the value I was looking for, ‘in_footer.’ Leave it blank and it’s in the header, put in true and it’s not.
This makes my code:
function my_scripts_method() {
wp_enqueue_script('my_script', plugins_url('myscript.js',__FILE__), '','', true ););
wp_enqueue_style('my_script', plugins_url('myscript.css',__FILE__) );
}
add_action('wp_enqueue_scripts', 'my_scripts_method');
Yeah, isn’t that a lot easier?
Using a different jQuery
This last one I’m going to touch on today is the exact code I saw, in the wild, and it’s got two of my three buggaboos in it.
wp_enqueue_script('jquery-1.4.3.min.js', '/wp-content/plugins/myplugin/js/jquery-1.4.3.min.js');
Okay. You already know the right way to call the script, so we’ll edit that into something more flexible.
wp_enqueue_script('jquery-1.4.3.min.js', plugins_url('js/jquery-1.4.3.min.js',__FILE__) );
That should be okay, but it’s totally not.
Most importantly here, we’re calling jquery, which is actually built in to WordPress. Now, we’re calling it by a different handle, but that’s no guarantee that it won’t cause conflicts. In fact, I’m pretty sure this will cause no end of problems with some plugins. The right thing to do would be this:
function my_scripts_method() {
wp_deregister_script( 'jquery' );
wp_register_script( 'jquery', plugins_url('js/jquery-1.4.3.min.js',__FILE__) );
wp_enqueue_script( 'jquery' );
}
add_action('wp_enqueue_scripts', 'my_scripts_method');
Now we’re making sure we won’t have conflicts by re-registering jquery, replacing it, and moving on.
A lot of people would actually recommend using Google instead, as it takes the responsibility off you for including a file you don’t ‘control.’ Also it makes your plugin smaller and load faster.
function my_scripts_method() {
wp_deregister_script( 'jquery' );
wp_register_script( 'jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js' );
wp_enqueue_script( 'jquery' );
}
add_action('wp_enqueue_scripts', 'my_scripts_method');
Great! Now we’re done, right? Wrong. As of this writing, WordPress is using jQuery 1.7.2. Now I couldn’t come up with a reason to include an old version of jQuery in WordPress (newer, yes, older, no), so I asked around and none of my friends could either. Using an older version is more likely to cause issues with newer code included in WordPress, as well as plugins which are upgraded to take advantage of the new features. You’re shooting yourself in the foot. The only thing you might be using this for is to include deprecated fictions, and really you need to update your code to fix that instead.
If the whole point is to load the scripts from Google, though, there’s an awesome plugin for that.



The majority of what I do to speed up my website is on the server level. In 2009 I 








I’m not a super-psycho coder. But between being a busybody and being a volunteer plugin referee, I do spend a disproportionate amount of time looking at the code people put in for plugins, which means I actually see a lot more code, and a lot more submissions, than you might expect. This puts me in a place where I actually can offer some of the world’s most basic advice ever, that a surprising number of people seem to miss, about how to submit your plugins, what will get them downcheked, and what you really just shouldn’t do.
When you submit your plugin, put in a link to the code so it can be downloaded and checked. (See
A subset of that is that if your plugin is a fork of someone else’s, be the good person and credit them! It’s not required all the time, but take a look at the copyright information on a plugin. Sometimes they say they require credit in the code. If so, you’ve got to do it. Even just a line that says “Copyright 2009-2011 Some Other Dude” and then “Copyright 2011 Me” below it. That’s a nice CYA. If you want to be really nice, put their userID under ‘contributors’ in the readme file, and they’ll have their pretty face on your plugin.
This happens when your plugin has been reported as possibly being in conflict with the developer guidelines, or it has a security hole. Many times you will not be notified when this happens. Sometimes you’re not notified because the report is found to be incorrect, and sometimes it’s because you’ve been warned before. And, once in a while, it’s because the person who closed your plugin doesn’t have the ability to email you. Surprise! There are some people on the plugin repository team who don’t have the access to the plugins email system, so when they close your plugin, they’ll ask someone else to email you. If that person is busy, it might take a while.

One of the ways to secure your web apps is to limit the damage they can cause. When you create a database for a webapp, you have to provide a user ID and password to connect to the database, logically enough. Illogically, most people just use the same username and password they use to SSH into their server. After all, it works.




This most often comes up when someone is suffering content theft. Invariably, someone will see their hard written prose on some scammy person’s site, and want it taken down. This is, sadly, harder to do than we’d like. Basically you have to find the site owner, contact them, ask them to take the stuff down, hope they do it, and when they don’t, go up to their webhost. I’m not going to get into the copyright issue, and just assume you know not to attack someone over links to your site (not illegal), rss feeds pulling excerpts from your site (ditto), or quotes (really?). If you don’t know what is and isn’t copyright/content theft, then you’re not ready for this yet.
