Tính năngPluginGiáTài nguyên
Thay đổi ngôn ngữ
Tài nguyênSử dụng msgctxt: Thêm ngữ cảnh vào bản dịch Gettext

Sử dụng msgctxt: Thêm ngữ cảnh vào bản dịch Gettext

SimplePoTranslate Team15 tháng 5, 2026
Sử dụng msgctxt: Thêm ngữ cảnh vào bản dịch Gettext

Bạn dịch từ tiếng Anh "Book" sang tiếng Đức, và người dịch của bạn tự tin trả về "Buch". Ba tuần sau, một báo cáo lỗi xuất hiện: nút "Book a table" trên biểu mẫu đặt chỗ của bạn giờ đây hiển thị "Buch a table" - danh từ, không phải động từ. Từ thì đúng. Ngữ cảnh thì thiếu. Đây là một trong những lỗi không gây tiếng ồn phổ biến nhất trong việc bản địa hóa phần mềm, và giải pháp đã tồn tại trong Gettext hàng thập kỷ: msgctxt.

Nếu bạn từng phát hành một bản dịch mà một chuỗi tiếng Anh duy nhất đúng ở một nơi nhưng lại vô nghĩa ở nơi khác, bạn đã gặp phải vấn đề mơ hồ. Cùng một từ nguồn ánh xạ tới các bản dịch khác nhau tùy thuộc vào nơi nó xuất hiện. Nếu không có msgctxt, người dịch (con người hoặc AI) không thể phân biệt được các trường hợp đó, vì tất cả những gì họ thấy chỉ là chuỗi trần msgid "Book". Hướng dẫn này giải thích cách msgctxt hoạt động trong Gettext, cách đánh dấu mã nguồn của bạn bằng _x()_ex(), cách nó hiển thị trong các tệp .po của bạn, và tại sao một quy trình dịch có nhận thức ngữ cảnh là cách đáng tin cậy duy nhất để xử lý đúng các chuỗi này ở quy mô lớn.

Vấn đề mơ hồ: Một từ, nhiều nghĩa

Ngôn ngữ tự nhiên đầy rẫy những từ rút gọn thành một token tiếng Anh duy nhất nhưng lại phân tách thành nhiều từ trong các ngôn ngữ khác. Người dịch chỉ thấy chuỗi nguồn, vì vậy khi hai phần tử giao diện người dùng không liên quan chia sẻ cùng một từ tiếng Anh, chúng chia sẻ cùng msgid - và Gettext hợp nhất chúng thành một mục nhập.

Các từ phân tách trong các ngôn ngữ

Hãy xem xét ba ví dụ kinh điển:

  • "Book" - danh từ (một vật trên kệ sách) so với động từ ("Book a flight" - Đặt chuyến bay). Tiếng Đức: Buch so với buchen.
  • "Post" - xuất bản nội dung so với gửi thư. Tiếng Pháp: publier so với courrier.
  • "Order" - một trình tự/sắp xếp so với một giao dịch mua. Tiếng Tây Ban Nha: orden so với pedido.

Trong tiếng Anh, mã của bạn sử dụng cùng một chuỗi nguyên văn ở cả hai nơi:

// Somewhere in a library catalog screen
echo __( 'Book', 'mytextdomain' );

// Somewhere in a reservation form button
echo __( 'Book', 'mytextdomain' );

Cách các chuỗi giống hệt nhau rút gọn thành một mục nhập

Khi bạn chạy wp i18n make-pot hoặc xgettext, cả hai lệnh gọi đều rút gọn thành một mục nhập .po:

#: catalog.php:42 reservation-form.php:88
msgid "Book"
msgstr ""

Chỉ có đúng một msgstr để điền vào. Dù người dịch chọn gì, một trong hai màn hình sẽ sai. Người dịch không thể khắc phục điều này ngay cả khi họ hiểu vấn đề, vì bản thân định dạng không cho phép họ cung cấp hai bản dịch cho một msgid. Sự mơ hồ đã được tích hợp sẵn trong dữ liệu.

msgctxt là gì và cách nó loại bỏ sự mơ hồ?

msgctxt là một chuỗi ngữ cảnh được đính kèm vào một mục dịch. Câu trả lời ngắn gọn: nó thêm một khóa thứ hai cùng với msgid, vì vậy Gettext coi (context, msgid) là một cặp duy nhất. Hai mục nhập có cùng msgid nhưng msgctxt khác nhau sẽ trở thành hai chuỗi riêng biệt, có thể dịch độc lập.

Trong mô hình tra cứu của Gettext, một bản dịch thường chỉ được khóa bằng chuỗi nguồn. Với msgctxt, khóa trở thành sự kết hợp của ngữ cảnh cộng với nguồn. Đó là toàn bộ cơ chế, và đó là lý do tại sao nó hoạt động rất gọn gàng: bạn không thay đổi văn bản hiển thị, mà chỉ thay đổi khóa tra cứu nội bộ.

Dòng msgctxt trong tệp .po

Trong một tệp .po, ngữ cảnh xuất hiện trên dòng riêng của nó, ngay phía trên msgid:

