Javascript and WordPress — The Definitive Guide

Digg Muti Delicious

Using cus­tom Javascript code in a WordPress theme or plu­gin is, in many cases, a given. Fortunately, WordPress comes bundled with a selec­tion of pop­u­lar Javascript lib­rar­ies (jQuery, Prototype and oth­ers) for use with your plu­gins and themes. Many users, how­ever, simply write the ‘<script>‘ tags in the header.php file of their theme or as part of a func­tion in their plu­gin that is run in the header of the theme being used. This is a poten­tial prob­lem area that can have you, the developer, sit­ting for ages look­ing at your code and won­der­ing why plu­gin ‘X‘ isn’t work­ing cor­rectly when theme ‘Y‘ is act­ive. This guide aims to provide an under­stand­ing of how to cor­rectly enqueue Javascript in WordPress and how to avoid poten­tial Javascript conflicts.

Okay, what are we doing here?

We’re going to enqueue the Javascript files, used by our WordPress plu­gin or theme, using the cor­rect method and the wp_enqueue_script()func­tion. We will be adding an action to the init() and, inside a func­tion within our theme or plu­gin, run­ning the wp_enqueue_script() func­tion. We will also be includ­ing the Javascript in the admin­is­tra­tion area only, cre­at­ing depend­en­cies between our vari­ous cus­tom Javascript files and enqueuing the scripts on only a spe­cific page in the admin­is­tra­tion area.

How do we enqueue the Javascript?

Okay, you will need:

  1. 1 x cus­tom func­tion in either your theme’s functions.php file or in your plugin.
  2. 1 x selec­tion of Javascript files required by your theme or plugin.
  3. 1 x add_action() line within your code.

Lets fol­low this like a recipe. The above ingredi­ents each form part of the recipe we need to fol­low in order to cor­rectly enqueue Javascript in WordPress.

1. Write a func­tion in your theme or plu­gin that will run the vari­ous enqueue commands.

This func­tion is the heart of enqueuing the Javascripts in WordPress. It tells the sys­tem which scripts to include, what they require (if any­thing) and in what order to enqueue the scripts. An example of this func­tion may look like this:
function matty_enqueue_theme_js () {
wp_enqueue_script('matty-functions', TEMPLATE_URL . 'js/functions.js', array('jquery'), '1.0', false);
} // End matty_enqueue_theme_js()

  • The ‘TEMPLATE_​URL‘ con­stant can be defined in your functions.php file as:
    define( 'TEMPLATE_URL', trailingslashit( get_stylesheet_directory_uri() ) );
    Or, altern­at­ively, it can be replaced with:
    trailingslashit( get_stylesheet_directory_uri() )

Okay. Lets run through this func­tion and work out what it does.

For each Javascript file you wish to include, add another wp_enqueue_script() line to the func­tion. This line reads as follows:

The name by which I would like to refer to this Javascript file is ‘matty-​​functions‘. It is loc­ated at TEMPLATE_​URL . ‘js/functions.js’ *, requires jQuery to run and has a ver­sion num­ber of 1.0. The ‘false‘ at the end denotes whether or not the script is to be loaded in the footer of the theme (on wp_footer()). If false, the script will load in wp_head() of the cur­rent theme.

Each para­meter can be explained as follows:

$handle — A lower­case text string, no spaces, that is the “iden­ti­fier” of the Javascript file being loaded on that line. Can be used if one of your files requires another of your files in order to run.

$src — The full URL path to the Javascript file being loaded.

$deps — Does your script require any­thing to run? It could require a spe­cific lib­rary (for example, jQuery) or another of your Javascript files being loaded in (referred to by its $handle).

$ver — The ver­sion num­ber of the script being loaded. This is an optional parameter.

$in_​footer — Should the script be loaded in the footer or in the header? If set to false, the script will load in the header. This is an optional para­meter that defaults to ‘false‘.

And hey presto! We’ve got a func­tion that we can tell to include all our Javascripts!

Run the func­tion when the WordPress wp_​head() action occurs.

