DevinVinson / WordPress-Plugin-Boilerplate

[WordPress] A foundation for WordPress Plugin Development that aims to provide a clear and consistent guide for building your plugins.
http://wppb.io
7.67k stars 2.25k forks source link

Place for wp_enqueue_script #364

Closed Kivylius closed 8 years ago

Kivylius commented 8 years ago

Hi I just started using this plugin to better organise my code and I think its great but I have a problem. I need the javascript to only load on when the admin page is visible. How do I do this? Like I know all the add_menu_page() code but not sure where to put the wp_enqueue_script and wp_localize_script for ajax to work with this layout.

My current setup is class-name-admin.php

class Name_Admin {
    private $plugin_name;
    // ....

    public function enqueue_scripts() {
        wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'assets/js/name-admin.min.js', array( 'jquery' ), $this->version );
        wp_localize_script($this->plugin_name, $this->plugin_name+"_obj", array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
    }

    public function page_setup(){
        add_menu_page("name", "name", 'manage_options', $this->plugin_name, array( $this, 'show_page'));
    }

    public function show_page(){
       //TODO:  enqueue_scripts to load here
       // $this->enqueue_scripts(); // not working;
       // show_page -> page_setup -> Name::define_admin_hooks -> add_action -> Loader
       echo require "partials/name-admin-page.php"; 
    }
}

And the class-name.php

class Name {
    // ...
    private function define_admin_hooks() {
        $plugin_admin = new Name_Admin( $this->get_plugin_name(), $this->get_version(), $this->loader );
        $this->loader->add_action( 'admin_menu', $plugin_admin, 'page_setup');
    }
}
DevinVinson commented 8 years ago

The admin/js/plugin-name-admin.js is already only getting pulled into the admin side of things. See: https://github.com/DevinVinson/WordPress-Plugin-Boilerplate/blob/master/plugin-name/includes/class-plugin-name.php#L155

The script is loaded with admin_enqueue_scripts so it will be admin only.

It should be fine to keep wp_localize_script within the admin class though I don't think I've done that within the boilerplate now that I think about it. If you have the full plugin somewhere I can take a look at poke around.

Kivylius commented 8 years ago

I understand that admin_enqueue_scripts are fine for loading anywhere in wp-admin page, but the problem is that I have a separate page ('add_menu_page') app and I only want the js/css to load once that page is selected.

According to the official documentation, the enqueue_scripts should be called withing the add_menu_page callback witch is show_page in my example:

class Name_Admin {
    // ....

    public function enqueue_scripts() {
        wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'assets/js/name-admin.min.js', array( 'jquery' ), $this->version );
        wp_localize_script($this->plugin_name, $this->plugin_name+"_obj", array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
    }

    public function page_setup(){
        add_menu_page("name", "name", 'manage_options', $this->plugin_name, array( $this, 'show_page'));
    }

    public function show_page(){
        $this->enqueue_styles();
        $this->enqueue_scripts();
    }
}

and the define_admin_hooks is now:

private function define_admin_hooks() {
        $plugin_admin = new Name_Admin( $this->get_plugin_name(), $this->get_version());
        $this->loader->add_action( 'admin_menu', $plugin_admin, 'page_setup');
}

This is almost perfect, the CSS/JS only loads on that specific page but no mater what I try, the wp_localize_script just does not work/fire, and I need this to do AJAX calls and Nonce. This is the only changes I made to your boiler plate as i'm switching to this.

DevinVinson commented 8 years ago

$this->plugin_name+"_obj" shouldn't work as far as I know for concatenation of the plugin name and _obj since php uses . and not a +.

Kivylius commented 8 years ago

I changed it to just a string "plugintester" and still: Uncaught ReferenceError: plugintester is not defined (browser console), however that a good notice.

Edit I have simplified the whole plugin to not even use the loader class but yet still its not working so it maybe a bug or a programming error. I asked a question over at stack-overflow.

Edit2 The problem was my problem, the name of the wp_enqueue_script handle MUST be the same as the wp_localize_script handle according to this post on stackexhange.

DevinVinson commented 8 years ago

Ah there ya go. I'm worthless without being able to see the whole plugin at once typically :)