#: catalog.php:42
msgctxt "noun"
msgid "Book"
msgstr "Buch"

#: reservation-form.php:88
msgctxt "verb"
msgid "Book"
msgstr "Reservieren"

Bây giờ có hai mục nhập. Chúng có giá trị msgid giống hệt nhau nhưng giá trị msgctxt khác biệt, vì vậy mỗi mục có msgstr riêng. Danh mục hiển thị Buch; nút đặt chỗ hiển thị Reservieren. Runtime chọn đúng mục vì mã của bạn đã cho biết ngữ cảnh nào cần sử dụng.

So sánh điều đó với phiên bản một mục nhập bị lỗi ở trên. Sự khác biệt không phải là chất lượng bản dịch - mà là liệu mô hình dữ liệu có cho phép câu trả lời đúng tồn tại hay không.

Đánh dấu mã của bạn: _x()_ex()

Để xuất msgctxt vào mẫu .po của bạn, bạn gọi một hàm dịch có nhận thức ngữ cảnh thay vì hàm thông thường. Trong WordPress, đó là _x() và hàm xuất bản _ex() của nó; trong Gettext thuần, chúng ánh xạ tới pgettext().

Lựa chọn giữa _x()_ex()

Hàm __() thông thường nhận chuỗi và text domain. Biến thể ngữ cảnh chèn ngữ cảnh làm đối số thứ hai:

// Without context - ambiguous
__( 'Book', 'mytextdomain' );

// With context - the second argument is the msgctxt
_x( 'Book', 'noun', 'mytextdomain' );        // returns the translated string
_ex( 'Book', 'verb', 'mytextdomain' );       // echoes it directly

// Real-world disambiguation
_x( 'Post', 'verb: publish content', 'mytextdomain' );
_x( 'Post', 'noun: mail item', 'mytextdomain' );
_x( 'Order', 'sequence or sorting', 'mytextdomain' );
_x( 'Order', 'customer purchase', 'mytextdomain' );

Đối số thứ hai là nhãn ngữ cảnh. Nó không bao giờ được hiển thị cho người dùng của bạn - nó tồn tại thuần túy để loại bỏ sự mơ hồ, cả cho việc tra cứu Gettext và cho bất kỳ ai (hoặc bất kỳ thứ gì) đang thực hiện dịch thuật. Viết ngữ cảnh dưới dạng các gợi ý ngắn gọn, mô tả: 'noun', 'verb', 'button label', 'admin menu'. Một ngữ cảnh mơ hồ như '1' về mặt kỹ thuật là hợp lệ nhưng vô dụng đối với người dịch.

Khi bạn tạo lại mẫu, trình trích xuất sẽ nhận ra các lệnh gọi này và xuất dòng msgctxt. Các công cụ như Poedit và các trình chỉnh sửa PO khác sau đó nhóm các mục nhập rõ ràng theo ngữ cảnh, để người dịch ngay lập tức thấy rằng "Book (danh từ)" và "Book (động từ)" là hai công việc khác nhau. Nếu bạn vẫn đang thiết lập chuỗi công cụ trích xuất của mình hoặc đang vật lộn với cách các biến tương tác với các chuỗi này, hướng dẫn của chúng tôi về dịch các tệp PO mà không làm hỏng các biến mã bao gồm quy trình làm việc xung quanh một cách chuyên sâu.

Tại sao những người dịch thiếu kinh nghiệm - và nhiều công cụ AI - lại làm sai điều này

Đây là phần khó chịu. Thêm msgctxt vào nguồn của bạn là cần thiết nhưng chưa đủ. Ngữ cảnh chỉ hữu ích nếu thứ thực hiện dịch thuật thực sự đọc nó.

Chế độ lỗi ngữ cảnh bị loại bỏ

Một tập lệnh dịch hàng loạt đơn giản làm điều này: nó lặp qua các mục nhập, lấy từng msgid, gửi nó đến một API dịch thuật và ghi kết quả vào msgstr. Nó không bao giờ nhìn vào dòng msgctxt. Vì vậy, ngay cả khi bạn cẩn thận viết _x( 'Book', 'noun' )_x( 'Book', 'verb' ), tập lệnh vẫn gửi hai yêu cầu giống hệt nhau - "dịch Book" - và dán cùng một câu trả lời vào cả hai. Tất cả nỗ lực đánh dấu của bạn bị loại bỏ ở bước cuối cùng.

Nhiều công cụ dịch thuật AI đa năng có cùng điểm mù. Chúng được xây dựng để dịch văn bản, và msgctxt là siêu dữ liệu, không phải văn bản. Nếu công cụ làm phẳng tệp .po của bạn thành một danh sách các chuỗi trước khi gửi nó đến mô hình, ngữ cảnh sẽ không bao giờ đến được với lời nhắc của mô hình. Mô hình, thiếu bất kỳ tín hiệu nào, sẽ mặc định chọn nghĩa phổ biến nhất của từ về mặt thống kê - thường là danh từ cho "Book", nghĩa xuất bản cho "Post" - và dịch sai một cách lặng lẽ trường hợp thiểu số. Bạn sẽ không thấy lỗi. Bạn sẽ thấy một báo cáo lỗi từ người dùng Đức vài tuần sau đó.