No sweat. We’re going to run the above func­tion on the WordPress wp_head()action (when the sys­tem ini­tial­ises). This is how we do it: add_action('wp_head', 'matty_enqueue_theme_js', 1);

Explaination? Okay.

When the WordPress wp_head() func­tion runs, add the ‘matty_​enqueue_​theme_​js‘ func­tion to the list of func­tions to run. Give it a pri­or­ity set­ting of 1 (this can be used to con­trol which func­tions execute before others).

Easy, right?

What Javascript lib­rar­ies are already bundled with WordPress?

In a word; loads. Here’s a com­pre­hens­ive list of Javascript lib­rar­ies bundled with WordPress. Try to stick to one lib­rary, as it will greatly min­im­ize poten­tial con­flicts between your scripts. Where pos­sible, be sure to use the bundled ver­sion of the script your code requires, as it will min­im­ize load times and gen­er­ally be a lot easier to work with your scripts (unless the ver­sion you require is not yet bundled with WordPress… *cough* jQuery 1.4 *cough*.).

I only want the Javascript in the WordPress amin­is­tra­tion area. How do I do that?

No sweat. Simply run the fol­low­ing script instead of the above add_action():

add_action('admin_print_scripts', 'matty_enqueue_theme_js');

To include the Javascript on only one par­tic­u­lar admin­is­tra­tion page, run some­thing like the following:

add_action('admin_print_scripts-widgets.php', 'matty_enqueue_theme_js');

The above line will enqueue the Javascript only on the wid­gets screen of the admin­is­tra­tion area.

One of my scripts relies on another. What do I do?

Remember that ‘$handle‘ para­meter we dis­cussed earlier? Lets use it.

When one script relies on another script (note: not a bundled lib­rary but another cus­tom Javascript file), the ‘handle’ para­meter is used in the ‘$deps‘ to let the script know that another script is required. Lets take a look at our func­tion again:

function matty_enqueue_theme_js () {
wp_enqueue_script('matty-some-cool-code', TEMPLATE_URL . 'js/some-cool-code.js', array('jquery'), '1.0', false);
wp_enqueue_script('matty-functions', TEMPLATE_URL . 'js/functions.js', array('jquery', 'matty-some-cool-code'), '1.0', false);
} // End matty_enqueue_theme_js()

See what we did there? We added the handle of the first line to the depend­en­cies array of the second line. Therefore, ‘matty-​​some-​​cool-​​code’ requires jQuery ** to run, and ‘matty-​​functions’ requires both jQuery and ‘matty-​​some-​​cool-​​code’ in order to run. Please note that, because I have spe­cified that my scripts require jQuery, there is no need to load the jQuery lib­rary itself on it’s own line.

Right. Lets sum it up.

What did we dis­cuss here today? We learned how to cor­rectly enqueue Javascript files in WordPress, how to cre­ate depend­en­cies between files and how to load Javascript lib­rar­ies that come bundled with WordPress.

And all the code we dis­cussed above:
function matty_enqueue_theme_js () {
wp_enqueue_script('matty-some-cool-code', TEMPLATE_URL . 'js/some-cool-code.js', array('jquery'), '1.0', false);
wp_enqueue_script('matty-functions', TEMPLATE_URL . 'js/functions.js', array('jquery', 'matty-some-cool-code'), '1.0', false);
} // End matty_enqueue_theme_js()

add_action('init', 'matty_enqueue_theme_js', 1);
I hope this post is found use­ful. If you have any quer­ies, please post them in the comments.

* TEMPLATE_​URL is a con­stant I have setup that holds the dir­ect URL path to the cur­rent theme’s dir­ect­ory. This is the path as it is typed in a web browser, begin­ning with ‘http://‘.

** Notice how jQuery is required by both Javascripts but is only loaded once in your code? This is why we use the wp_enqueue_script() action… to avoid a) mul­tiple ver­sions or instances of a script being included and b) to avoid script con­flicts because of these load issues.

Related Posts

