1

I have a question on the following code at https://developer.wordpress.org/plugins/plugin-basics/activation-deactivation-hooks/#example

function pluginprefix_setup_post_type() {
    // register the "book" custom post type
    register_post_type( 'book', ['public' => true] );
}
add_action( 'init', 'pluginprefix_setup_post_type' );

function pluginprefix_install() {
    // trigger our function that registers the custom post type
    pluginprefix_setup_post_type();

    // clear the permalinks after the post type has been registered
    flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'pluginprefix_install' );

Why does pluginprefix_setup_post_type need to be called on both init and activation? I tried an example plugin, commenting out the call to pluginprefix_setup_post_type in pluginprefix_install and adding the label like the following.

function pluginprefix_setup_post_type() {
    // register the "book" custom post type
    register_post_type( 'book', ['public' => true, 'label' => 'Books'] );
}
add_action( 'init', 'pluginprefix_setup_post_type' );

function pluginprefix_install() {
    // trigger our function that registers the custom post type
    // pluginprefix_setup_post_type();

    // clear the permalinks after the post type has been registered
    flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'pluginprefix_install' );

And the code works fine too. I can see the Books in the Admin menu once I activate the plugin.

So what is the benefit of calling it twice?

1
  • When you say works fine you mean the permalink cache is set up correctly for the new type? I guess it's just being extra careful then in case the plugin activation code is called without the plugin being loaded in the original page load, because then it would miss the init hook.
    – Rup
    Apr 9, 2020 at 8:46

1 Answer 1

0

I think you're mistaken and the activation didn't work correctly: you won't have the new post type set up in the permalinks cache.

Here's activate_plugin() in 5.4. You can see the sequence is

  • wp-admin/plugins.php loads without the new plugin; init is triggered now
  • activate_plugin() PHP-includes the new plugin, loading it and registering its hooks; it's now too late for the plugin's init hook to be called
  • activate_plugin() calls the global activate_plugin hook
  • activate_plugin() calls the plugin-specific activate hook

So if you're relying on the init hook to register your post type in the activation case it won't have been called before flush_rewrite_rules(). Not that you'll see any errors here, but the new post type won't be set up in the permalink cache.

(That all is unless, on the very off chance you have an activate_plugin hook that triggers init, but that seems unlikely and definitely isn't the default.)

4
  • Hmm. Is there no way that one call is enough? It must be called twice?
    – Haibin Liu
    Apr 9, 2020 at 14:35
  • It's not called twice: when you're activating the plugin the register_activation_hook handler is called; once the plugin is activated, the init version will be called. They're never both called on the same page load.
    – Rup
    Apr 9, 2020 at 14:37
  • Thanks. I think I got it. Init is called for every request but activation is not. For activation hook, if I do not register the new post type, I don't even need to call flush_rewrite_rules(). Also we don't want to flush_rewrite_rules in init for every request.
    – Haibin Liu
    Apr 10, 2020 at 14:06
  • Yes, that's right: init is called on every page load after the plugin has been activated; the activation hook is only called once but this plugin's init won't have been called that time. Yes, the flush_rewrite_rules call is only needed if you're adding or removing a custom post type from the site (or something else that would affect routing) and it's meant to be called once as a setup step and then all future page loads will use cached routing rules.
    – Rup
    Apr 11, 2020 at 9:23

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.