Ngữ cảnh và số nhiều có cùng nguyên nhân gốc rễ

Đây cũng là nơi xử lý số nhiều và ngữ cảnh giao nhau, bởi vì cả hai đều phụ thuộc vào việc công cụ hiểu cấu trúc của Gettext thay vì coi tệp là văn bản phẳng. Nếu các chuỗi của bạn cũng liên quan đến các dạng dựa trên số lượng, thì nhận thức cấu trúc tương tự cũng quan trọng - chúng tôi sẽ phân tích điều đó trong hiểu các dạng số nhiều của Gettext.

Cách một quy trình có nhận thức ngữ cảnh sử dụng msgctxt

Một quy trình dịch thuật tôn trọng msgctxt làm ngược lại với tập lệnh đơn giản. Nó phân tích cú pháp tệp .po dưới dạng dữ liệu có cấu trúc, giữ ngữ cảnh của mỗi mục nhập được đính kèm vào chuỗi nguồn của nó, và chuyển ngữ cảnh đó cho AI như một phần của lời nhắc - để mô hình biết rằng nó đang dịch "Book" cụ thể là một động từ, chứ không phải một cách trừu tượng.

Ngữ cảnh như một tín hiệu hạng nhất

Đây chính xác là cách SimplePoTranslate tiếp cận vấn đề. AI nhận thức ngữ cảnh của nó đọc dòng msgctxt như một tín hiệu hạng nhất: khi hai mục nhập chia sẻ cùng một msgid nhưng khác nhau về ngữ cảnh, chúng được dịch thành các chuỗi riêng biệt mà chúng thực sự là, và gợi ý ngữ cảnh thông báo cho mô hình lựa chọn từ. Kết quả là "Book (danh từ)" trở lại là Buch trong khi "Book (động từ)" trở lại là buchen hoặc reservieren - tự động, mà không cần bạn phải tự tay sửa từng thuật ngữ mơ hồ.

Cũng quan trọng không kém, quy trình duy trì dòng msgctxt trong đầu ra. Một công cụ yếu hơn có thể loại bỏ ngữ cảnh trong quá trình chuyển đổi qua lại, âm thầm hợp nhất hai mục nhập của bạn trở lại thành một và gây ra lại sự mơ hồ trong lần hợp nhất tiếp theo. Hỗ trợ Gettext đầy đủ có nghĩa là ngữ cảnh tồn tại qua bản dịch, biên dịch .mo và bất kỳ lần nhập lại sau này nào - vì vậy việc loại bỏ sự mơ hồ của bạn là bền vững, chứ không phải là một bản vá thủ công một lần. Kết hợp với Khóa cú pháp cho các placeholder bên trong các chuỗi đó, bạn nhận được các bản dịch vừa đúng ngữ cảnh vừa nguyên vẹn về cấu trúc.

Bạn vẫn là người quyết định đánh dấu - chỉ bạn mới biết rằng một từ "Book" nhất định là một động từ. Nhưng một khi bạn đã chú thích nguồn của mình bằng _x()_ex(), một quy trình có nhận thức ngữ cảnh sẽ biến chú thích đó thành các bản dịch chính xác trên mọi ngôn ngữ đích mà không cần phải chăm sóc từng chuỗi.

Kết luận

Vấn đề mơ hồ - một từ tiếng Anh, nhiều nghĩa - không phải là một điểm kỳ lạ mà bạn có thể bỏ qua; nó là một đặc điểm cấu trúc về cách Gettext lưu trữ các chuỗi. Giải pháp là msgctxt: chú thích các chuỗi mơ hồ trong nguồn của bạn bằng _x()_ex(), cung cấp cho mỗi lần xuất hiện một nhãn ngữ cảnh rõ ràng, và để Gettext khóa bản dịch dựa trên cặp (context, msgid). Phần đó là do bạn, và chỉ mất vài phút.

Phần khó hơn là đảm bảo bước dịch của bạn thực sự tôn trọng ngữ cảnh đó thay vì loại bỏ nó. Các tập lệnh đơn giản và các công cụ AI chỉ dịch văn bản loại bỏ msgctxt và gây ra lại chính xác lỗi mà bạn đang cố gắng ngăn chặn. Một quy trình có nhận thức ngữ cảnh đọc ngữ cảnh, dịch từng mục nhập đã được loại bỏ sự mơ hồ một cách chính xác, và duy trì nó thông qua biên dịch và nhập lại.

Sẵn sàng ngừng phát hành các bản dịch sai do thiếu ngữ cảnh? Dùng thử SimplePoTranslate miễn phí — không yêu cầu thẻ tín dụng. Gói miễn phí xử lý các tệp .po.pot thực với hỗ trợ ngữ cảnh msgctxt đầy đủ, để các chuỗi đã được loại bỏ sự mơ hồ của bạn được dịch chính xác ngay lần đầu tiên.

Các chủ đề liên quan