Enqueueing Scripts on a Custom Top-level Menu Page

I’ve created a menu page using the following function:

add_menu_page(
'Nonpareil options',
'Nonpareil options',    
'administrator',    
'nonpareil_theme_options',  
'nonpareil_theme_display'   
);

Now I want to load a js file only on this page. I’m trying to do so properly by enqueueing it only on my new page:

Read More
function nonpareil_options_js_enqueue($hook_suffix) {
    if( 'nonpareil_theme_options' != $hook_suffix )
    return;
    wp_enqueue_script( 'nonpareil-options', get_template_directory_uri().'/js/nonpareil-options.js', array('jquery') );
}       
add_action( 'admin_enqueue_scripts', 'nonpareil_options_js_enqueue' );

The script is not being enqueued. I think the issue is probably that $hook_suffix != “nonpareil_theme_options” on my new page, but in that case I have no idea what to put instead. What’s wrong here?

Thank you!

Related posts

Leave a Reply

2 comments

  1. You could try replacing

    if( 'nonpareil_theme_options' != $hook )
    

    with

    if( 'toplevel_page_nonpareil_theme_options' != $hook )
    

    if you have the custom menu added like this:

    add_action('admin_menu', 'register_custom_menu_page');
    function register_custom_menu_page() {
        add_menu_page('Nonpareil options','Nonpareil options',    'administrator',    'nonpareil_theme_options',  'nonpareil_theme_display'   );
    }
    

    Edit:

    It looks like you are using this admin_enqueue_scripts example in the Codex:

    http://codex.wordpress.org/Plugin_API/Action_Reference/admin_enqueue_scripts#Example:_Target_a_Specific_Admin_Page

    so in your case the Codex example would be like this:

    function nonpareil_options_js_enqueue($hook) {
        if( 'toplevel_page_nonpareil_theme_options' != $hook )
        return;
        wp_enqueue_script( 'nonpareil-options', get_template_directory_uri().'/js/nonpareil-options.js', array('jquery') );
    }       
    add_action( 'admin_enqueue_scripts', 'nonpareil_options_js_enqueue' );
    

    In the file /wp-admin/admin-header.php you have the following

    do_action('admin_enqueue_scripts', $hook_suffix);
    do_action("admin_print_scripts-$hook_suffix");
    do_action('admin_print_scripts');
    

    so you can see the difference, admin_print_scripts doesn’t take input, but admin_enqueue_scripts does (and this is the filter you are using in your code example).

    If you wonder where toplevel_page_ comes from, you can check out the source code for get_plugin_page_hookname() since it is generating the value for $hook_suffix in your case.

    Conclusion:

    Add toplevel_page_ in front of your menu slug.

  2. You can’t just import a particular variable into an action by naming it in the callback function. The variable imported, if available, is the variable supplied when the do_action function for that hook name runs. What you call that variable inside your callback function is irrelevant.

    admin_print_scripts does not pass a variable at all. You can prove this to yourself with this disposable function (which will break stuff):

    function apx($a) {
     var_dump($a); die;
    }
    add_action('admin_print_scripts','apx');
    

    Again, that will break the site. You will have to remove the function (or at least the die part of it) before the admin pages will work again. I work on a development server so that is not a problem for me.

    admin_enqueue-scripts does pass a variable, and what you are trying to do should work but requires additional logic in the function whereas doing the following does not. The logic is handled by the hook itself.

    1. Visit the page you want the script enqueued on
    2. View source for the page in your browser
    3. Near the top there is some embedded Javascript.
    4. Inside that Javascript look for pagenow = 'some_string_resembling_the_page_slug'
    5. Enqueue on a hook named admin_print_scripts-some_string_resembling_the_page_slug

    In your case something like:

    function nonpareil_options_js_enqueue($hook) {
        wp_enqueue_script( 'nonpareil-options', get_template_directory_uri().'/js/nonpareil-options.js', array('jquery') );
    }       
    add_action( 'admin_print_scripts-some_string_resembling_the_page_slug', 'nonpareil_options_js_enqueue' );