0

If I call register_post_type() before the init action, will my plugin explode in a ball of fire under some circumstances? Codex says:

register_post_type should only be invoked through the 'init' action. It will not work if called before 'init', and aspects of the newly created or modified post type will work incorrectly if called later.

Codex also says:

Note that you must call register_post_type() before the admin_menu and after the after_setup_theme action hooks. A good hook to use is the init hook.

Given this advice, I've always registered my CPT on the init action. That's always worked well for me, until today, when I found a problem.

I have a plugin (not yet released anywhere) that logs emails. I use it extensively when testing. It registers a CPT, which it uses to store the email logs. All good so far. Today, testing an Easy Digital Downloads shop, I noticed that I was getting errors logged in debug.log, each time I inserted a new email log post. The error was caused by get_post_type_object() not finding my CPT, because EDD is sending emails before the init action.

So, after verifying that the doco and piles of other references including WPSE concur that "register_post_type should only be invoked through the 'init' action", I went ahead and changed my plugin to register on plugins_loaded. Note that this action precedes the after_theme_setup action, so I'm violating both of the above Codex excerpts.

Am I OK doing this, or will I strike some problem under some circumstances?

BTW, when I dump the contents of $wp_post_types on plugins_loaded, it already has all the standard WordPress post types defined...

Edit: OK, I'm dumb, EDD isn't sending emails out before init, I just needed to increase my hook's priority to beat it -- now hooking init at priority 1. But the question still stands...

1

The short answer is no. For the canonical example of why just take a look at native post types. They are registered twice during each page load:

  1. Quite early because of backwards compatibility reasons and plugins possibly expecting them to exist.
  2. On init because now locale things are actually loaded and post type definitions can be properly translated.

So long answer is — you can make it work, but you are in a world of pain and poor performance to make it happen properly. Just don't. :)

  • 1
    For completeness, translations also should be loaded on init, because locale can be filtered and the effective locale can differ from whatever WP_LANG is set to in wp-config.php. Translations can actually be loaded before init, but might get the wrong locale. Which raises another interesting point, translations should be loaded before CPT are registered, and both should happen on init... :) – webaware Jul 19 '14 at 22:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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