Tính năngPluginGiáTài nguyên
Thay đổi ngôn ngữ
Tài nguyênDịch JSON của WordPress: Dịch JavaScript của Trình chỉnh sửa khối

Dịch JSON của WordPress: Dịch JavaScript của Trình chỉnh sửa khối

SimplePoTranslate Team27 tháng 5, 2026
Dịch JSON của WordPress: Dịch JavaScript của Trình chỉnh sửa khối

Bạn đã dịch plugin của mình. Các chuỗi PHP hiển thị hoàn hảo trong cài đặt quản trị, các mẫu giao diện người dùng, thông báo email - tất cả đều đã được bản địa hóa. Sau đó, bạn mở trình chỉnh sửa khối, và mọi nhãn trong khối Gutenberg tùy chỉnh của bạn vẫn cứng đầu, trêu ngươi bằng tiếng Anh. Nút "Add Item", các tiêu đề bảng kiểm tra, văn bản giữ chỗ. Tệp .mo của bạn đã được tải. Vậy tại sao những chuỗi này không được dịch?

Bởi vì kể từ WordPress 5.0 và sự xuất hiện của Gutenberg, các chuỗi JavaScript hoàn toàn không đến từ tệp .mo của bạn. Chúng cần một tệp dịch JSON của WordPress riêng biệt, theo từng script - và nếu bạn không tạo ra nó, trình chỉnh sửa khối của bạn sẽ vẫn bằng tiếng Anh cho dù tệp .po của bạn có hoàn chỉnh đến đâu. Đây là một trong những lỗ hổng bản địa hóa phổ biến và gây nhầm lẫn nhất trong phát triển WordPress hiện đại. Hướng dẫn này giải thích chính xác tại sao điều này xảy ra, cách hệ thống dịch JSON hoạt động, các tên tệp được băm MD5 gây khó khăn cho mọi người, và bộ công cụ hoàn chỉnh để khắc phục nó.

Tại Sao Các Chuỗi Trình Chỉnh Sửa Khối Của Bạn Vẫn Bằng Tiếng Anh

Câu trả lời ngắn gọn: PHP và JavaScript sử dụng hai hệ thống phân phối bản dịch hoàn toàn khác nhau trong WordPress, và tệp .mo của bạn chỉ cung cấp cho hệ thống PHP.

Hai Hệ Thống Dịch, Một Plugin

Khi WordPress chạy load_plugin_textdomain(), nó đọc tệp .mo đã biên dịch của bạn vào bộ nhớ PHP. Mỗi lệnh gọi __(), _e(), và _x() trong mã PHP của bạn sẽ tìm bản dịch ở đó. Điều này hoạt động vì PHP hiển thị phía máy chủ - dữ liệu .mo nằm ngay trong cùng một quy trình.

JavaScript thì khác. Mã khối của bạn chạy trong trình duyệt, rất lâu sau khi PHP đã hoàn thành. Nó không thể truy cập vào tệp .mo phía máy chủ. Thay vào đó, gói @wordpress/i18n - tương đương Gettext trong JS, hiển thị __(), _x(), và sprintf() cho các script của bạn - mong đợi các bản dịch được cung cấp dưới dạng tải trọng JSON gắn liền với script cụ thể cần chúng.

Điều Gì Xảy Ra Với Chuỗi JS Chưa Được Dịch

Vì vậy, một khối với các chuỗi như thế này:

import { __ } from '@wordpress/i18n';

registerBlockType( 'myplugin/feature-box', {
    title: __( 'Feature Box', 'myplugin' ),
    edit: () => {
        return <Button>{ __( 'Add Item', 'myplugin' ) }</Button>;
    },
} );

sẽ không bao giờ tìm thấy "Feature Box" hoặc "Add Item" trong tệp .mo của bạn, bởi vì trình duyệt không bao giờ đọc tệp .mo. Những chuỗi đó cần đến dưới dạng JSON, được kết nối với đúng script handle này. Nếu bạn chưa thiết lập điều đó, các lệnh gọi __() của JS chỉ đơn giản là trả về tiếng Anh gốc - âm thầm, không có lỗi trong console.

Kết Nối Bản Dịch JSON Với wp_set_script_translations()

Cầu nối giữa script của bạn và các bản dịch JSON của nó là một hàm PHP duy nhất: wp_set_script_translations(). Câu trả lời cho câu hỏi "làm thế nào WordPress biết tệp JSON nào thuộc về script nào" là: bạn cho nó biết, bằng cách đăng ký script và sau đó khai báo text domain của nó và thư mục chứa JSON.

Đăng Ký Script và Thư Mục Dịch Của Nó

add_action( 'init', function () {
    wp_register_script(
        'myplugin-editor',
        plugins_url( 'build/index.js', __FILE__ ),
        array( 'wp-blocks', 'wp-i18n', 'wp-element' ),
        '1.0.0'
    );

    // Tell WordPress where this script's JSON translations live
    wp_set_script_translations(
        'myplugin-editor',        // the registered script handle
        'myplugin',               // text domain
        plugin_dir_path( __FILE__ ) . 'languages'
    );
} );

