Starting in WordPress 2.1 (if I remember correctly), the awesome folks at Automattic gave us the even awesomer function of wp_enqueue_script.
Before that, it was every plugin or theme author for himself. If you wanted to add in a script, it was hard-coded in.
As you might imagine, this presented a ton of problems. Scripts were loaded twice, out of order, or even when they weren’t needed at all.
Furthermore, some themes and plugins had the JavaScript embedded within the plugin’s or theme’s PHP file just to capture a few PHP variables. Not good! In order to add scripts properly to JavaScript, you must always keep your PHP and JavaScript separate. And by separate, I mean separate files. There’s just no excuse anymore (I’ll get into this in Part 2 of this series).
The wp_enqueue_script function is the first step in loading your scripts properly. Not only can you add your script, but you can also specify the dependencies (e.g., jQuery), and the version number.
This prevents duplicate JavaScript files from loading, which is always a good thing.
So How Does wp_enqueue_script Work?
Aside from the excellent documentation from WordPress, you’ll find my regurgitated version below (gross, I know).
The function wp_enqueue_script takes in five arguments, with the last four being optional.
<?php wp_enqueue_script('handle', 'src', 'deps', 'ver', 'in_footer'); ?>
The handle argument is a string that names your script, or references someone else’s.
For example, you can add the jQuery script to any page by calling:
<?php wp_enqueue_script('jquery'); ?>
Likewise, if you have previously registered your script (using wp_register_script), you can call your script by calling:
<?php wp_enqueue_script('my_script'); ?>
Src
The src argument is asking for the URL of the file. If you supply the src of the script, the wp_enqueue_script function automatically registers your script for others to use (no need to use wp_register_script).
An example of it in use is:
<?php wp_enqueue_script('my_script', WP_CONTENT_URL . 'plugins/my_plugin/my_script.js'); ?>
Themers would use:
<?php wp_enqueue_script('my_script', WP_CONTENT_URL . 'themes/my_theme/my_script.js'); ?>
Deps
The deps argument is an array of dependencies. For example, if your script requires jQuery or other JavaScript files, it’ll load these files before your plugin’s JavaScript file.
Here’s an example:
<?php wp_enqueue_script('my_script', WP_CONTENT_URL . 'plugins/my_plugin/my_script.js', array('jquery', 'another_script')); ?>
See that array up there (it’s pretty, I know)? That’s what’s calling your dependencies.
jQuery is built into WordPress by default, so calling it via dependency is no problem as long as you queue it via wp_enqueue_script.
The another_script dependency assumes you have already used wp_enqueue_script to assign it a handle and a src.
The outcome in this scenario is that jQuery and another_script will load before my_script.
Ver
The ver argument is simply the version of the JavaScript file for caching purposes. If you are supplying your own script, it’s a good idea to supply a version.
The version is string based and looks like this:
<?php wp_enqueue_script('my_script', WP_CONTENT_URL . 'plugins/my_plugin/my_script.js', array('jquery', 'another_script'), '1.0.0'); ?>
As you update your JavaScript file, update the ver argument. If you don’t, you’ll inevitably run into caching issues with WordPress.
In_footer
The in_footer argument (since WP 2.8) determines if the script will load in the header or footer (header is the default).
To load your script in the footer, simply pass it a 1 (or true).
<?php wp_enqueue_script('my_script', WP_CONTENT_URL . 'plugins/my_plugin/my_script.js', array('jquery', 'another_script'), '1.0.0', true); ?>
Great care should be used when setting the scripts to load in the footer as some themes do not have this functionality built in (the theme must make use of the wp_footer function call).
Naming Your Handler
One last thing (err, warning?) to take note of is naming your handler for wp_enqueue_script. If you are using a third-party script (say, Colorbox), use common sense in naming the handler. There’s no reason to name it “lightbox” or “mybox”. The handler name should be obvious, right?
The same goes for the built-in scripts with WordPress.
For example, the handler ‘jquery’ is built-in. Do you want to supply your own version of jQuery?
How about ruin everybody’s day and give it a handler of ‘jquery.js’? The result will inevitably be two jQuery instances loading on the same page and causing mayhem with other scripts.
Instead, use the function wp_deregister_script to remove the WordPress reference and supply your own.
<?php wp_deregister_script(array('jquery')); wp_enqueue_script('jquery', 'your-jquery-path.js'); ?>
With this technique, however, you should have a pretty darn good reason for not including the default scripts. After all, you’ll essentially be running a piece of software that may not be fully tested and/or compatible with WordPress.
Great, I have wp_enqueue_script down. Now what?
You have to call wp_enqueue_script from the appropriate hook in WordPress.
Fortunately, WordPress has two such action hooks you can tap into: admin_print_scripts and wp_print_scripts.
The admin_print_scripts hook allows you to add scripts in the admin panel, while the wp_print_scripts hook allows you to add scripts everywhere else.
Adding your wp_enqueue_script code is as simple as adding an action inside your plugin or theme code.
An example of the code being used inside of a class constructor is:
<?php add_action('admin_print_scripts', array(&$this, 'add_admin_scripts')); ?>
And for those not using a class (classes help avoid conflicts with other plugins):
<?php add_action('admin_print_scripts', 'add_admin_scripts'); ?>
For the above example, we have a callback method of add_admin_scripts. An example of it in use is:
<?php function add_admin_scripts() { wp_enqueue_script('jquery'); } ?>
Conclusion
Here are the steps you should follow in order to add scripts to a WordPress theme or plugin:
- Add the appropriate action to your WordPress theme or plugin (themers will want to use functions.php).
- Determine your script dependencies.
- Code your wp_enqueue_script calls appropriately.
This article is an excerpt from Ronald Huereca’s e-book entitled WordPress and Ajax (used with permission).
Interesing. I was not using this function I was just adding the scripts in the normal way.
Regards
It definitely helps with script conflicts. I think you’ll find it useful.
Like Quicoto, I am also just adding scripts the usual way that I know of, so this is really something new to me and much more helpful. Thanks for sharing this. Will be bookmarking this.
Why don’t you use WP_PLUGINS_URL instead of WP_CONTENT_URL . ‘plugins ?
Habit 🙂 – I do in some of my code though.
Use of those WP_*_URL constants is actually not recommended. Instead, you should use the functions designed for this purpose.
Will produce: http://example.com/blog/wp-content/whatever
There’s also plugins_url(), includes_url(), admin_url(), and site_url(). These have been around since WP 2.6.
WP 3.0 adds a bunch of new ones, like home_url and network_home_url and so forth. All these work basically the same way.
The reason you should use these is that they take path changes and https and other things into account and such. They’re also shorter and less likely to break in the future than defines and such are.
Okay, so my PHP got nixed. That should have read:
echo content_url(‘/whatever’);
Will produce: http://example.com/blog/wp-content/whatever
Thanks. That’s good info.
Otto,
Those functions don’t seem to be covered in the Codex, at least Google and the Codex search don’t seem to have them listed. This was the closest I could find, and it’s recommending the constants (WP_…_URL).
http://codex.wordpress.org/Det.....irectories
Any ideas where the directory/url functions might be documented?
Thanks,
Byron
Otto,
Thanks for this tip! I’d become quite fond of WP_PLUGIN_DIR and WP_PLUGIN_URL. This is good to know. Will start revamping…
Thanks for publishing this article! It mirrors one that I published a while back on my whypad blog, but this will definitely hit a bigger audience. This script inclusion problem is the single biggest problem I see with people who use my plugin. Most of my forum posts are people saying that uploading images doesn’t work, and 95% of the time it is due to either the theme or some other plugin loading jQuery without using the enqueue function. I’ve seen jQuery being loaded 3 or 4 times on the same page while helping folks.
So, THANK YOU, THANK YOU, THANK YOU!!!!
@Byron,
Wow, never seen it that bad.
Another “sin” I didn’t mention is people who still use the “onload” event.
@Ronald,
You might also mention the wp_head() and wp_footer() sins of omission as well. Those seem to be getting better, but I still get a fair number of people coming by with a missing wp_footer, which is where Thickbox gets added.
Thanks again, and cheers!
Byron
Hi Ronald,
You mentioned this:
“Another “sin” I didn’t mention is people who still use the “onload” event.”
Can you enlighten me on why this a sin when adding a script to WP?
After searching for nearly 30 mins to get the syntax so i could understand what the true and false were being used for this article is the clearest and easiest to understand. Many Thanks it’s helped me to load jquery and jquery-ui.min from google and place it in the footer.
Great work thanks for sharing,
Ian
Awesome article, I love it!!!
I had so many problems with my plugin, because of jquery, now it’s all solved 🙂