Pippins Plugins
  • Email
  • Facebook
  • Feedburner
  • Github
  • Google
  • Twitter
  • Vimeo
  • Youtube
  • Rss
  • About
  • News
  • Join the Site
    • Member Benefits
    • Member Plugins
    • Email Notifications
  • Plugin Store
    • Affiliate Area
    • Checkout
  • Plugins
    • Plugin Portfolio
      • Plugin Portfolio – List View
    • Free
    • Premium
    • Member Plugins
    • Coding Standards
    • Get Plugin Support
  • Tutorials
    • Series
      • Plugin Development 101
      • Creating a User Follow System Plugin
      • Customizing Restrict Content Pro
      • Displaying Content with Easy Content Types
      • Writing Your First WordPress Plugins, Basic to Advanced
      • Working with Widgets
      • User Submitted Image Galleries
      • Plugin Thoughts
      • Integrating Stripe.com with WordPress
      • WordPress Rewrite API
    • Member Exclusive
      • Free Members
      • Subscriber Only
    • Difficulty
      • Beginner
      • Intermediate
      • Advanced
    • Action and Filter Hooks
    • Ajax
    • Custom Post Types
    • External APIs
    • Short Codes
    • Taxonomies
    • Video Tutorials
    • Widget Tutorials
    • WordPress Admin / Dashboard
    • Working with jQuery
    • WordPress Database
    • Writing Plugins
    • Tag Index
  • Reviews
  • Support Forum
  • Contact
    • Support the Site
    • Request Code Review
    • Plugin Support

Loading Scripts Correctly in the WordPress Admin

Posted on May 16, 2012 by Pippin in Action and Filter Hooks, Intermediate, Tutorials, WordPress Admin / Dashboard, Working with Users, Writing Plugins 23 Comments
Home» Tutorials » Action and Filter Hooks » Loading Scripts Correctly in the WordPress Admin
Tweet
Love It - 6

There has been a lot of talk over the last two days about loading scripts, particularly jQuery, correctly in WordPress themes and plugins, and anyone who follows me on Twitter probably knows that this is an issue I bring up a lot. When providing support for my plugins, I discover themes (and plugins) that are loading jQuery incorrectly and thus causing a conflict with my plugin all the time. It is, unfortunately, a very common issue, so now I’m going to show you how NOT to load scripts in the WordPress admin, and also walk you through the correct way of doing it.

A lot of WordPress plugins use jQuery scripts in their settings or other admin pages, and a lot of them do it incorrectly. While I don’t often see this, here is an example of how you absolutely should never do it:

1
2
3
4
function pw_loading_scripts_wrong() {
	echo '<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>';
}
add_action('admin_head', 'pw_loading_scripts_wrong');

Using a function like this will cause a second version of jQuery to be loaded into the head section of every single page in the WordPress admin. Not only will this place the extra jQuery library everywhere it is not needed, it will also most likely break most WordPress interfaces that rely on jQuery.

What about if you want to load a custom jQuery script, but not jQuery itself? You could do this:

1
2
3
4
function pw_loading_scripts_wrong() {
	echo '<script type="text/javascript" src="https://yoursite.com/path/to/custom.js"></script>';
}
add_action('admin_head', 'pw_loading_scripts_wrong');

However, if you do this, you will mostly likely be ensuing the wrath of plugin developers when they find you are breaking their correctly coded systems.

These two examples are not, however, the only incorrect ways to load jQuery and custom JS scripts. Here is another:

1
2
3
4
function pw_loading_scripts_wrong_again() {
	wp_enqueue_script('custom-js', 'wp-content/my-plugin-dir/js/custom.js');
}
add_action('admin_init', 'pw_loading_scripts_wrong_again');

You may ask why this is wrong, especially as it might look like the function does everything in an okay manner, but it doesn’t.

The first reason it is incorrect is that it is using the “admin_init” hook to load the scripts, which is not the correct hook to use. Instead the admin_enqueue_scripts hook should be used in order to ensure that the scripts are loaded at the right time.