Khi trình chỉnh sửa tải myplugin-editor, WordPress giờ đây biết phải tìm trong thư mục languages/ của bạn một tệp JSON khớp với script này và ngôn ngữ của người dùng hiện tại. Nếu tìm thấy, nó sẽ chèn các bản dịch trước khi script của bạn chạy, và các lệnh gọi __() của JS sẽ được phân giải đúng cách. Handle bạn truyền phải khớp chính xác với một script đã đăng ký - handle không khớp hoặc bị thiếu là lý do phổ biến thứ hai khiến bản dịch thất bại âm thầm.

Tên Tệp Được Băm MD5 Mà Không Ai Ngờ Đến

Đây là chi tiết gây trở ngại cho hầu hết mọi người. Tệp JSON mà WordPress tìm kiếm không được đặt tên gọn gàng như myplugin-fr_FR.json. Nó được đặt tên bằng một MD5 hash của đường dẫn nguồn script:

Giải Mã Mẫu Tên Tệp

myplugin-fr_FR-a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6.json

Mẫu là {textdomain}-{locale}-{md5}.json, trong đó hash là MD5 của đường dẫn tương đối đến tệp script (ví dụ build/index.js) như đã đăng ký. WordPress tính toán hash này trong thời gian chạy để tìm đúng JSON cho đúng script. Nếu bạn đặt tên tệp theo cách thủ công, WordPress sẽ không tìm thấy nó, và bạn sẽ thề rằng hệ thống bị hỏng trong khi nó chỉ đang tìm một tên tệp khác.

Bạn không tự tính toán hash. Lệnh WP-CLI i18n sẽ làm điều đó cho bạn, đó chính xác là lý do tại sao bạn phải sử dụng công cụ thay vì tự tạo các tệp này bằng tay. Tuy nhiên, việc hiểu rằng hash tồn tại sẽ giúp bạn tiết kiệm hàng giờ khi một tệp JSON có mặt trong languages/ nhưng vẫn bị bỏ qua - đó gần như luôn là sự không khớp hash tên tệp vì đường dẫn script đã thay đổi.

Quy Trình Hoàn Chỉnh: Từ make-pot Đến make-json

Tin tốt là bạn vẫn giữ các bản dịch của mình trong các tệp .po mà bạn đang sử dụng. JSON là một tạo phẩm được tạo ra ở cuối. Câu trả lời cho câu hỏi "tôi có cần duy trì các chuỗi JS riêng biệt không" là không - chúng nằm trong cùng tệp .pot/.po với các chuỗi PHP của bạn, và một lệnh bổ sung sẽ tách các chuỗi JS thành JSON.

Quy Trình Bốn Lệnh

Dưới đây là quy trình hoàn chỉnh:

# 1. Extract ALL translatable strings (PHP and JS) into one template
wp i18n make-pot . languages/myplugin.pot

# 2. Translate languages/myplugin-fr_FR.po as usual (Poedit, AI, etc.)

# 3. Compile the .mo for PHP strings (server-side, as always)
wp i18n make-mo languages/

# 4. Generate the MD5-hashed JSON files for JS strings
wp i18n make-json languages/ --no-purge

Lệnh make-pot ở Bước 1 đủ thông minh để quét cả tệp .php và mã nguồn .js/.jsx của bạn, vì vậy một tệp .po duy nhất cho mỗi ngôn ngữ sẽ chứa tất cả mọi thứ. Lệnh make-json ở Bước 4 đọc từng tệp .po đã dịch, tìm các mục đến từ tệp JavaScript và ghi ra một tệp JSON được băm đúng cho mỗi script. Cờ --no-purge cũng giữ các chuỗi JS trong tệp .po của bạn, để lệnh make-mo sau này không làm mất chúng - nếu không có cờ này, make-json sẽ loại bỏ các mục JS ra khỏi .po, điều này gây bất ngờ cho những người chạy lệnh sai thứ tự.

Một tệp JSON được tạo trông giống như một tập hợp bản dịch định dạng Jed:

{
  "translation-revision-date": "2026-06-12 10:00+0000",
  "generator": "WP-CLI/2.x",
  "domain": "messages",
  "locale_data": {
    "messages": {
      "": { "domain": "messages", "lang": "fr_FR" },
      "Feature Box": [ "Bloc fonctionnalité" ],
      "Add Item": [ "Ajouter un élément" ]
    }
  }
}

WordPress đọc locale_data và cấp nó cho @wordpress/i18n trước khi script của bạn chạy. Giờ đây, __( 'Add Item', 'myplugin' ) trong trình duyệt sẽ trả về Ajouter un élément, và trình chỉnh sửa khối của bạn cuối cùng đã được bản địa hóa.

