In: , , , , ,
On: 2008 / 04 / 11
Shorter URL for this post: http://ozh.in/hk

Adding javascript into an admin page is a critical part of plugin coding. Critical, because it is both trivial and probably reason #1 why it will conflict with other plugins if not done properly. When their plugin needs javascript, Good Plugin Coders™ have to make sure of the following points:

  • add javascript only once: if you need prototype.js, don't add it if it's already included
  • add javascript only on your plugin page: don't load yourscript.js in every admin page (with hook 'admin_head') including on other's plugin pages.

Doing so is hopefully very easy :

Add javascript only once

Need to include a javascript library or an external script? Don't ever use some straight echo '<script src="prototype.js"></script>';. The script might have been already loaded already, so there's no point in adding it again. Moreover, it can break everything: just add prototype after jQuery and you're ready for some trouble.

Instead, use wp_enqueue_script() :

  1. wp_enqueue_script('prototype');
  2. wp_enqueue_script('myscript', '/wp-content/plugins/myplugin/myscript.js');
  3. wp_enqueue_script('theirscript', 'http://theirsite.com/script.js');

Even simpler, if your script needs, say, Scriptaculous to work, just use:

  1. wp_enqueue_script('myscript', '/wp-content/plugins/myplugin/myscript.js', array('scriptaculous') );

Usage:
wp_enqueue_script( [string: handle], [optional string: src], [optional array: dependencies], [optional string: version number])

There are a number of predefined script handles: 'jquery', 'prototype', 'scriptaculous' and a bunch of others. Please refer to wp_enqueue_script() on the Codex for more details.

Add javascript only to your page

Never ever simply hook into 'admin_head' to add your script: not only you will be adding it to every admin pages (the Dashboard, Comments, etc…) but also to every other plugin pages. Seriously, half of the support question I've had with Who Sees Ads were because of WP-ContactForm adding its crappy javascript everywhere it could, including my plugin page.

Instead of testing current page URL in order to determine if it's your plugin page with a smart strpos() over $pagenow or $_SERVER['REQUEST_URI'], you should use hook 'admin_print_scripts-(page_hook)'

Example with a plugin that would create an admin page under "Manage":

  1. $mypage = add_management_page( 'myplugin', 'myplugin', 9, __FILE__, 'myplugin_admin_page' );
  2. add_action( "admin_print_scripts-$mypage", 'myplugin_admin_head' );
  3.  
  4. function myplugin_admin_head() {
  5.     // what your plugin needs in its <head>
  6. }

This snippet from Andrew Ozz on the wp-hackers mailing list.

Complete Example

This simple plugin will create an admin page under "Settings" in which a CSS and a JS file will be loaded. Check other pages of the admin area: they won't be affected.

Download load-js-example.

Summary

Be nice to other plugin coders. Add your javascript properly and only where needed. Thanks :)

Shorter URL

Want to share or tweet this post? Please use this short URL: http://ozh.in/hk

Metastuff

This entry "How To: Load Javascript With Your WordPress Plugin" was posted on 11/04/2008 at 10:35 am and is tagged with , , , , ,
Watch this discussion : Comments RSS 2.0.

