The plugins_loaded
hook is too early in the WordPress event sequence and it is even before the theme features. That would be one line causing the warning in the log.
The WordPress 6.8.2 source code for _load_textdomain_just_in_time()
is hardcoded to log a warning of anyone (themes & plugins) try to use language translation before the after_setup_theme
hook.
Research also seems to strongly recommend leaving all language translation setup using load_theme_textdomain()
& load_plugin_textdomain()
until the init
hook.
function my_theme_setup_7() {
load_theme_textdomain('mytheme', WP_LANG_DIR . '/themes');
}
add_action('init', 'my_theme_setup_7', 7);
function my_theme_setup_8() {
register_nav_menus( array(
'topbar' => esc_html__( 'Topbar', 'mytheme' ),
'primary' => esc_html__( 'Primary', 'mytheme' ),
'base' => esc_html__( 'Base Menu', 'mytheme' ),
...
[rest of setup]
}
add_action('init', 'my_theme_setup_8', 8);
- Try using the
init
hook for all international language setup.- This will remove the ‘too early’ warning message from the log.
- As you say, deferring
load_theme_textdomain()
further down the event sequence introduces a race-war problem of dependant theme functionality. Specifically, the delima of the theme hooks then mostly only being used to create deferred callbacks, while intentionally leaving the theme partially unconfigured until the ‘init’ hook. It is an uncomfortable idea, especially if we were wanting to have ALL the theme stuff done only in the theme hooks.
- Try using
init
hook with a priority higher than the default 10 (like 1 to 9) so that when all the ‘init’ actions are executed, the higher prioroty ones are done first.- Like ‘init’ hook priority 7 for all pre-requisite actions, like
load_theme_textdomain()
&load_plugin_textdomain()
. - Then ‘init’ hook priority 8 & 9 to do all other dependant activities to complete the theme initialisation; like
register_nav_menus()
. Also, the WordPress user is fully initalised just before ‘init’, so your theme has access to user specific details for a more customised user experience (if your theme is personalising). - That way, the theme is officially configured and fully setup just before the default ‘init’ priority 10.
- Like ‘init’ hook priority 7 for all pre-requisite actions, like
Hint – The code sample above is intentionally not using an anonymous function, because they block other possible down-stream actions like remove_action().
Disclaimer This is one approach that works. I have not found any negative consequences, yet. This appears to play very nicely with all the other themes and plugins I use … but there are more experienced developers here that might have a better idea and/or improvements to expand this approach.