The second reason it is incorrect is that, just like in the first two examples, the custom.js file is loaded into every single admin page in WordPress. You should never, ever do this. Always do your best to make sure your plugin is as efficient as possible and is only loading resources when those resources are needed.

And the third reason it is incorrect is because it is using a relative path for the custom.js file. It might load the file correctly in some WP installs, but it will fail in others. You should always load scripts through a complete path.

How do we fix the three problems with this example? Well, let’s start by using the correct hook:

1
2
3
4
function pw_load_scripts() {
	wp_enqueue_script('custom-js', 'wp-content/my-plugin-dir/js/custom.js');
}
add_action('admin_enqueue_scripts', 'pw_load_scripts');

That’s a little better, but not quite. Let’s now fix the problem of the script being loaded through a relative path. To do this, we should use a function that outputs the exact URL to the directory the file is stored in. When writing plugins, the best function to use for this is plugins_url(). Assuming our custom.js file exists inside of a folder called js that is in our plugin’s main folder, the exact function will look like this:

plugins_url( 'js/custom.js' , dirname(__FILE__) )

Add this into our function and we have this:

1
2
3
4
function pw_load_scripts() {
	wp_enqueue_script( 'custom-js', plugins_url( 'js/custom.js' , dirname(__FILE__) ) );
}
add_action('admin_enqueue_scripts', 'pw_load_scripts');

This is getting much closer to being correct, but we still have the problem of our script being loaded on all pages. How do we take care of that?

Luckily, the admin_enqueue_scripts hooks allows us to pass a variable called $hook to our pw_load_scripts() function. This $hook will contain the name, or hook, of the current admin page, which we can then use to conditionally load our scripts.

For this first example, let’s assume that we want to load some extra JS into the edit.php page, which is the primary page/file loaded when viewing a list of any post type, such as the Posts or Pages page.

1
2
3
4
5
6
7
8
function pw_load_scripts($hook) {
 
	if( $hook != 'edit.php' ) 
		return;
 
	wp_enqueue_script( 'custom-js', plugins_url( 'js/custom.js' , dirname(__FILE__) ) );
}
add_action('admin_enqueue_scripts', 'pw_load_scripts');

This says the following: “if we are NOT on the edit.php page, get out of here and do not continue this function”, which means that our “custom.js” file will only be loaded if we ARE on the edit.php page. Pretty cool right?

What about some of the other pages? Perhaps you want to load scripts anytime a post list, a new post, or an edit post page are displayed? Then we can do this:

1
2
3
4
5
6
7
8
function pw_load_scripts($hook) {
 
	if( $hook != 'edit.php' && $hook != 'post.php' && $hook != 'post-new.php' ) 
		return;
 
	wp_enqueue_script( 'custom-js', plugins_url( 'js/custom.js' , dirname(__FILE__) ) );
}
add_action('admin_enqueue_scripts', 'pw_load_scripts');

You can do the same thing for any page in the WordPress admin, and here is a list of some of the other pages:

  • index.php – the Dashboard
  • upload.php – the Media library
  • link-manager.php – the Links page
  • edit-comments.php – the Comments list page
  • comment.php – editing a specific comment
  • themes.php – Appearance
  • widgets.php – Appearance > Widgets
  • nav-menus.php – Appearance > Menus
  • plugins.php – Plugins
  • users.php – Users
  • options-general.php – Settings > General
  • options-writing.php – Settings > Writing

Most pages are named pretty straight forward, so it’s easy to figure out which files display which pages, but what about custom admin pages? Many (if not most) plugins create custom settings pages in the WordPress admin. How do we go about only loading JS files on those pages? It’s actually quite easy. There are multiple ways to do it actually, but the way I want to show you also assumes you have created your settings page correctly.

Settings pages are created like this:

1
2
3
4
5
function pw_create_settings_page() {
	global $pw_settings_page;
	$pw_settings_page = add_options_page(__('My Plugin Settings', 'my-domain'), __('Plugin Settings', 'my-domain'), 'manage_options', 'my-page-slug', 'pw_callback_function');
}
add_action('admin_menu', 'pw_create_settings_page');

