Đây là lỗi phổ biến nhưng ít được hiểu rõ khi phát triển plugin hoặc theme WordPress hỗ trợ đa ngôn ngữ. Mình sẽ viết cho bạn một bài kỹ thuật chuyên sâu, phân tích nguyên nhân, cách khắc phục, và những tình huống thực tế liên quan đến lỗi:
Nội dung lỗi
Notice: Function _load_textdomain_just_in_time was called incorrectly.
The text domain must be loaded before `get_translations_for_domain()` is called.
Hoặc bạn cũng có thể gặp phải thông báo lỗi:
Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the [...] domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in [...]/public_html/wp-includes/functions.php on line 6121
Hiểu đúng lỗi này nghĩa là gì?
WordPress báo rằng:
Bạn đang cố dịch một chuỗi (
__()
,_e()
,…) trước khi gọiload_textdomain()
hoặcload_plugin_textdomain()
, nên WordPress không thể tìm thấy bản dịch, và báo lỗi.
Cụ thể, get_translations_for_domain()
là hàm nội bộ của WP để lấy bản dịch từ .mo
tương ứng với textdomain
, nhưng textdomain chưa được load, nên hệ thống không có bản dịch để dùng.
Ví dụ gây lỗi
Ví dụ sai:
echo __('Chào bạn', 'my-plugin'); // ← bị gọi quá sớm
add_action('plugins_loaded', function () {
load_plugin_textdomain('my-plugin', false, dirname(plugin_basename(__FILE__)) . '/languages');
});
→ Ở đây, bạn gọi hàm dịch trước khi load textdomain ⇒ gây lỗi Function _load_textdomain_just_in_time
.
Cách khắc phục đúng chuẩn
Luôn gọi load_plugin_textdomain()
trước khi dịch
add_action('plugins_loaded', function () {
load_plugin_textdomain('my-plugin', false, dirname(plugin_basename(__FILE__)) . '/languages');
});
Sau đó mới dùng:
echo __('Chào bạn', 'my-plugin');
Vị trí đúng để đặt load_plugin_textdomain
Trong file plugin chính (ví dụ my-plugin.php
), viết như sau:
defined('ABSPATH') || exit;
/*
Plugin Name: My Plugin
Text Domain: my-plugin
*/
add_action('plugins_loaded', 'my_plugin_load_textdomain');
function my_plugin_load_textdomain() {
load_plugin_textdomain('my-plugin', false, dirname(plugin_basename(__FILE__)) . '/languages');
}
Không nên đặt trong init
hoặc gọi sớm ở global scope.
Đối với theme thì sao?
Sử dụng load_theme_textdomain()
trong after_setup_theme
:
add_action('after_setup_theme', function () {
load_theme_textdomain('my-theme', get_template_directory() . '/languages');
});
Checklist kiểm tra nếu bạn gặp lỗi:
Hạng mục | Đã làm? |
---|---|
Dùng __() , _e() , _x() đúng cách? | ✅ |
Đặt đúng Text Domain trong header plugin? | ✅ |
Gọi load_plugin_textdomain() trong plugins_loaded ? | ✅ |
Gọi dịch sau khi load textdomain? | ✅ |
Dịch đang gọi từ một file include sớm (cẩn thận)? | 🔍 cần kiểm tra |
Tình huống thực tế dễ sai:
Tình huống 1:
// hello.php
echo __('Hello!', 'my-plugin'); // bị gọi sớm!
Cách xử lý đúng:
→ Đảm bảo chỉ gọi trong shortcode/hook, ví dụ:
add_shortcode('hello', function () {
return __('Hello!', 'my-plugin');
});
Cấu trúc thư mục plugin đúng chuẩn hỗ trợ đa ngôn ngữ:
my-plugin/
├── my-plugin.php
├── languages/
│ └── vi.mo
├── includes/
│ └── hello.php
Cách test lỗi này có còn hay không:
- Bật WP_DEBUG = true trong
wp-config.php
- Vào trang sử dụng shortcode hoặc gọi
__()
- Không thấy thông báo
Notice: Function _load_textdomain_just_in_time
nữa là đã ok 👌
Tóm tắt xử lý lỗi _load_textdomain_just_in_time
:
Việc cần làm | Mô tả |
---|---|
Gọi load_plugin_textdomain() đúng thời điểm | Dùng plugins_loaded hook |
Không dịch sớm quá | Không gọi __() ở ngoài hook, hoặc global scope |
Dùng đúng Text Domain | Phải khớp trong file .po , plugin header |
Đặt file .mo đúng thư mục | /languages/ trong plugin |
Kết luận
Luôn load textdomain trước khi dịch
Không bao giờ echo__()
ở global scope nếu plugin chưa sẵn sàng
Thảo luận