61 Blablas

  1. CLS says:

    Great post! It's the solution to a problem I was having just in these days.
    Thanks!

  2. Rick says:

    Great post full of wisdom words :)

  3. […] explains how to properly use JavaScript in your WordPress plugins. There are two key […]

  4. Adam Dempsey says:

    Ah thanks for that! Might explain the problems I've been having on one of my sites!

  5. […] WordPress. Go ahead, subscribe to our feed! You can also receive updates from this blog via email.Load Javascript With Your WordPress Plugin: Sage advice from a seasoned and proven plugin developer for WordPress. Ozh talks about some neat […]

  6. Barry says:

    I second the loading of JS files ONLY on your plugins page and if you have more than one page (a manage page and an options for instance then only load the required JS file for the page your user is on. I would like to add a call for selective loading of CSS style sheets as well – if only there was a wp_enqueue_css function…

  7. arena says:

    c'est justement ce que je suis en train de faire (sur le Dashboard en plus) un peu tricky mais j'y arrive !

    Aujourd'hui release du widget dashboard-last-news sur wordpress.org !!

  8. Khairil says:

    Nice!

  9. It's nice to keep it in mind as a personal developing tip, but I'd wonder if all plugin developers stick to this?!

    Thanks for it!

  10. Fausto Ponce says:

    Hi, I read this pos and I think it discribes what is happening to me with the podpress plugin and wordpress 2.5. When I activate the plugin I have an unresposive scritp whenever I want to write or edit eithe a post or a page…

    any sugestion?

  11. Yes thanks a lot Andrew, nice words of advice, I never knew about these till now (I'm not that into plugin developing)
    Cheers

  12. Ryan says:

    Thank you very much for this. I was wondering how to deal with this problem in a plugin I'm developing at the moment (it's in beta form at the mo) and had never heard of wp_enqueue_script.

  13. […] on 12 April 2008 by Mark Ghosh Load Javascript With Your WordPress Plugin: Sage advice from a seasoned and proven plugin developer for WordPress. Ozh talks about some neat […]

  14. Agel says:

    Excellent post. It's nice to keep it in mind as a personal developing tip, but I'd wonder if all plugin developers stick to this?

  15. […] How To: Load Javascript With Your WordPress Plugin (tags: wordpress) […]

  16. Rick says:

    BTW, it also valid for load specific CSS files (like archives and contact form pages plugins)

  17. Dhruva Sagar says:

    Hey thanks a ton for this info, this is a great post.

  18. […] Da PlanetOzh, come usare i tooltip di WordPress 2.5 per fornire informazioni utili, ed ancora come integrare JavaScript nei plugin WordPress. […]

  19. […] By PlanetOzh, how to use WordPress 2.5 tooltips to show useful info in your plugins, and how to load JavaScript code in your WordPress plugins. […]

  20. Matt says:

    Great post but how would this work with a plugin written as a class?

  21. Ozh says:

    Matt » This doesnt make a difference

  22. Matt says:

    I did some more tinkering and found that if I merged my 2 functions so that I had on action adding the admin pages and with this function the action calls to the scripts were made that things worked very nicely.

    Great tip and thanks for your help.

  23. Tom Stone says:

    Are all these tips deprecated in WP 2.5.1? I've struggled for 17 hours straight, but the only thing that works is the hook 'admin_head'.

    "admin_print_scripts-$mypage" results in absolutely nothing, and the same with "wp_enqueue_script". Most plugin authors seem to use the plain 'admin_head', and it seems they have a really good reason – to actually get the plugin to work.
    I've spend considerable time googling for any tutorial, or any readable and clear documentation, and there is none – which also seem to indicate that the advice given here isn't really supported by WP.

  24. Ozh says:

    Tom Stone » I really can't imagine how it's possible to waste 17 hours on this. I've updated this page with an example plugin doing just what's explained here, no more, no less. You could have found similar examples in literally *hundreds* of plugins.

  25. Tom Stone says:

    Weeell, I might have exaggerated a bit. I guess it really only was 15 hours. And it is my second plugin experiment ever.
    I'm very grateful for the download, which is the first really clear example I've seen. While there might be hundreds of plugins out there, doing it right, only two in my plugin-folder use "admin_print_scripts-", the rest adds everything to all admin pages.
    I'm not sure, but looking at your example, gives me the feeling that I might have attempted it in the wrong order, and that I tried to add something to the head too late, when the head was already assembled. Just guessing.

    As it turned out, the jquery color-picker I wanted to add didn't work in the admin page, so those hours was spent in vain in any case. Still, with your example, I now have a headstart, if I attempt something similar again.
    Thanks!

  26. DennisBB says:

    Good tutorial. Everything works in wp 2.5

  27. teo says:

    I want to put java script in a page created by my plugin.

  28. […] make the wp-config.php including fully WP 2.6 compliant, and I would make sure the javascripts are correctly added, those are my thoughts when looking at this plugin. I will definitely give this plugin a real […]

  29. Yustian says:

    Woow.. Good information. I will applying this technique into my blog.

  30. […] dependencies, such as the above mentioned jQuery, are handled correctly (further information about loading JavaScripts into WordPress plugins can be found on planetozh). The show_datagrid-function adds our specific Ext JS script (the […]

  31. Excellent post, Ozh, as always – exactly what I needed.

    I have a comment regarding loading CSS files in a similar fashion. I have a function enqueue_scripts() that does the CSS and JS enqueuing using wp_enqueue_script() and wp_enqueue_style().
    After I applied

    1. add_action("admin_print_scripts-$menu_page", array($this, 'enqueue_meta'));

    I only saw JS showing up in the head. After a bit of mucking around, I found that there's a admin_print_styles- hook that does exactly that. It's obvious but a bit of a tricky one to notice right away.

    So, really, they can both call the same function, like so:

    1. add_action("admin_print_scripts-$menu_page", array($this, 'enqueue_meta'));
    2. add_action("admin_print_styles-$menu_page", array($this, 'enqueue_meta'));

    Hope it helps someone.

  32. Just to clarify my last comment, as it may not have been clear enough.
    If you want to use this method for CSS, you HAVE TO USE the admin_print_styles-$menu_page hook, not the admin_print_scripts-$menu_page!! Now that I have your attention, go read the previous comment.

  33. […] in pratica. Vediamo il modo più semplice e veloce per farlo. In primis, vi ricordo che esiste un modo consigliato per caricare javascript sulle pagine di WordPress ed è la funzione wp_enqueue_script che, come vedete da link, richiede un […]

  34. Rune Jensen says:

    Cool post! It really helped me develop the admin panel and chart features for SpamTask. :)
    Thanks!

  35. Stephen R says:

    So, what's the difference between:

    1. admin_print_scripts-(page_hook)

    and

    1. admin_head-(page_hook)

    ?

  36. Henry says:

    Hello,

    first thanks for the post, it already helped a lot. Now I know how to properly load an external javascript file into the header of a specific page.

    Though a new problem arose from that: I defined some functions in my external javascript file, which need to be called when the DOM is ready. Usually jQuery provides the "ready" function for that purpose. But I don't want to put the "jQuery(document).ready(function() { });" code directly in the head, because this might cause trouble with other plugins (overriding). Any suggestions how to deal with that problem?

    Thanks for reading and thinking about it…

    Cheers
    Henry

  37. Ozh says:

    Henry » You can totally have several $(document).ready() and they won't override themselves.

  38. Henry says:

    @Ozh: Oh really?! That's good news :-) Thanks for the hint!

  39. bobsoap says:

    Thanks Ozh for yet another eye-opening post right when it was needed. Keep it up.

  40. mwaterous says:

    I tried searching google, poking through dashboard.php and even crossed my fingers and checked out what wp_add_dashboard_widget returned as a value, but to no avail.

    I have a plugin that I originally had done this with, until I added a dashboard widget. I'm curious if there's a hook I could use to load the styles on the dashboard, so I don't have to load them globally?

    The closest thing I turned up on google, was ironically this post.

  41. Theo Ephraim says:

    So this may sound stupid, but I've been searching now for a couple hours and can't figure it out.
    What is the RIGHT way to add CSS and JS to the header of the admin pages ONLY when displaying the page/post editing forms. Basically my plugin adds an extra meta box to the editing tools and they require some custom javascript/css files. I've really really digged and cant figure it out.

    After searching lots of places, and digging through the wordpress core, here's what I've come up. It works, but I REALLY hope I'm just overlooking something.

    1. add_action("admin_init", "hookAdminInit");
    2. function hookAdminInit(){
    3.   $editing = (substr($_SERVER['SCRIPT_NAME'], strlen($_SERVER['SCRIPT_NAME'])-8) == 'post.php' &amp;&amp; $_GET['action']=='edit' &amp;&amp; current_user_can('edit_post', (int) $_GET['post']) );
    4.   if ($editing){
    5.     wp_enqueue_style('myplugin', plugins_url('css/myplugin.css',__FILE__) );
    6.     wp_enqueue_script('myplugin', plugins_url('js/myplugin.js',__FILE__), array('jquery') );
    7.   }
    8. }

    Please let me know what you think. Thanks.

  42. Eric says:

    Helpful post, but not great by any means. You should edit this post to include Artem Russakovskii's comments in the actual post. Where you are telling people to echo the link tag in the header, the proper way to do it as Artem showed is to use the admin_print_styles-[name] action and wp_enqueue_style.

    Also, you incorrectly replied to Matt "This doesnt make a difference" with his question about how this changes when using a class — also addressed in Artem's comment by passing an array with a reference to the class instance to the wp_enqueue_[*] function.

  43. Rem says:

    Hi,

    Love this post, have been using this information with great success for my plugin development. I would need to ask a question though: in order to add Javascript or CSS to plugin pages only it is very easy indeed to do it with admin_print_scripts-(page_hook) when using functions like add_options_page() . What about if I am registering a new post type ( register_post_type() ) ?

    Thanks!

  44. Ozh says:

    Rem » there might be a more elegant & concise solution (I'll dig) but this is pretty good I think: load a custom JS on the write page of a custom post type 'my_cpt':

    1. add_action( 'load-post-new.php', 'ozh_insertjs_on_cpt' );
    2. function ozh_insertjs_on_cpt() {
    3.     global $current_screen;
    4.     if( $current_screen->post_type == 'my_cpt' );
    5.           wp_enqueue_script( 'ozh_cpt_js', 'http://bleh/script.js' );
    6. }
  45. Matthew Born says:

    This is exactly what I have been looking for. Thanks!

  46. Hi!

    Thanks for the info, i have found it very useful. Now i have a question.

    How do i add my scripts to the public pages containing my plugin only? so if only in one page/post my plugin is used, the plugin script will be added only on that page/post and nowhere else.

    Thanks,
    Anjan

  47. brasofilo says:

    cool, i was using some 'brute force' methods to avoid loading in pages where my plugin doesn't belong… now it's crystal clear, thX!

  48. Brian Hogg says:

    Rather than hard-coding the style HTML in the example, can use the admin_print_styles-$mypage hook instead. Something like:

    1. function ozh_loadjs_add_page() {
    2.     $mypage = add_options_page('Load JS Example', 'Load JS Example', 8, 'loadjsexample', 'ozh_loadjs_options_page');
    3.     add_action( "admin_print_scripts-$mypage", 'ozh_loadjs_admin_head' );
    4.     add_action( "admin_print_styles-$mypage", 'ozh_loadcss_admin_head' );
    5. }
    6.  
    7. function ozh_loadjs_admin_head() {
    8.     $plugindir = get_settings('home').'/wp-content/plugins/'.dirname(plugin_basename(__FILE__));
    9.     wp_enqueue_script('loadjs', $plugindir . '/example.js');
    10. }
    11.  
    12. function ozh_loadcss_admin_head() {
    13.     $plugindir = get_settings('home').'/wp-content/plugins/'.dirname(plugin_basename(__FILE__));
    14.     wp_enqueue_style('loadcss', $plugindir . '/example.css');
    15. }
  49. Steve B. says:

    Brian, instead of admin_print_style-, you might start moving toward using the admin_enqueue_scripts instead, according to the update to WP:

    http://wpdevel.wordpress.com/2011/12/12/use-wp_enqueue_scripts-not-wp_print_styles-to-enqueue-scripts-and-styles-for-the-frontend/

    Just a thought
    Steve

  50. Brian Hogg says:

    @ Steve

    Thanks for the heads up!

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
Gravatars: Curious about the little images next to each commenter's name ? Go to Gravatar and sign for a free account
Spam: Various spam plugins may be activated. I'll put pins in a Voodoo doll if you spam me.

Read more ?