The settings page is stored in a global variable called $pw_settings_pages (yours will be named differently). This variable will then be equal to the $hook variable in our admin_enqueue_scripts function, and since it is a global variable, we can access it, like so:

1
2
3
4
5
6
7
8
9
10
function pw_load_scripts($hook) {
 
	global $pw_settings_page;
 
	if( $hook != $pw_settings_page ) 
		return;
 
	wp_enqueue_script( 'custom-js', plugins_url( 'js/custom.js' , dirname(__FILE__) ) );
}
add_action('admin_enqueue_scripts', 'pw_load_scripts');

We have now successfully loaded our custom script into our plugin’s settings page AND avoided loading it anywhere else within the WordPress admin. Awesome.

The process itself is quite simple and there is not a single reason you shouldn’t be doing it this way.

Tweet Follow @pippinsplugins
admin_enqueue_scripts, jquery, wp_enqueue_script, wp_enqueue_scripts

23 comments on “Loading Scripts Correctly in the WordPress Admin”

  1. Ben Voran says:
    May 23, 2012 at 11:16 am

    Hi Pippin, I’m curious if this theme, http://www.rootstheme.com/ which I use frequently is subject to this jQuery loading issue. It looks like there is something going on in regards to sniffing out the admin pages… But I figured you’d be able to tell quickly!

    Reply
    • Pippin says:
      May 23, 2012 at 6:04 pm

      After exploring the source code on Github, I don’t see anything. Doesn’t actually look like it loads a single script in the admin :)

  2. paul says:
    June 16, 2012 at 12:08 pm

    how do you load the script only on a specific post type edit/new screen?

    Reply
    • Pippin says:
      June 16, 2012 at 12:48 pm

      Inside of your function hooked to “admin_enqueue_scripts”, use something like this:

      1
      2
      
      if( ( !isset($post) || 'YOUR POST TYPE' != $post->post_type )
           return;

      That will make it so only the scripts below that line will get loaded if you are on the post type “YOUR POST TYPE”.

    • bali50 says:
      December 13, 2012 at 3:05 pm

      Tried the code below Pippin but it didn’t work. I removed the extraneous opening bracket “(” after the if, but still didn’t work. But when I called the global $post it worked fine.

      global $post;
      if ( !isset($post) || 'product' != $post->post_type )
      return;

    • Pippin says:
      December 13, 2012 at 6:24 pm

      Doesn’t work in what way? Can you elaborate?

    • Bali Rakhra says:
      December 13, 2012 at 7:46 pm

      Maybe I was doing something wrong, but I added it to my plugin’s main file as a conditional to load my JS scripts, however the scripts failed to load. But then, by adding the call to the global $post variable first, your code worked, and my scripts loaded just fine. So I’m not sure if everyone has to call the global first, or if it’s just something peculiar to my own set up, but that’s the only way it would work for me.

      My full script is this:

      // check if in Admin section AND on Edit-Post page (post.php).
      if( !is_admin() || $hook != 'post.php' )
      return;
      // now check to see if the $post type is 'product'
      global $post;
      if ( !isset($post) || 'product' != $post->post_type )
      return;
      wp_enqueue_script(........

    • Pippin says:
      December 15, 2012 at 7:01 pm

      Anytime you reference $post (except inside of a loop), you must set the global.

    • Bali Rakhra says:
      December 15, 2012 at 10:29 pm

      Cheers Pippin – and my apologies if my comment was too ‘obvious’, I’m not that far up the learning curve yet! Thanks again for all you do!

  3. Aj Clarke says:
    August 13, 2012 at 11:20 am

    Thanks for this Pippin. The method I was using before was not nearly as clean and straight forward as using the $hook variable. This is great!

    Reply
  4. casas en venta says:
    September 11, 2012 at 4:32 pm

    excellent scripts, I hope I serve to my projects

    Reply
  5. Wordpressor says:
    January 29, 2013 at 7:11 pm

    Just out of curiosity, what was wrong with admin_print_styles-$page? The only difference between the old way of enqueing and admin_enqueue_scripts is using global variables for custom options and theme pages, which is, pure evil I guess?

    Reply
  6. Wordpressor says:
    January 29, 2013 at 7:31 pm

    Oh, I’ve also checked wp_print_styles() and looks like it got replaced with wp_enqueue_scripts() too! Naming is a bit confusing, but it’s still better to have one action, than two separate ones for js and css.

    Cheers!

    Reply
  7. Josh Kurz (@JoshKurz) says:
    February 14, 2013 at 3:56 am

    great post, Im just wondering one thing. The examples show how to not load pages on optional admin pages, but what about random posts and pages that are not admin which use the shortcode or a widget call to the plugin.

    I would like to only load the scripts and css on certain non admin pages.

    I understand this is not what the post is about, but I cant seem to find the answer and this is the most thorough post I have seen on this issue.

    Reply
    • Pippin says:
      February 14, 2013 at 11:16 am

      Saw your comment over here: http://pippinsplugins.com/load-scripts-if-post-has-short-code/comment-page-1/#comment-57401

  8. Aman says:
    March 5, 2013 at 7:02 am

    I have a question.
    Suppose I have plugin which make some changes to the frontend of my blog using javascript and my javascript code requires jquery. How should I load properly the javascript code. Some themes enque them but not all, so whats the best method do do it it from a plugin.

    Reply
    • Pippin says:
      March 5, 2013 at 8:23 pm

      The only proper way to do it is with wp_enqueue_script().

  9. Barry Laminack says:
    March 15, 2013 at 3:06 pm

    Hey Pippin – first of all thanks for this great site, I just found it last week and it’s awesome.

    I’m glad I found this post, but I can’t for the life of me get the last part to work on my Submenu page. It either works on all pages in the admin menu or none. It might be because of my design, but I don’t know.

    From my base plug-in page I install my table in the db and then call an adminmenu.php page.

    On the adminmenu.php page I create my main menu page (caling add_menu_page) then I create my submenu pages (calling add_submenu_page). Each of these calls a function that simply has an include of the PHP file with the page content.

    Here is some code if it helps -
    ===========================================================
    My base plugin page contains the following:
    if (is_admin () ){
    require_once( plugin_dir_path( __FILE__ ) . ‘includes/adminmenu.php’);
    }
    ===========================================================
    adminmenu.php page:

    //Create the Admin Menus system and content
    function bl_recp_admin_menu () {
    global $bl_recp_manageOptions_page;
    global $bl_recp_clientManager_page;

    //CREATE MAIN MENU
    $bl_recp_manageOptions_page = add_menu_page( ‘RE Client Portal Settings’, ‘RE Client Portal’, ‘manage_options’, __FILE__, ‘bl_recp_settings_content’, plugins_url(‘/images/icon_arrow.gif’,plugin_dir_path( __FILE__ )) );

    //Create “Manage Clients” Sub Menu
    $bl_recp_clientManager_page = add_submenu_page( __FILE__, ‘RE Client Portal – Client Manager’, ‘Manage Clients’, ‘manage_options’, __FILE__.’_client_manager’, bl_recp_manageclients_page);
    }

    //Call the General Setting Page HTML
    function bl_recp_settings_content () {
    //Add the HTML
    include( plugin_dir_path( __FILE__ ) . ‘general_settings.php’);
    }
    //Call the Manage Clients Page HTML
    function bl_recp_manageclients_page () {
    //Add the HTML
    include( plugin_dir_path( __FILE__ ) . ‘client_manager.php’);
    }

    add_action(‘admin_menu’, ‘bl_recp_admin_menu’);
    ===========================================================

    client_manager.php has all the form data and other html. I need the script to run on the file, so using this tutorial this is what I have done:

    I added the following to the adminmenu.php file:

    function bl_recp_load_scripts() {

    global $bl_recp_clientManager_page;

    if( $hook != $bl_recp_clientManager_page )
    return;

    wp_enqueue_script(‘recp-client-insert-js’, ‘/wp-content/plugins/js/test_client_insert.js’, ”, ’0.0.1a’);
    }
    add_action(‘admin_enqueue_scripts’, ‘bl_recp_load_scripts’);

    ===========================================================

    As is it doesn’t load the script on ANY page , but if I comment out the global line, the if($hook line and the return line the script loads…it just loads on every page.

    Any ideas? I want to do this write, but I need to move on and I’ve spent 2 days trying to figure this out.

    Thanks again, being brand new to WP Plugin development, your site has already helped me a tone.

    Reply
    • Pippin says:
      March 17, 2013 at 8:33 pm

      Can you post the code to snippi.com and share the link? That way the formatting remains.

  10. Barry Laminack says:
    March 17, 2013 at 11:49 pm

    Of course. Here is the link: http://snippi.com/s/0naubgv

    Reply
    • Pippin says:
      March 22, 2013 at 4:48 pm

      I see the problem. Change

      function bl_recp_load_scripts() {

      to

      function bl_recp_load_scripts( $hook ) {
  11. Barry Laminack says:
    March 25, 2013 at 11:16 pm

    That was it. Thanks!

    Reply
    • Pippin says:
      March 26, 2013 at 9:56 am

      Great!

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

  • Login

Lost your password?

Please enter your username or e-mail address. You will receive a new password via e-mail.

  • Facebook Become a Fan Like

  • Twitter Subscribe on Twitter Follow

  • YouTube Follow my Videos Subscribe

  • RSS Feed Subscribe with RSS Subscribe

Easy Digital Downloads

Most Loved

  • Love It Pro for WordPress
  • Write a “Love It” Plugin with Ajax to Let Users Love Their Favorite Posts / Pages
  • Simple Notices Pro Plugin for WordPress
  • User Bookmarks for WordPress
  • Front End Registration and Login Forms Plugin

Similar Plugins and Posts

  • Ensure Your Scripts and Styles Are Not Cached with Updates
  • Using Ajax in Your Plugin and WordPress Admin
  • Use wp_localize_script, It Is Awesome
  • Create a Live Search in WordPress with jQuery and Ajax
  • Review: Cudazi Scroll to Top

Latest Premium Content

  • Plugin Development 101 – Introduction to Adding Dashboard Menus
  • Plugin Development 101 – Intro to Loading Scripts and Styles
  • User Follow System – Part 5
  • Plugin Development 101 – Intro to Short Codes
  • Plugin Development 101 – Registering a Custom Post Type
  • Plugin Development 101 – Intro to Actions

Latest Tutorials

  • Test Your Plugins with RTL (0)

    Right-To-Left languages are those that...

  • Submitting Your First Pull Request to a WordPress Plugin on Github (5)

    Github is an extremely popular tool for managing WordPress plugins, and one...

  • Plugin Development 101 – Introduction to Adding Dashboard Menus (1)

    Adding new menus, both top level and sub level, to the WordPress Dashboard is a really common task for plugins...

Enter your email to receive automated updates when new posts are published

Latest Tweets

  • @corymiller303 I hope everything with the surgery went well!
    May 25, 2013
  • RT @strickland: To celebrate Memorial Day weekend @gittyapp is on sale through Monday. Now is the time to join in! http://t.co/vOAqksLLrN
    May 25, 2013
  • RT @GaryJ: Premium theme sellers: consider spending 30mins to add an rtl.css to your themes, to considerably open up your potential market.
    May 25, 2013

Topics

register_setting contextual help attachments add_shortcode hook featured campaign monitor wp_enqueue_script Rémi Corson shortcodes the_content get_user_meta Sugar Event Calendar plugin authors attachment image forms login short codes do_action Related posts mail chimp comments recent posts post types apply_filters bbpress short code taxonomies custom post type gallery Ajax images Stripe taxonomy jquery users widgets add_filter easy content types add_action widget restrict content pro easy digital downloads

Weekly Newsletter

Useful Links

  • Join the Site
  • Plugin Store
  • Affiliate Area
  • Tag Index
  • Support the Site
  • Suggest a Tutorial
  • Random Post
  • Contact

Monthly Archives

(c) 2013 Pippin's Plugins