14 Comments

  1. Posted 14th March, 2010 at 11:14 pm (172 days ago)

    Now, that’s use­ful dude! *bookmark*

    • Posted 14th March, 2010 at 11:28 pm (172 days ago) in reply to Chris M

      Hey Chris,
      Thanks man. Glad you like. :)

      I’ve exper­i­enced Javascript con­flicts, once or twice, where the issue ulti­mately stemmed from this very thing– incor­rect inclu­sion of the Javascript. Thought oth­ers
      may have had/​be hav­ing sim­ilar issues and that this could help.

      Always great to hear from you man. :)

      Cheers,
      Matt.

  2. Posted 14th March, 2010 at 11:29 pm (172 days ago)

    Hey Matt,

    Ye, I’ve hit issues quite a few times and as much as I search the Internet, I’m yet to find an art­icle that really gets down to the bot­tom of it, so I’m well impressed to see this one, thank you for shar­ing it!

    Chat to you soon bro.

  3. Posted 14th March, 2010 at 11:56 pm (172 days ago)

    Chris and I were just dis­cuss­ing this the other day. As he said — super use­ful. Thanks Matt.

    • Posted 15th March, 2010 at 8:55 am (171 days ago) in reply to Brendon

      Hey Brendon,
      Thanks man. :)

      It seems like one of those things that can get in the way really eas­ily if it isn’t handled cor­rectly. :P

      Glad the post is use­ful man. :)

      Cheers,
      Matt.

  4. Posted 16th March, 2010 at 12:59 pm (170 days ago)

    Hi Matt,

    Great write up about WordPress and JavaScript! This post is really use­ful, espe­cially when most of the themes I bought ended up with javas­cript spill­ing all over the place. Those developers really need to learn how to prop­erly organ­ize js and css files.

    If you could add a syn­tax high­lighter to your blog post, that would be great!

    I’m fol­low­ing you on Twitter.

    • Posted 16th March, 2010 at 6:11 pm (170 days ago) in reply to WordPress Hardcore

      Hi Gary,
      Thanks so much for your kind words. I really appre­ci­ate it and am glad you found this post to be useful.

      I’m cur­rently in the pro­cess of redesign­ing and recod­ing this blog. I will be adding fea­tures to enhance the code vis­ib­il­ity and will look into adding a syn­tax high­lighter. Thanks for the note. :)

      Cheers,
      Matty.

  5. Posted 23rd March, 2010 at 6:27 am (164 days ago)

    very cool & good tips, thank you very much for sharing.

    but I think you should wrap your code into PRE or CODE tags?

    • Posted 25th March, 2010 at 8:09 pm (161 days ago) in reply to JavaScriptBank.com

      Thanks. :)

      Yeah, I do wrap my code snip­pets in CODE tags. I’ll be high­light­ing them more in my redesign (com­ing soon) as well as look­ing into adding a syn­tax high­lighter to make longer snip­pets easier to read.

      Thanks again for your com­ment. :)

  6. Posted 9th July, 2010 at 2:20 pm (55 days ago)

    Hi Matt,

    Wonder if you could help… I’ve tried your tech­nique with the Coda-​​Slider. I’ve imple­men­ted it in my tem­plate file using this:

    <script type=“text/javascript” src=”/scripts/jquery-1.3.2.min.js”>
    <script type=“text/javascript” src=”/scripts/jquery.easing.1.3.js”>
    <script type=“text/javascript” src=”/scripts/jquery.coda-slider-2.0.js”>

    $().ready(function() {
    $(‘#coda-slider-1′).codaSlider();
    $(‘#coda-slider-2′).codaSlider({
    dynam­icAr­rows: false,
    dynamicTabs: false,
    auto­Slide: true,
    auto­SlideIn­ter­val: 4000,
    auto­SlideStop­When­Clicked: true
    });
    $(‘#coda-slider-3′).codaSlider();
    $(‘#coda-slider-4′).codaSlider();
    $(‘#coda-slider-5′).codaSlider({
    dynam­icAr­rows: false,
    dynamicTabs: false
    });
    $(‘#coda-slider-6′).codaSlider({
    cross­Link­ing: false,
    first­Pan­elTo­Load: 3
    });
    $(‘#coda-slider-7′).codaSlider({
    auto­HeightEaseD­ur­a­tion: 300,
    auto­HeightEase­Func­tion: “easeIn­Ou­t­Expo”,
    slideEaseD­ur­a­tion: 300,
    slideEase­Func­tion: “easeIn­Ou­t­Expo“
    });
    $(‘#coda-slider-8′).codaSlider({
    auto­HeightEaseD­ur­a­tion: 2500,
    auto­HeightEase­Func­tion: “easeIn­OutElastic”,
    slideEaseD­ur­a­tion: 2500,
    slideEase­Func­tion: “easeIn­OutElastic“
    });
    $(‘#coda-slider-9′).codaSlider({
    dynam­icAr­rows: false
    });
    });

    And works fine. However, that’s not the proper way to do it, so using your tutorial I wrote this code:

    func­tion wm_​enqueue_​theme_​js () {
    wp_enqueue_script(‘easing’, TEMPLATE_​URL . ‘scripts/jquery.easing.1.3.js’, array(‘jquery’), ‘1.0′, false);
    wp_enqueue_script(‘coda-slider’, TEMPLATE_​URL . ‘scripts/jquery.coda-slider-2.0.js’, array(‘jquery’, ‘eas­ing’), ‘1.0′, false);
    } /​/​ End wm_​enqueue_​theme_​js()

    add_action(‘init’, ‘wm_​enqueue_​theme_​js’);

    And added into my func­tions file. But it doesn’t work! Any ideas of why? Thanks!

    • Posted 11th August, 2010 at 2:46 pm (22 days ago) in reply to Wagner Matos

      Hi Wagner,
      Thanks for check­ing in. :)

      Regarding your query, I have a few ideas:

      1. Your code to cre­ate the slider itself needs to be in a JavaScript file, that would also need to be enqueued. I’d recom­mend cre­at­ing a gen­eric functions.js file, stored in your “scripts” folder, con­tain­ing the code to setup the Coda slider. You would then need to add another enqueue below the line entitled “coda-​​slider”, to enqueue your setup script for the slider.

      2. Do you have “TEMPLATE_​URL” defined? If not, add this to your functions.php file (prefer­ably at the top):

      define( 'TEMPLATE_URL', trailingslashit( get_stylesheet_directory_uri() ) );

      This sets TEMPLATE_​URL equal to your theme’s folder and enables the cor­rect dir­ect link to each JavaScript file.

      3. Change the action from run­ning on init() to wp_head(). I have found this to work bet­ter and have amended the blog post to reflect this.

      I hope this helps, Wagner. Please let me know if you require any fur­ther assist­ance with this. :)

      Cheers,
      Matt.

  7. Posted 11th August, 2010 at 2:43 pm (22 days ago)

    @Wagner — Hey mate, I know this is late, but here it goes any­way… I went through this one with our themes, with this tech­nique it’s best to use jQuery instead of $ so instead of saying:

    $(“selector”)

    Use

    jQuery(“selector”)

    Or you could also say jQuery().ready(function($) {}; if you want to keep using your $ signs…

    Cheers

  8. Posted 13th August, 2010 at 4:40 am (21 days ago)

    I am hav­ing dif­fi­culty with this and hop­ing someone can answer. How do I enqueue a script without a ver­sion #? Even if I leave it off, WordPress auto­mat­ic­ally adds ?ver=3.0 to it… and with the ver­sion # on the URL, the script will not load.
    Any help would be appreciated.

    • Posted 26th August, 2010 at 10:33 am (7 days ago) in reply to Ed

      Hi Ed,
      As per our cor­res­pond­ence, after look­ing through the code provided, I believe this to bea case of either the file not being poin­ted to cor­rectly (ie: the path to the JavaScript file is incor­rect) or a JavaScript con­flict situ­ation (the script provided looks to rely on the Prototype frame­work, which would need to be enqueued as well).

      I would recom­mend get­ting a single script to enqueue cor­rectly and, from there, enqueuing one script at a time in order to isol­ate the JavaScript conflict.

      All the best,
      Matty.

Leave your comment

Your email is never shared. Required fields are marked *

*
*