The Plugin_Name_Loader class of the WordPress Plugin Boilerplate is very useful if you must hook into a WordPress action or filter from your plugin. The original author, Tom McFarlin, says the following about the loader:

The goal of this file is to encapsulate the registration of hooks and then execute both actions and filters at the appropriate time when the plugin is loaded.

It is often necessary to hook into the appropriate action or filter, so how does one take advantage of the plugin boilerplate's loader class and use it to hook into actions and filters?

1 Answer 1


This answer assumes a basic understanding of working with classes and objects. The complete answer is a bit long, so skip down to the checklist summary at the bottom if you're impatient. Read and follow the entire answer if you don't understand the summary.

In order to understand how to use the loader, we should look at the source for the core plugin class, Plugin_Name in class-plugin-name.php.

The first block of code in this class declares the private container $loader:

protected $loader;

Next, we see within the construct that the functions load_dependencies and define_public_hooks() are called:

public function __construct() {
    $this->plugin_name = 'plugin-name';
    $this->version = '1.0.0';
    // Our fearless loader is called from within this class object.

Following the construct, we see the function load_dependencies() defined. Here is where the resource files for classes used by the plugin are called. The first class resource file we see being required here is plugin-name-loader.php.

require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-plugin-name-loader.php';


Require any additional class files your plugin relies on within the load_dependencies() function.

For example, if you have defined a class called Plugin_Name_Alert in the file class-plugin-name-alert.php located in the includes directory of your plugin, require it by adding this line to load_dependencies():

require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-plugin-name-alert.php';

The first step is done.

Continuing our examination, we see that at the end of this function, our earlier declared container called $loader is now defined as a new object of the class Plugin_Name_Loader, which it can do now because it was just required earlier in this function:

$this->loader = new Plugin_Name_Loader();

Now let's skip down and take a look at define_public_hooks(). This is another function that was called from the construct earlier. This is a great place to organize hooks used by your plugin. Here's how it looks:

private function define_public_hooks() {
    // Instantiates a new object of the class Plugin_Name_Public.
    $plugin_public = new Plugin_Name_Public( $this->get_plugin_name(), $this->get_version() );
    // This is where the loader's add_action hooks the callback function of the class object. 
    $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' );
    // Another action is passed to the class object.
    $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' );

You can see two important things going on here:

  1. An object of a class is instantiated.

  2. The loader's custom version of add_action() is performed which accepts the object as an argument.

This is where the loader becomes useful for us. Instead of passing just the hook and callback function to add_action(), the loader uses it's own custom add_action() and add_filter() functions which allow us to pass three arguments: hook, class, and callback function. This way it knows how to find the function in your class.

While it seems more convoluted it standardizes the addition of hooks completely, splitting them into two distinct groups in the process. WordPress Plugin Boilerplate splits hooks into admin/public groups but that’s not all. It splits all your code in the same way by asking you to write public-facing code in the public folder and admin-facing code in the admin folder.

For reference, here are all of the arguments accepted by the loader's version of add_action():

add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 )

While there are ways to pass a class function to the WordPress add_action() or add_filter(), this is how you do it through the boilerplate's loader.


Within the function define_public_hooks(), you will repeat the two steps we just examined. Remember, we can only do this because earlier we required our class file for Plugin_Name_Alert.

1. Instantiate an object of your class:

$plugin_alert = new Plugin_Name_Alert();

2. Use the loader's add_action() to hook a function of $plugin_alert:

$this->loader->add_action( 'init', $plugin_alert, 'my_alert_function' );

That is all. Here is a checklist to make sure you've done everything you need to.

Checklist Summary

0. Create your class. In the above example it was defined as Plugin_Name_Alert at includes/class-plugin-name-alert.php. Here's a very simple class you can use for testing which we'll use to display an alert message every time WordPress initializes:


class Plugin_Name_Alert {

    public function my_alert_function() {
        ?> <script>alert("VAE VICTIS!");</script> <?php


1. Require your class within the load_dependencies() function. This example used: require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-plugin-name-alert.php';

2. Instantiate an object of your class within the function define_public_hooks(). Here was the example:
$plugin_alert = new Plugin_Name_Alert();

3. Lastly, hook the function from your class to an action or filter. Do this within define_public_hooks(). Here was the example:
$this->loader->add_action( 'init', $plugin_alert, 'my_alert_function' );

  • Why is using a loader in this way superior to registering the hook within the Plugin_Name_Alert class? Jan 15, 2021 at 11:51
  • Danny, thanks for the question. I have updated the answer to include a quote to briefly explain why the boilerplate does things this way. More can be found at codeinwp.com/blog/the-wordpress-plugin-boilerplate-101
    – iyrin
    Feb 9, 2021 at 11:36
  • This is a very well documented answer. Thank you for sharing. Jan 3 at 4:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.