Điều Này Khác Với i18next JSON Như Thế Nào

Cả hai hệ thống đều sử dụng JSON, cả hai đều nhắm mục tiêu JavaScript, và sự tương đồng bề mặt đó gây ra sự nhầm lẫn thực sự. Chúng không thể hoán đổi cho nhau. JSON của trình chỉnh sửa khối WordPress là một tải trọng được băm MD5, có nguồn gốc từ Gettext, theo từng script được tiêu thụ bởi @wordpress/i18n. i18next JSON là một tệp khóa-giá trị phẳng hoặc lồng nhau được tiêu thụ bởi react-i18next hoặc next-intl, với cú pháp {{interpolation}} và quy ước khóa số nhiều riêng.

Nếu bạn đang làm việc với React hoặc Next.js thuần túy bên ngoài WordPress, bạn muốn cách tiếp cận i18next, mà chúng tôi đề cập trong bài viết dịch JSON i18next trong React và Next.js. Trong WordPress, bạn muốn quy trình make-json ở trên. Việc trộn lẫn chúng - ví dụ, tự viết JSON kiểu i18next phẳng và mong đợi wp_set_script_translations() tải nó - đơn giản là sẽ không hoạt động, bởi vì WordPress đang tìm kiếm định dạng Jed đã được băm, chứ không phải các cặp khóa-giá trị tùy ý.

Một Nguồn, Mọi Định Dạng Bạn Cần

Điểm yếu trong tất cả những điều này là bước dịch ở giữa. Tệp .po của bạn cung cấp cho cả .mo (PHP) và JSON (JavaScript), vì vậy một bản dịch bị lỗi duy nhất - một %s bị hỏng, một thẻ <strong> bị sai, một dạng số nhiều bị đổi tên - sẽ làm hỏng cả hai đầu ra cùng một lúc. Và bởi vì các chuỗi JS được tải không đồng bộ trong trình duyệt, lỗi cấu trúc ở đó thường biểu hiện dưới dạng một nhãn trống hoặc một sự cố nghiêm trọng chứ không phải là một phương án dự phòng khéo léo.

Một Lần Tải Lên, Bao Gồm PHP và JavaScript

Đây là nơi một quy trình dịch hiểu cấu trúc Gettext chứng minh giá trị của nó. SimplePoTranslate nhận một tệp .po hoặc .pot nguồn duy nhất và tạo ra đầu ra đã dịch sạch sẽ ở nhiều định dạng từ một lần tải lên duy nhất - .po, .mo, .json, .php, và .xliff - để bạn không phải kết nối các công cụ riêng biệt cho các lớp PHP và JavaScript của mình. Khóa cú pháp của nó giữ %s, %1$s, {count}, và HTML nội tuyến ở đúng vị trí, điều này đặc biệt quan trọng đối với các chuỗi trình chỉnh sửa khối nơi một placeholder bị lỗi có thể làm hỏng toàn bộ bảng điều khiển trình chỉnh sửa. Chúng tôi đi sâu hơn vào mô hình một nguồn, nhiều đầu ra trong bài viết một tệp đầu vào, năm định dạng đầu ra.

Bạn vẫn chạy make-json để tạo ra các tệp được băm mà WordPress mong đợi - bước đó là dành riêng cho WordPress và nằm trong quá trình xây dựng của bạn. Nhưng bản dịch, phần có nhiều khả năng làm hỏng các chuỗi JS của bạn nhất, được xử lý bởi một công cụ nhận biết ngữ cảnh thay vì một script tìm-và-thay thế.

Kết Luận

Lý do trình chỉnh sửa khối của bạn vẫn bằng tiếng Anh là do cấu trúc, chứ không phải lỗi: Dịch JSON của WordPress là một hệ thống phân phối riêng biệt với tệp .mo, được xây dựng đặc biệt vì trình duyệt không thể đọc dữ liệu Gettext phía máy chủ. Khi bạn hiểu rằng các chuỗi JavaScript cần JSON được băm MD5, theo từng script, được tạo bởi wp i18n make-json và được kết nối với wp_set_script_translations(), cách khắc phục là tự động. Giữ các chuỗi của bạn trong một tệp .po, biên dịch .mo cho PHP, và chạy make-json cho JS.

Thực hiện đúng bước dịch và cả hai đầu ra sẽ theo. Làm sai và bạn sẽ phải gỡ lỗi các bảng trình chỉnh sửa trống rỗng suốt buổi chiều.

Sẵn sàng dịch các chuỗi JSON và PHP của WordPress từ một nguồn sạch? Thử SimplePoTranslate miễn phí — không cần thẻ tín dụng. Gói miễn phí dịch các tệp .po.pot thực với tính năng Khóa cú pháp an toàn placeholder, để các chuỗi trình chỉnh sửa khối của bạn được xuất bản chính xác.