Software, Development, and WordPress

The WordPress Register Activation Hook

For those of you who have been following development of the WordPress Plugin Boilerplate, you’ll recall that I previously included the `register_activation_hook` and `register_deactivation_hook` calls within the the class itself.

In the latest version of the Boilerplate, they’ve been removed outside of the context of the class and into a separate file. Last week, I received a great comment asking why this decision was made:

I have this one question – why plugin activation/deactivation hooks are registered outside the constructor (as they were in v1.0) ?

I thought it would be better to discuss the decision in a blog post rather than in a lengthy comment.

The WordPress Register Activation Hook Function

There are two ways that I can go about explaining my particular implementation.


I’m handling the activation and deactivation hooks outside of the plugin class because I’ve opted to implement the Singleton Pattern, which requires a different strategy.

The Long Version

First, according to the Codex, the `register_activation_hook` is meant to provide the following functionality:

The register_activation_hook function registers a plugin function to be run when the plugin is activated.

And the `register_deactivation_hook` is meant to provide similar functionality:

The function register_deactivation_hook (introduced in WordPress 2.0) registers a plugin function to be run when the plugin is deactivated.

Sure, it’s easy enough to understand – but there are some subtle nuances that come with working with these two functions.

Primarily, they expect that the functions are marked as static and their use depends on if you’re using object-oriented programming or procedural programming.

Yes, it’s completely possible – and acceptable – to keep the plugin activation and deactivation functions within the class, and it’s possible to specify the hooks in the constructor; however, because the second version of the Boilerplate places the class in a separate file, because the Boilerplate implements the Singleton Pattern, and because I’m using a secondary file to grab an instance of the plugin, I opted to place the register activation and deactivation hooks out of the constructor.

Straight from the Codex, here’s their example::

class MyPlugin {
     static function install() {
            // do not generate any output here
register_activation_hook( __FILE__, array('MyPlugin', 'install') );

But there’s a subtly to this example and the Boilerplate and that’s that the plugin class is in one file, and the plugin is loaded by a secondary file.

To that end, I’m following the strategy above except I’ve placed the call to `register_activation_hook` in a separate file that invokes the static activation (or deactivation) functions.

So, ultimately, it’s not an arbitrary design decision. Instead, it’s more of a function of the implementation of the Singleton Pattern which is better covered in the topic of a series of different posts.


  1. John Saddington

    what, no img tags? BAH!

  2. Charlie

    With havin so much written content do you ever run into any issues of plagorism or copyright infringement? My site has a lot of exclusive content I’ve either authored myself or outsourced but it seems a lot of it is popping it up all over the web without my agreement. Do you know any solutions to help protect against content from being ripped off? I’d certainly appreciate it.

    • Tom McFarlin

      I’ve run into a few problems where people have copied articles verbatim, but honestly, I’ve never had that big of an issue with it.

      General recommendations that I have:

      • Append some type of unique footer message in RSS that reads “This blog first appears on [your blog].” with a link. That way, RSS scrapers will grab it, too.
      • Setup a Google Custom Search for certain keywords or things that you often talk about – or just your name, if it’s part of your blog – and have them email you whenever results come back.

      Other than that, I don’t sweat it too much. The way I see it – the information is free and people are going to always be out there copying stuff so, to me, it’s not worth the effort of trying to fight it.

      There’s only been a few times where I’ve had to email someone directly and basically issue a C&D to take down content. And in every case, people have been happy to comply.

  3. Damien

    Thanks for finally talking about >The WordPress Register Activation Hook <Loved it!

  4. Galen

    Pretty nice post. I just stumbled upon your blog and wished to say that I’ve truly enjoyed browsing your blog posts. After all I’ll be subscribing to your rss feed and I hope you write again soon!

  5. Janek

    Just wonder why activate/deactivate hooks are listed in Public-Facing Functionality instead of Administrative Functionality section.

    Also why functions: activate( $network_wide ), deactivate( $network_wide ),activate_new_site( $blog_id ) are located in public/class-plugin-name not admin/class-plugin-name class.

    Aren’t the plugins activated from the admin dashboard?

    • Tom McFarlin

      This is a good point! Will be adding this as an issue for the upcoming milestone :).

  6. kilbot

    Hi Tom, thanks for your great WP Plugin Boiler Plate, it’s helped me a lot to learn about good WordPress practise (and good OOP practise). I’m wondering why you chose to put the activate and deactivate methods in the public facing class, rather than in the admin class .. is there a reason they shouldn’t be moved into the administrative functionality?

    • Tom

      This is going to be changed a little bit in the upcoming version, but it’s placed in the public functionality for the time being because it’s something that affects what happens when the plugin is activated — this may or may not include data on the front end, you know?

      It can go in the administrative functionality just fine, so it was somewhat of an arbitrary decision.

      Good question :).

  7. Edison Silva Jr

    Error: The plugin generated 1868 characters of unexpected output during activation. If you notice “headers already sent” messages, problems with syndication feeds or other issues, try deactivating or removing this plugin.

    • Tom

      Normally when you see this message, it’s because something in your plugin is echoing data out or printing an error. Further debugging would need to be done to find the exact problem.

Leave a Reply

© 2020 Tom McFarlin

Theme by Anders NorenUp ↑