Việc cung cấp trang web hoặc ứng dụng web của bạn cho nhiều đối tượng hơn thường yêu cầu trang web hoặc ứng dụng web đó phải có sẵn bằng nhiều ngôn ngữ. Đối với các dự án không phải tiếng Anh, bạn có thể tăng lượng khán giả của mình bằng cách phát hành nó bằng tiếng Anh cũng như ngôn ngữ mẹ đẻ của bạn. Tuy nhiên, quốc tế hóa và bản địa hóa dự án của bạn sẽ trở thành một quá trình dễ dàng hơn nhiều nếu bạn bắt đầu từ giai đoạn sơ khai. Trong bài viết này, Kỹ sư phần mềm Toptal Igor Gomes dos Santos chỉ cho chúng ta cách tận dụng các công cụ đơn giản, như Gettext và Poedit, để quốc tế hóa và bản địa hóa một dự án PHP
Qua
Igor Santos
Có tầm nhìn lớn về UI/UX, Igor là một nhà phát triển có nền tảng PHP vững chắc [hơn 10 năm], chuyển sang lĩnh vực JS để có nhiều trải nghiệm tương tác hơn
ĐĂNG LẠI
ĐĂNG LẠI
Cho dù bạn đang xây dựng một trang web hay một ứng dụng web chính thức, thì việc làm cho nó có thể tiếp cận được với nhiều đối tượng hơn thường yêu cầu nó phải có sẵn bằng các ngôn ngữ và ngôn ngữ khác nhau
Sự khác biệt cơ bản giữa hầu hết các ngôn ngữ của con người làm cho điều này trở nên dễ dàng. Sự khác biệt về quy tắc ngữ pháp, sắc thái ngôn ngữ, định dạng ngày tháng, v.v. kết hợp lại khiến việc bản địa hóa trở thành một thách thức độc đáo và ghê gớm
Hãy xem xét ví dụ đơn giản này
Quy tắc chia số nhiều trong tiếng Anh khá đơn giản. bạn có thể có dạng số ít của một từ hoặc dạng số nhiều của một từ
Tuy nhiên, trong các ngôn ngữ khác – chẳng hạn như các ngôn ngữ Slavic – có hai dạng số nhiều ngoài dạng số ít. Bạn thậm chí có thể tìm thấy các ngôn ngữ có tổng cộng bốn, năm hoặc sáu dạng số nhiều, chẳng hạn như tiếng Slovenia, tiếng Ireland hoặc tiếng Ả Rập
Cách mã của bạn được tổ chức cũng như cách các thành phần và giao diện của bạn được thiết kế đóng vai trò quan trọng trong việc xác định mức độ bạn có thể bản địa hóa ứng dụng của mình dễ dàng như thế nào
Quốc tế hóa [i18n] cơ sở mã của bạn, giúp đảm bảo rằng nó có thể thích ứng với các ngôn ngữ hoặc khu vực khác nhau một cách dễ dàng. Việc quốc tế hóa thường được thực hiện một lần, tốt nhất là khi bắt đầu dự án để tránh cần những thay đổi lớn trong mã nguồn sau này
Khi cơ sở mã của bạn đã được quốc tế hóa, bản địa hóa [l10n] trở thành vấn đề dịch nội dung ứng dụng của bạn sang một ngôn ngữ/ngôn ngữ cụ thể
Bản địa hóa cần được thực hiện mỗi khi cần hỗ trợ một ngôn ngữ hoặc khu vực mới. Ngoài ra, bất cứ khi nào một phần của giao diện [chứa văn bản] được cập nhật, nội dung mới sẽ có sẵn - nội dung này sau đó cần được bản địa hóa [i. e. , đã dịch] sang tất cả các ngôn ngữ được hỗ trợ
Trong bài viết này, chúng ta sẽ tìm hiểu cách quốc tế hóa và bản địa hóa phần mềm viết bằng PHP. Chúng tôi sẽ xem xét các tùy chọn triển khai khác nhau và các công cụ khác nhau có sẵn để chúng tôi xử lý dễ dàng
Công cụ quốc tế hóa
Cách dễ nhất để quốc tế hóa phần mềm PHP là sử dụng tệp mảng. Mảng sẽ được điền bằng các chuỗi đã dịch, sau đó có thể tra cứu từ bên trong các mẫu
Tuy nhiên, đây hầu như không phải là một cách được khuyến nghị cho các dự án nghiêm túc, vì nó chắc chắn sẽ gây ra các vấn đề về bảo trì sau này. Một số vấn đề thậm chí có thể xuất hiện ngay từ đầu, chẳng hạn như thiếu hỗ trợ cho phép nội suy biến hoặc số nhiều của danh từ, v.v.
Một trong những công cụ cổ điển nhất [thường được dùng làm tài liệu tham khảo cho i18n và l10n] là một công cụ Unix có tên là Gettext
Mặc dù ra đời từ năm 1995, nó vẫn là một công cụ toàn diện để dịch phần mềm cũng như dễ sử dụng. Mặc dù khá dễ dàng để bắt đầu nhưng nó vẫn có các công cụ hỗ trợ mạnh mẽ
Gettext là những gì chúng tôi sẽ sử dụng trong bài đăng này. Chúng tôi sẽ trình bày một ứng dụng GUI tuyệt vời có thể được sử dụng để dễ dàng cập nhật các tệp nguồn l10n của bạn, do đó không cần phải xử lý dòng lệnh
Thư viện giúp mọi thứ trở nên dễ dàng
Có các thư viện và khuôn khổ web PHP chính hỗ trợ Gettext và các triển khai khác của i18n. Một số dễ cài đặt hơn những cái khác hoặc có các tính năng bổ sung hoặc hỗ trợ các định dạng tệp i18n khác nhau. Mặc dù trong tài liệu này, chúng tôi tập trung vào các công cụ được cung cấp cùng với lõi PHP, đây là danh sách một số công cụ khác đáng được đề cập
oscarotero/Gettext. Hỗ trợ gettext với giao diện hướng đối tượng; . Cũng có thể xuất sang các định dạng không chỉ. tháng/. po, có thể hữu ích nếu bạn cần tích hợp các tệp dịch của mình vào các phần khác của hệ thống, chẳng hạn như giao diện JavaScript
symfony/bản dịch. Hỗ trợ nhiều định dạng khác nhau, nhưng khuyên bạn nên sử dụng XLIFF dài dòng. Không bao gồm các chức năng của trình trợ giúp hoặc trình trích xuất tích hợp, nhưng hỗ trợ trình giữ chỗ bằng cách sử dụng nội bộ
8msgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
zend/i18n. Hỗ trợ các tệp mảng và INI hoặc định dạng Gettext. Triển khai một lớp bộ nhớ đệm để tránh phải đọc hệ thống tệp mỗi lần. Cũng bao gồm các trình trợ giúp chế độ xem cũng như các trình xác thực và bộ lọc đầu vào nhận biết ngôn ngữ. Tuy nhiên, nó không có trình trích xuất tin nhắn
Các khung khác cũng bao gồm các mô-đun i18n, nhưng chúng không có sẵn bên ngoài cơ sở mã của chúng
ấu trùng. Hỗ trợ các tệp mảng cơ bản;
yii. Hỗ trợ dịch mảng, Gettext và dựa trên cơ sở dữ liệu, đồng thời bao gồm trình trích xuất thông báo. Được hỗ trợ bởi tiện ích mở rộng
0, có sẵn kể từ PHP 5. 3, và dựa trên dự án ICU. Điều này cho phép Yii chạy các thay thế mạnh mẽ, như đánh vần số, định dạng ngày, giờ, khoảng thời gian, tiền tệ và thứ tựmsgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
Nếu bạn quyết định sử dụng một trong những thư viện không cung cấp trình trích xuất, bạn có thể muốn sử dụng các định dạng Gettext, vì vậy bạn có thể sử dụng chuỗi công cụ Gettext gốc [bao gồm cả Poedit] như được mô tả trong phần còn lại của chương
Cài đặt Gettext
Bạn có thể cần cài đặt Gettext và thư viện PHP có liên quan bằng cách sử dụng trình quản lý gói của mình, như apt-get hoặc yum. Sau khi được cài đặt, hãy kích hoạt nó bằng cách thêm
msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
1 [Linux/Unix] hoặc msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
2 [Windows] vào tệp msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
0 của bạnỞ đây chúng tôi cũng sẽ sử dụng Poedit để tạo tệp dịch. Bạn có thể sẽ tìm thấy nó trong trình quản lý gói của hệ thống;
Các loại tệp Gettext
Có ba loại tệp bạn thường xử lý khi làm việc với Gettext
Các tệp chính là các tệp PO [Đối tượng di động] và MO [Đối tượng máy], tệp đầu tiên là danh sách các “đối tượng được dịch” có thể đọc được và tệp thứ hai là tệp nhị phân tương ứng [được Gettext giải thích khi thực hiện bản địa hóa]. Ngoài ra còn có một tệp POT [Mẫu PO], chỉ chứa tất cả các khóa hiện có từ các tệp nguồn của bạn và có thể được sử dụng làm hướng dẫn để tạo và cập nhật tất cả các tệp PO
Các tệp mẫu không bắt buộc; . Bạn sẽ có một cặp tệp PO/MO cho mỗi ngôn ngữ và khu vực nhưng chỉ có một POT cho mỗi miền
Tách tên miền
Có một số trường hợp, trong các dự án lớn, bạn có thể cần phải tách các bản dịch khi cùng một từ truyền đạt ý nghĩa khác nhau trong các ngữ cảnh khác nhau
Trong những trường hợp đó, bạn sẽ cần chia chúng thành các “miền” khác nhau, về cơ bản được đặt tên theo nhóm tệp POT/PO/MO, trong đó tên tệp là miền dịch đã nói
Các dự án vừa và nhỏ thường chỉ sử dụng một miền để đơn giản;
Ví dụ, trong các dự án Symfony, các miền được sử dụng để phân tách bản dịch cho các thông báo xác thực
Mã địa phương
Ngôn ngữ chỉ đơn giản là một mã xác định một phiên bản của ngôn ngữ. Nó được xác định theo thông số ISO 639-1 và ISO 3166-1 alpha-2. hai chữ cái viết thường cho ngôn ngữ, tùy chọn theo sau là dấu gạch dưới và hai chữ cái viết hoa xác định quốc gia hoặc mã vùng
Đối với các ngôn ngữ hiếm, ba chữ cái được sử dụng
Đối với một số người nói, phần quốc gia có vẻ dư thừa. Trên thực tế, một số ngôn ngữ có phương ngữ ở các quốc gia khác nhau, chẳng hạn như tiếng Đức gốc Áo [de_AT] hoặc tiếng Bồ Đào Nha Brazil [pt_BR]. Phần thứ hai được sử dụng để phân biệt giữa các phương ngữ đó - khi nó không có mặt, nó được coi là phiên bản “chung” hoặc “lai” của ngôn ngữ
Cấu trúc thư mục
Để sử dụng Gettext, chúng ta cần tuân theo một cấu trúc thư mục cụ thể
Trước tiên, bạn sẽ cần chọn một gốc tùy ý cho các tệp l10n trong kho lưu trữ nguồn của mình. Bên trong nó, bạn sẽ có một thư mục cho từng ngôn ngữ cần thiết và một thư mục “LC_MESSAGES” cố định sẽ chứa tất cả các cặp PO/MO của bạn
Hình thức số nhiều
Như chúng tôi đã nói trong phần giới thiệu, các ngôn ngữ khác nhau có thể áp dụng các quy tắc số nhiều khác nhau. Tuy nhiên, Gettext giúp chúng ta tránh khỏi rắc rối này
Khi tạo mới. po, bạn sẽ phải khai báo các quy tắc số nhiều cho ngôn ngữ đó và các phần đã dịch nhạy cảm với số nhiều sẽ có dạng khác nhau cho mỗi quy tắc đó
Khi gọi Gettext trong mã, bạn sẽ phải chỉ định một số liên quan đến câu [e. g. cho cụm từ “Bạn có n tin nhắn. ”, bạn sẽ cần chỉ định giá trị của n], và nó sẽ tìm ra dạng chính xác để sử dụng - thậm chí sử dụng thay thế chuỗi nếu cần
Quy tắc số nhiều bao gồm số lượng quy tắc cần thiết với phép thử boolean cho mỗi quy tắc [có thể bỏ qua phép thử cho nhiều nhất một quy tắc]. Ví dụ
tiếng Nhật.
1 - một quy tắc. không có dạng số nhiềumsgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
Tiếng Anh.
2 - hai quy tắc. chỉ sử dụng dạng số nhiều khi n không phải là 1, nếu không thì sử dụng dạng số ítmsgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
tiếng Bồ Đào Nha của người brazi.
3 - hai quy tắc, chỉ sử dụng dạng số nhiều khi n lớn hơn 1, nếu không thì sử dụng dạng số ítmsgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
Để được giải thích sâu hơn, có một hướng dẫn LingoHub thông tin có sẵn trực tuyến
Gettext sẽ xác định quy tắc nào sẽ sử dụng dựa trên số được cung cấp và sẽ sử dụng phiên bản chuỗi được bản địa hóa chính xác. Đối với các chuỗi cần xử lý dạng số nhiều, bạn sẽ cần đưa vào. po tệp một câu khác nhau cho mỗi quy tắc số nhiều được xác định
Thực hiện mẫu
Sau tất cả những lý thuyết đó, chúng ta hãy thực hành một chút. Đây là một đoạn trích của một. po [đừng lo lắng quá nhiều về cú pháp, mà thay vào đó chỉ cần hiểu nội dung tổng thể]
msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
Phần đầu tiên hoạt động giống như một tiêu đề, có
msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
4 và msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
5 trốngNó mô tả mã hóa tệp, dạng số nhiều và một số thứ khác. Phần thứ hai dịch một chuỗi đơn giản từ tiếng Anh sang tiếng Bồ Đào Nha Brazil và phần thứ ba thực hiện tương tự, nhưng tận dụng thay thế chuỗi từ
msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
6, cho phép bản dịch chứa tên người dùng và ngày truy cậpPhần cuối cùng là một mẫu các dạng số nhiều, hiển thị phiên bản số ít và số nhiều là
msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
4 trong tiếng Anh và các bản dịch tương ứng của chúng là msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
5 0 và 1 [theo số được đưa ra bởi quy tắc số nhiều]Ở đó, thay thế chuỗi cũng được sử dụng, vì vậy số có thể được nhìn thấy trực tiếp trong câu bằng cách sử dụng
msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
9. Dạng số nhiều luôn có hai msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
4 [số ít và số nhiều], vì vậy không nên sử dụng ngôn ngữ phức tạp làm nguồn dịchKhóa bản địa hóa
Như bạn có thể nhận thấy, chúng tôi đang sử dụng câu tiếng Anh thực tế làm ID nguồn.
msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
4 đó được sử dụng giống nhau trong tất cả các. po, nghĩa là các ngôn ngữ khác sẽ có cùng định dạng và cùng 14 trường nhưng được dịch 15 dòngNói về khóa dịch, có hai cách tiếp cận “triết học” tiêu chuẩn ở đây
1. msgstr dưới dạng câu thực
Ưu điểm chính của phương pháp này là
Nếu có một số phần của phần mềm chưa được dịch sang bất kỳ ngôn ngữ cụ thể nào, phím được hiển thị sẽ vẫn giữ một số ý nghĩa. Ví dụ: nếu bạn biết cách dịch từ tiếng Anh sang tiếng Tây Ban Nha nhưng cần trợ giúp dịch sang tiếng Pháp, bạn có thể xuất bản trang mới thiếu các câu tiếng Pháp và thay vào đó, các phần của trang web sẽ được hiển thị bằng tiếng Anh
Người dịch sẽ dễ dàng hiểu những gì đang diễn ra hơn và thực hiện một bản dịch phù hợp dựa trên
4msgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
Nó cung cấp cho bạn l10n “miễn phí” cho một ngôn ngữ - ngôn ngữ nguồn
Mặt khác, nhược điểm chính là, nếu bạn cần thay đổi văn bản thực tế, bạn cần thay thế cùng một
msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
4 trên một số tệp ngôn ngữ2. msgstr dưới dạng khóa có cấu trúc, duy nhất
Điều này sẽ mô tả vai trò của câu trong ứng dụng theo cách có cấu trúc, bao gồm mẫu hoặc phần chứa chuỗi thay vì nội dung của nó
Đây là một cách tuyệt vời để sắp xếp mã, tách nội dung văn bản khỏi logic mẫu. Tuy nhiên, điều đó có thể gây ra vấn đề cho người dịch, những người sẽ bỏ lỡ ngữ cảnh.
Cần có tệp ngôn ngữ nguồn để làm cơ sở cho các bản dịch khác. Ví dụ: nhà phát triển lý tưởng sẽ có một “en. po”, mà người dịch sẽ đọc để hiểu những gì cần viết trong “fr. po”
Các bản dịch bị thiếu sẽ hiển thị các phím vô nghĩa trên màn hình [“top_menu. chào mừng” thay vì “Xin chào, Người dùng. ” trên trang tiếng Pháp chưa được dịch nói trên]
Điều đó tốt vì nó sẽ buộc bản dịch phải hoàn thành trước khi xuất bản - nhưng thật tệ vì các vấn đề dịch thuật sẽ thực sự khủng khiếp trong giao diện. Tuy nhiên, một số thư viện bao gồm một tùy chọn để chỉ định một ngôn ngữ nhất định là "dự phòng", có hành vi tương tự như cách tiếp cận khác
Hướng dẫn sử dụng Gettext ủng hộ cách tiếp cận đầu tiên vì nói chung, nó dễ dàng hơn cho người dịch và người dùng trong trường hợp gặp sự cố. Đó cũng là cách tiếp cận mà chúng ta sẽ sử dụng ở đây
Tuy nhiên, cần lưu ý rằng tài liệu Symfony ủng hộ dịch thuật dựa trên từ khóa, để cho phép thay đổi độc lập tất cả các bản dịch mà không ảnh hưởng đến các mẫu.
Sử dụng hàng ngày
Trong một ứng dụng phổ biến, bạn sẽ sử dụng một số hàm Gettext khi viết văn bản tĩnh trong các trang của mình
Những câu đó sau đó sẽ xuất hiện trong. po, được dịch, được biên dịch thành. mo, sau đó được Gettext sử dụng khi hiển thị giao diện thực tế. Vì vậy, hãy kết hợp những gì chúng ta đã thảo luận cho đến nay trong một ví dụ từng bước
1. Tệp mẫu mẫu, bao gồm một số lệnh gọi gettext khác nhau
msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
8
86 chỉ cần dịch mộtmsgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
4 thành mộtmsgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
5 tương ứng cho một ngôn ngữ nhất định. Ngoài ra còn có hàm tốc kýmsgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
89 hoạt động theo cách tương tựmsgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
30 làm tương tự nhưng với quy tắc số nhiềumsgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
Ngoài ra còn có
31 vàmsgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
32, cho phép bạn ghi đè miền cho một cuộc gọi [thêm về cấu hình miền trong ví dụ tiếp theo]msgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
2. Tệp thiết lập mẫu [i18n_setup. php như đã sử dụng ở trên], chọn đúng ngôn ngữ và định cấu hình Gettext
Sử dụng Gettext liên quan đến một chút mã soạn sẵn, nhưng chủ yếu là về việc định cấu hình thư mục ngôn ngữ và chọn tham số phù hợp [ngôn ngữ và miền]
msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
33. Chuẩn bị dịch cho lần chạy đầu tiên
Một trong những lợi thế lớn của Gettext so với các gói i18n khung tùy chỉnh là định dạng tệp mở rộng và mạnh mẽ của nó
Có lẽ bạn đang nghĩ “Ôi trời, nó khá khó hiểu và chỉnh sửa bằng tay, một mảng đơn giản sẽ dễ dàng hơn. ” Đừng nhầm lẫn, các ứng dụng như Poedit luôn sẵn sàng trợ giúp - rất nhiều. Bạn có thể lấy chương trình từ trang web của họ, nó miễn phí và có sẵn cho tất cả các nền tảng. Đây là một công cụ khá dễ làm quen và đồng thời là một công cụ rất mạnh - sử dụng tất cả các tính năng mà Gettext có sẵn. Chúng tôi sẽ làm việc ở đây với phiên bản mới nhất, Poedit 1. 8
Trong lần chạy đầu tiên, bạn nên chọn “File > New…” từ menu. Bạn sẽ được hỏi về ngôn ngữ;
Bây giờ, hãy lưu tệp - cũng sử dụng cấu trúc thư mục mà chúng tôi đã đề cập. Sau đó, bạn nên nhấp vào "Trích xuất từ các nguồn" và tại đây, bạn sẽ định cấu hình các cài đặt khác nhau cho các tác vụ trích xuất và dịch thuật. Bạn sẽ có thể tìm thấy tất cả những thứ đó sau thông qua “Danh mục > Thuộc tính”
Đường dẫn nguồn. Bao gồm tất cả các thư mục từ dự án có tên là
86 [và các anh chị em] - đây thường là [các] thư mục mẫu/khung nhìn của bạn. Đây là cài đặt bắt buộc duy nhấtmsgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
Thuộc tính dịch
- Tên và phiên bản dự án, Nhóm và địa chỉ email của Nhóm. Thông tin hữu ích có trong. tiêu đề tập tin po
- Hình thức số nhiều. Đây là những quy tắc chúng tôi đã đề cập trước đây. Hầu hết thời gian bạn có thể để tùy chọn này với tùy chọn mặc định vì Poedit đã bao gồm một cơ sở dữ liệu tiện dụng gồm các quy tắc số nhiều cho nhiều ngôn ngữ
- bộ ký tự. UTF-8, tốt nhất là
- Bộ ký tự mã nguồn. Bộ ký tự được sử dụng bởi cơ sở mã của bạn - có lẽ cũng là UTF-8, phải không?
từ khóa nguồn. Phần mềm cơ bản biết cách gọi
86 và các lệnh gọi hàm tương tự trong một số ngôn ngữ lập trình, nhưng bạn cũng có thể tạo các hàm dịch của riêng mình. Nó sẽ ở đây, bạn sẽ thêm các phương pháp khác. Điều này sẽ được thảo luận sau trong phần “Mẹo”msgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
Sau khi đặt các thuộc tính đó, Poedit sẽ chạy quét qua các tệp nguồn của bạn để tìm tất cả các lệnh gọi bản địa hóa. Sau mỗi lần quét, Poedit sẽ hiển thị bản tóm tắt những gì đã tìm thấy và những gì đã bị xóa khỏi tệp nguồn. Các mục mới sẽ trống trong bảng dịch, cho phép bạn nhập các phiên bản đã bản địa hóa của các chuỗi đó. Lưu nó và một. mo sẽ được [tái] biên dịch vào cùng một thư mục và thế là xong. , dự án của bạn được quốc tế hóa
Poedit cũng có thể đề xuất các bản dịch phổ biến từ web và từ các tệp trước đó. Nó tiện dụng nên bạn chỉ cần kiểm tra xem chúng có hợp lý không và chấp nhận chúng. Nếu bạn không chắc chắn về bản dịch, bạn có thể đánh dấu bản dịch đó là Mờ và bản dịch đó sẽ hiển thị màu vàng. Các mục màu xanh là những mục không có bản dịch
4. dịch chuỗi
Như bạn có thể nhận thấy, có hai loại chuỗi bản địa hóa chính. những cái đơn giản và những cái có dạng số nhiều
Những cái đơn giản chỉ có hai hộp. nguồn và chuỗi cục bộ. Không thể sửa đổi chuỗi nguồn vì Gettext/Poedit không bao gồm khả năng thay đổi các tệp nguồn của bạn; . [Mẹo. Nếu bạn nhấp chuột phải vào một dòng dịch, nó sẽ hiển thị một gợi ý với các tệp nguồn và các dòng mà chuỗi đó đang được sử dụng. ]
Các chuỗi dạng số nhiều bao gồm hai hộp để hiển thị hai chuỗi nguồn và các tab để bạn có thể định cấu hình các dạng cuối cùng khác nhau
Ví dụ về chuỗi có dạng số nhiều trên Poedit, hiển thị tab dịch cho từng chuỗi
Bất cứ khi nào bạn thay đổi tệp mã nguồn và cần cập nhật bản dịch, chỉ cần nhấn Làm mới và Poedit sẽ quét lại mã, xóa các mục không tồn tại, hợp nhất các mục đã thay đổi và thêm mục mới
Poedit cũng có thể thử đoán một số bản dịch, dựa trên những bản dịch khác mà bạn đã thực hiện. Những dự đoán đó và các mục đã thay đổi sẽ nhận được điểm đánh dấu “Mờ”, cho biết rằng chúng cần được xem xét, hiển thị bằng màu vàng trong danh sách
Nó cũng hữu ích nếu bạn có một nhóm dịch thuật và ai đó đang cố gắng viết điều gì đó mà họ không chắc chắn về nó. chỉ cần đánh dấu nó Mờ và người khác sẽ xem xét nó sau
Cuối cùng, bạn nên đánh dấu “Xem > Các mục chưa được dịch trước”, vì nó sẽ giúp bạn tránh quên bất kỳ mục nào. Từ menu đó, bạn cũng có thể mở các phần của giao diện người dùng cho phép bạn để lại thông tin theo ngữ cảnh cho người dịch nếu cần
Mẹo & Thủ thuật
Các máy chủ web có thể lưu vào bộ nhớ đệm của bạn. tập tin mo
Nếu bạn đang chạy PHP dưới dạng một mô-đun trên Apache [mod_php], bạn có thể gặp sự cố với. tập tin mo đang được lưu trữ. Nó xảy ra lần đầu tiên nó được đọc và sau đó, để cập nhật nó, bạn có thể cần phải khởi động lại máy chủ
Trên Nginx và PHP5, thường chỉ mất vài lần làm mới trang để làm mới bộ đệm dịch và trên PHP7 hiếm khi cần thiết
Các thư viện cung cấp các hàm trợ giúp để giữ cho mã bản địa hóa ngắn gọn
Theo sở thích của nhiều người, việc sử dụng
msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
89 thay vì msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
86 sẽ dễ dàng hơn. Nhiều thư viện i18n tùy chỉnh từ các khung cũng sử dụng thứ gì đó tương tự như msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
39 để làm cho mã được dịch ngắn hơn. Tuy nhiên, đó là chức năng duy nhất có phím tắtBạn có thể muốn thêm vào dự án của mình một số thứ khác, chẳng hạn như
msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
70 hoặc msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
71 cho msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
30, hoặc có thể là một msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
73 ưa thích sẽ tham gia các cuộc gọi msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
86 và msgid ""
msgstr ""
"Language: pt_BR\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=[n > 1];\n"
msgid "We're now translating some strings"
msgstr "Nós estamos traduzindo algumas strings agora"
msgid "Hello %1$s! Your last visit was on %2$s"
msgstr "Olá %1$s! Sua última visita foi em %2$s"
msgid "Only one unread message"
msgid_plural "%d unread messages"
msgstr[0] "Só uma mensagem não lida"
msgstr[1] "%d mensagens não lidas"
75. Các thư viện khác, chẳng hạn như Gettext của oscarotero cũng cung cấp các hàm trợ giúp như thế nàyTrong những trường hợp đó, bạn sẽ cần hướng dẫn tiện ích Gettext cách trích xuất các chuỗi từ các hàm mới đó. Đừng sợ, nó rất dễ. Nó chỉ là một lĩnh vực trong. po hoặc màn hình Cài đặt trong Poedit [trong trình chỉnh sửa, tùy chọn đó nằm trong “Danh mục > Thuộc tính > Từ khóa nguồn”]
Nhớ lại. Gettext đã biết các chức năng mặc định cho nhiều ngôn ngữ, vì vậy đừng lo lắng nếu danh sách đó có vẻ trống. Bạn cần đưa vào danh sách đó các thông số kỹ thuật của các chức năng mới, theo định dạng cụ thể này
Nếu bạn tạo thứ gì đó như
39, chỉ trả về bản dịch cho một chuỗi, bạn có thể chỉ định nó làmsgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
77. Gettext sẽ biết đối số duy nhất của hàm là chuỗi cần dịch;msgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
Nếu hàm có nhiều hơn một đối số, bạn có thể chỉ định chuỗi đầu tiên thuộc chuỗi nào và, nếu cần, cả dạng số nhiều. Chẳng hạn, nếu chữ ký hàm của chúng ta là
78, thông số kỹ thuật sẽ làmsgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
79, nghĩa là biểu mẫu đầu tiên là đối số đầu tiên và biểu mẫu thứ hai là đối số thứ hai. Thay vào đó, nếu số của bạn xuất hiện dưới dạng đối số đầu tiên, thông số kỹ thuật sẽ làmsgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
80, biểu thị dạng đầu tiên là đối số thứ hai, v.v.msgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=[n > 1];\n" msgid "We're now translating some strings" msgstr "Nós estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Olá %1$s! Sua última visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "Só uma mensagem não lida" msgstr[1] "%d mensagens não lidas"
Sau khi bao gồm những quy tắc mới trong. po, một lần quét mới sẽ mang lại các chuỗi mới của bạn một cách dễ dàng như trước đây
Làm cho ứng dụng PHP của bạn trở nên đa ngôn ngữ với Gettext
Gettext là một công cụ rất mạnh để quốc tế hóa dự án PHP của bạn. Ngoài tính linh hoạt cho phép hỗ trợ một số lượng lớn ngôn ngữ của con người, nó còn hỗ trợ hơn 20 ngôn ngữ lập trình cho phép bạn dễ dàng chuyển kiến thức sử dụng nó với PHP sang các ngôn ngữ khác như Python, Java hoặc C#
Hơn nữa, Poedit có thể giúp làm trơn tru đường dẫn giữa mã và chuỗi đã dịch, làm cho quy trình trở nên đơn giản và dễ theo dõi hơn. Nó cũng có thể hợp lý hóa các nỗ lực dịch thuật được chia sẻ với tích hợp Crowdin của nó
Bất cứ khi nào có thể, hãy xem xét các ngôn ngữ khác mà người dùng của bạn có thể nói. Điều này chủ yếu quan trọng đối với các dự án không phải tiếng Anh. Bạn có thể tăng quyền truy cập của người dùng nếu bạn phát hành bằng tiếng Anh cũng như ngôn ngữ mẹ đẻ của mình
Tất nhiên, không phải tất cả các dự án đều có nhu cầu quốc tế hóa, nhưng việc bắt đầu i18n trong giai đoạn sơ khai của dự án sẽ dễ dàng hơn nhiều, ngay cả khi ban đầu không cần thiết, hơn là thực hiện sau này nếu sau đó trở thành một yêu cầu. Và, với các công cụ như Gettext và Poedit, việc này trở nên dễ dàng hơn bao giờ hết
Có liên quan. Giới thiệu về PHP 7. Có gì mới và những gì đã qua
Thẻ
PHPQuốc tế hóaPoeditGettextBản địa hóaNgười làm việc tự do? Tìm công việc tiếp theo của bạn.
Việc làm Lập trình viên PHP
Xem thông tin đầy đủ
Igor Santos
Kỹ sư phần mềm tự do
Thông tin về các Tác giả
Igor là một nhà phát triển web tập trung vào PHP và JS hiện đại, luôn phấn đấu cho các công nghệ mới. Khi anh ấy đội chiếc mũ back-end của mình, anh ấy tập trung vào hiệu suất và mã DRY, làm việc trên máy chủ API hoặc người tiêu dùng. Khi anh ấy đội chiếc mũ giao diện người dùng của mình, anh ấy sẽ làm việc chăm chỉ để duy trì trải nghiệm người dùng tốt nhất mà anh ấy có thể tạo ra cho người dùng của mình
Thuê Igor
Bình luận
Thiago Ghilardi
Tôi đã cân nhắc sử dụng gettext nhiều lần, nhưng rắc rối về cài đặt, các vấn đề về tính di động và chi phí phát sinh khiến tôi không thể sử dụng. Tôi hài lòng khi sử dụng mảng tĩnh. Có phải gettext có tính năng cho bạn biết tệp và dòng mã mà chuỗi được sử dụng không? . tập tin po. Bài viết hay và giới thiệu về công cụ này
Thiago Ghilardi
Tôi đã cân nhắc sử dụng gettext nhiều lần, nhưng rắc rối về cài đặt, các vấn đề về tính di động và chi phí phát sinh khiến tôi không thể sử dụng. Tôi hài lòng khi sử dụng mảng tĩnh. Có phải gettext có tính năng cho bạn biết tệp và dòng mã mà chuỗi được sử dụng không? . tập tin po. Bài viết hay và giới thiệu về công cụ này
Tập đoàn Alconost
Nếu bạn cần nội địa hóa không đau, hãy xem Alconost. Chúng tôi làm việc với các nhà phát triển phần mềm và công ty CNTT từ năm 2004. Công ty chúng tôi cung cấp gói dịch vụ dịch thuật và bản địa hóa toàn chu kỳ [58 ngôn ngữ], sẽ đảm bảo chất lượng bản dịch và quy trình làm việc cao nhất [e. g. trao đổi hợp lý các tệp tài nguyên, hiệu đính và kiểm soát chất lượng, Bộ nhớ dịch thuật, bảng thuật ngữ, một nhóm các nhà ngôn ngữ học được chọn làm việc trong một dự án, Trình quản lý tài khoản cá nhân, v.v. vân vân. ]. Tất cả các dịch giả của chúng tôi là người bản ngữ của ngôn ngữ mục tiêu. Chúng tôi làm việc với các văn bản ở bất kỳ định dạng nào và hoàn thành khoảng. 200 dự án nội địa hóa/hỗ trợ với nhiều quy mô khác nhau hàng tháng. Thả chúng tôi một dòng. http. // alconost. com/
Tập đoàn Alconost
Nếu bạn cần nội địa hóa không đau, hãy xem Alconost. Chúng tôi làm việc với các nhà phát triển phần mềm và công ty CNTT từ năm 2004. Công ty chúng tôi cung cấp gói dịch vụ dịch thuật và bản địa hóa toàn chu kỳ [58 ngôn ngữ], sẽ đảm bảo chất lượng bản dịch và quy trình làm việc cao nhất [e. g. trao đổi hợp lý các tệp tài nguyên, hiệu đính và kiểm soát chất lượng, Bộ nhớ dịch thuật, bảng thuật ngữ, một nhóm các nhà ngôn ngữ học được chọn làm việc trong một dự án, Trình quản lý tài khoản cá nhân, v.v. vân vân. ]. Tất cả các dịch giả của chúng tôi là người bản ngữ của ngôn ngữ mục tiêu. Chúng tôi làm việc với các văn bản ở bất kỳ định dạng nào và hoàn thành khoảng. 200 dự án nội địa hóa/hỗ trợ với nhiều quy mô khác nhau hàng tháng. Thả chúng tôi một dòng. http. // alconost. com/
Rasmus Schultz
Đó là bài viết chi tiết nhất về gettext mà tôi từng thấy cho đến nay ;-] Thực sự đáng chú ý là có rất nhiều điều để nói về một thứ mà cuối cùng lại khá đơn giản, nhưng vâng, dịch thuật là một chủ đề khá sâu sắc. Nếu bạn thấy giống như tôi, gettext đó không hoạt động tốt trong môi trường mô-đun [Nhà soạn nhạc] và các gói lớn mà bạn liệt kê là quá nhiều, hãy thử giải pháp thay thế nhẹ này. https. //github. com/mindplay-dk/lang Nó sử dụng một quy ước rất đơn giản [mà bạn có thể ghi đè lên] cho "các tệp ngôn ngữ", được tự động tìm thấy cho các gói Trình soạn thảo, nhưng có thể được thay thế trong dự án của bạn. Nó đã làm việc tuyệt vời cho chúng tôi cho đến nay. -]
Rasmus Schultz
Đó là bài viết chi tiết nhất về gettext mà tôi từng thấy cho đến nay ;-] Thực sự đáng chú ý là có rất nhiều điều để nói về một thứ mà cuối cùng lại khá đơn giản, nhưng vâng, dịch thuật là một chủ đề khá sâu sắc. Nếu bạn thấy giống như tôi, gettext đó không hoạt động tốt trong môi trường mô-đun [Nhà soạn nhạc] và các gói lớn mà bạn liệt kê là quá nhiều, hãy thử giải pháp thay thế nhẹ này. https. //github. com/mindplay-dk/lang Nó sử dụng một quy ước rất đơn giản [mà bạn có thể ghi đè lên] cho "các tệp ngôn ngữ", được tự động tìm thấy cho các gói Trình soạn thảo, nhưng có thể được thay thế trong dự án của bạn. Nó đã làm việc tuyệt vời cho chúng tôi cho đến nay. -]
igorsantos07
Và không phải là. po được tạo bởi gettext?. ] Cảm ơn cho những lời khen
igorsantos07
Và không phải là. po được tạo bởi gettext?. ] Cảm ơn cho những lời khen
igorsantos07
Cảm ơn vì lời khen, thưa ngài. ] Nhưng tôi nghĩ rằng tôi đã bỏ lỡ một cái gì đó. Có gì sai với Gettext và Composer?
igorsantos07
Cảm ơn vì lời khen, thưa ngài. ] Nhưng tôi nghĩ rằng tôi đã bỏ lỡ một cái gì đó. Có gì sai với Gettext và Composer?
Rasmus Schultz
Không, tôi ổn với tiện ích mở rộng. Tôi thấy rằng gettext sử dụng rất nhiều trạng thái toàn cầu và dựa vào thứ tự thực thi, không cái nào thực sự phù hợp với phát triển dựa trên thử nghiệm, mô hình xem, tiêm phụ thuộc, v.v. Tôi cũng không thích thực tế là bạn phải dự đoán và mã hóa các chi tiết dịch thuật [chẳng hạn như số nhiều] vào chế độ xem của mình - vì logic này có thể khác nhau giữa các ngôn ngữ, tôi thích đưa logic này [và bất kỳ logic nào khác] vào chính các tệp dịch. Đối với số lượng đường cong học tập, có cảm giác như quá phức tạp [quá nhiều khái niệm] so với những gì nó thực sự đạt được. Ví dụ, tôi không phải là người hâm mộ định dạng tệp độc quyền. Tôi thích các cơ sở mang lại cảm giác như ở nhà hơn bằng ngôn ngữ, e. g. sử dụng các nguyên hàm ngôn ngữ như mảng và gọi lại nếu có thể. Và vâng, có sự phụ thuộc nhị phân [kể từ khi bạn đưa nó lên], ý tôi là, tại sao? . -]
Rasmus Schultz
Không, tôi ổn với tiện ích mở rộng. Tôi thấy rằng gettext sử dụng rất nhiều trạng thái toàn cầu và dựa vào thứ tự thực thi, không cái nào thực sự phù hợp với phát triển dựa trên thử nghiệm, mô hình xem, tiêm phụ thuộc, v.v. Tôi cũng không thích thực tế là bạn phải dự đoán và mã hóa các chi tiết dịch thuật [chẳng hạn như số nhiều] vào chế độ xem của mình - vì logic này có thể khác nhau giữa các ngôn ngữ, tôi thích đưa logic này [và bất kỳ logic nào khác] vào chính các tệp dịch. Đối với số lượng đường cong học tập, có cảm giác như quá phức tạp [quá nhiều khái niệm] so với những gì nó thực sự đạt được. Ví dụ, tôi không phải là người hâm mộ định dạng tệp độc quyền. Tôi thích các cơ sở mang lại cảm giác như ở nhà hơn bằng ngôn ngữ, e. g. sử dụng các nguyên hàm ngôn ngữ như mảng và gọi lại nếu có thể. Và vâng, có sự phụ thuộc nhị phân [kể từ khi bạn đưa nó lên], ý tôi là, tại sao? . -]
vlađimia
Đây là một bài viết rất thú vị và nó truyền cảm hứng cho tôi để thử gettext với poedit. Tôi đang mở bài viết này trong trình duyệt của mình trong nhiều ngày trong khi tôi khám phá gettext. ;] Tôi hiện đang xây dựng khung trang web của riêng mình và đã triển khai hệ thống của riêng mình, nơi tất cả các bản dịch được đặt trong tệp JSON có khóa và giá trị. Khi thay đổi ngôn ngữ, chỉ có json khác nhau được tải. Vì gettext rõ ràng có nhiều chức năng nâng cao hơn nên tôi đang cân nhắc sử dụng nó. Tôi đã tự hỏi, vì bạn rõ ràng là Igor có nhiều kinh nghiệm về việc này, việc triển khai gettext này tốn bao nhiêu tiền khi nói đến tài nguyên máy chủ trên các trang web lớn và chúng tôi có thể làm gì để tối ưu hóa nó?
vlađimia
Đây là một bài viết rất thú vị và nó truyền cảm hứng cho tôi để thử gettext với poedit. Tôi đang mở bài viết này trong trình duyệt của mình trong nhiều ngày trong khi tôi khám phá gettext. ;] Tôi hiện đang xây dựng khung trang web của riêng mình và đã triển khai hệ thống của riêng mình, nơi tất cả các bản dịch được đặt trong tệp JSON có khóa và giá trị. Khi thay đổi ngôn ngữ, chỉ có json khác nhau được tải. Vì gettext rõ ràng có nhiều chức năng nâng cao hơn nên tôi đang cân nhắc sử dụng nó. Tôi đã tự hỏi, vì bạn rõ ràng là Igor có nhiều kinh nghiệm về việc này, việc triển khai gettext này tốn bao nhiêu tiền khi nói đến tài nguyên máy chủ trên các trang web lớn và chúng tôi có thể làm gì để tối ưu hóa nó?
vlađimia
It is important to anticipate plurals in your translation. Because programmers have forgot to do that, I am constantly having problems translating different programs on Serbian, which have one of the most complex plural rules. nplurals=3; plural=[n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%101 = số nhiều]
igorsantos07
Tôi phải nói rằng tôi cũng tò mò về một số phản hồi về điều đó. Ý tưởng chỉ viết một biểu mẫu và để lại các dạng số nhiều cho tệp lang có vẻ khá hấp dẫn, mặc dù tôi không chắc nó sẽ hoạt động như thế nào trong thực tế. Tôi muốn nói rằng, trong các ngôn ngữ phức tạp như tiếng Serbia, việc có thể bỏ logic số nhiều bên trong thư viện và chỉ cần cung cấp "mẫu 1, mẫu 2, mẫu 3" là rất tiện dụng. Tôi có thể dễ dàng thấy thư viện đó sẽ dễ bị lỗi như thế nào với logic số nhiều được lặp lại, gọi lại sau khi gọi lại. Tôi có lẽ sẽ kết thúc việc viết một số chức năng trợ giúp cho phép tôi chỉ cung cấp các biểu mẫu thay vì viết logic số nhiều. Ngay cả trong tiếng Bồ Đào Nha, quy tắc đó rất đơn giản [>1 = số nhiều]
igorsantos07
Có ý tưởng bây giờ. Thư viện có vẻ khá thú vị, thực sự. So sánh với một người khổng lồ [được biên dịch] chẳng hạn như Gettext, bạn có biết thư viện đó sẽ hoạt động như thế nào với một số tệp lang "lớn" không?
igorsantos07
Có ý tưởng bây giờ. Thư viện có vẻ khá thú vị, thực sự. So sánh với một người khổng lồ [được biên dịch] chẳng hạn như Gettext, bạn có biết thư viện đó sẽ hoạt động như thế nào với một số tệp lang "lớn" không?
Rasmus Schultz
Nếu tiếng Serbia có các quy tắc rất phức tạp, có thể triển khai các chức năng đó trong một thư viện độc lập. Sau đó, chỉ cần e. g. `trả lại tiếng Serbia. số nhiều["dạng 1", "dạng 2", "dạng 3"]` v.v. Giữ nó đơn giản. Mọi người đều biết cách thực hiện một lệnh gọi hàm đơn giản - phát minh ra một cú pháp tùy chỉnh làm tăng thêm độ phức tạp và đường cong học tập. Những gì bạn cần là sử dụng lại chức năng đơn giản - ngôn ngữ có điều đó, vì vậy một cú pháp tùy chỉnh phần lớn sẽ chỉ là mỹ phẩm
Rasmus Schultz
Nếu tiếng Serbia có các quy tắc rất phức tạp, có thể triển khai các chức năng đó trong một thư viện độc lập. Sau đó, chỉ cần e. g. `trả lại tiếng Serbia. số nhiều["dạng 1", "dạng 2", "dạng 3"]` v.v. Giữ nó đơn giản. Mọi người đều biết cách thực hiện một lệnh gọi hàm đơn giản - phát minh ra một cú pháp tùy chỉnh làm tăng thêm độ phức tạp và đường cong học tập. Những gì bạn cần là sử dụng lại chức năng đơn giản - ngôn ngữ có điều đó, vì vậy một cú pháp tùy chỉnh phần lớn sẽ chỉ là mỹ phẩm
igorsantos07
Vâng. đó là thứ tôi đã từng nghĩ đến. ] có lẽ bạn có thể đề xuất kiểu tiếp cận này [điểm thưởng với mã mẫu] trong tệp readme?
igorsantos07
Vâng. đó là thứ tôi đã từng nghĩ đến. ] có lẽ bạn có thể đề xuất kiểu tiếp cận này [điểm thưởng với mã mẫu] trong tệp readme?
Jason bạc
Có lẽ bạn có thể giải thích về phần về các quốc gia khác nhau? . Để gettext hoạt động chính xác, tôi có cần tạo thêm tệp po cho mọi quốc gia không? . acceptFromHttp[$_SERVER['HTTP_ACCEPT_LANGUAGE']];
Jason bạc
Có lẽ bạn có thể giải thích về phần về các quốc gia khác nhau? . Để gettext hoạt động chính xác, tôi có cần tạo thêm tệp po cho mọi quốc gia không? . acceptFromHttp[$_SERVER['HTTP_ACCEPT_LANGUAGE']];
Jason bạc
Đừng bận tâm, tôi tình cờ tìm thấy câu trả lời. Chúng tôi không cần xử lý các ngôn ngữ khác nhau, chỉ cần tạo một ngôn ngữ 'es', chẳng hạn như bằng tiếng Tây Ban Nha và textedit sẽ tìm ra liệu có ngôn ngữ phù hợp hay không, ngay cả khi chúng đến từ Colombia, Tây Ban Nha hoặc Mexico. Vì vậy, không cần phải bùng nổ trên gạch dưới. Nếu bạn muốn cụ thể về cách viết, ví dụ như cách viết của Canada, thì hãy tạo một ngôn ngữ en_CA bổ sung với các chỉnh sửa đó trong đó
Jason bạc
Đừng bận tâm, tôi tình cờ tìm thấy câu trả lời. Chúng tôi không cần xử lý các ngôn ngữ khác nhau, chỉ cần tạo một ngôn ngữ 'es', chẳng hạn như bằng tiếng Tây Ban Nha và textedit sẽ tìm ra liệu có ngôn ngữ phù hợp hay không, ngay cả khi chúng đến từ Colombia, Tây Ban Nha hoặc Mexico. Vì vậy, không cần phải bùng nổ trên gạch dưới. Nếu bạn muốn cụ thể về cách viết, ví dụ như cách viết của Canada, thì hãy tạo một ngôn ngữ en_CA bổ sung với các chỉnh sửa đó trong đó
igorsantos07
Đúng. Bạn chỉ cần chỉ định ngôn ngữ quốc gia nếu ngôn ngữ chính là ngôn ngữ chính [tôi. e. "en", "es", "pt"] không đủ cho mọi quốc tịch mà bạn muốn hỗ trợ
igorsantos07
Đúng. Bạn chỉ cần chỉ định ngôn ngữ quốc gia nếu ngôn ngữ chính là ngôn ngữ chính [tôi. e. "en", "es", "pt"] không đủ cho mọi quốc tịch mà bạn muốn hỗ trợ
Jason bạc
rất tiếc, ý tôi là 'gettext' chứ không phải 'textedit'
Jason bạc
rất tiếc, ý tôi là 'gettext' chứ không phải 'textedit'
Vasiliy Pyatykh
Một số mẹo khắc phục cho những ai đang muốn bật gettext cho project theo hướng dẫn này. * để lệnh gọi `setlocale[$lang]` thành công, $lang được cung cấp phải khớp chính xác với một số ngôn ngữ có sẵn trên hệ thống của bạn, danh sách là đầu ra của `locale -a`. Nó có thể là một vấn đề nếu bạn đang sử dụng, ví dụ, bộ chứa docker php-fpm chính thức, không có bất kỳ ngôn ngữ nào được cài đặt theo mặc định, vì vậy bạn phải tự làm điều đó. * mọi thứ hoạt động mà không cần putenv["LANG=$lang"]; . * đừng bỏ lỡ sự thật rằng *. po và *. mo phải được đặt tên là "miền" mà bạn đang nhắm mục tiêu trong ứng dụng của mình - "chính" trong bài viết này. Vì lý do không rõ, chương trình PoEdit đã tạo chúng với tên sai cho tôi, điều này khiến tôi mất thời gian gỡ lỗi khó chịu
Ivan Argulo
Tôi biết đây là một chủ đề khá cũ, nhưng vẫn hữu ích cho nhiều dự án lớn của chúng tôi. Tuy nhiên, tôi đang gặp sự cố với bản dịch tiếng Ả Rập. Hiện tại, tôi có tiếng Tây Ban Nha [mặc định] và tiếng Anh với gettext, hoạt động tốt. Khi tôi cố gắng thêm tiếng Ả Rập hoặc ngôn ngữ ar_AE chẳng hạn, tôi không nhận được gì. chỉ là mặc định. Tôi đã cài đặt ngôn ngữ [ngôn ngữ -a hiển thị tất cả] và khởi động lại apache, nhưng không có gì hoạt động. Bất kì lời đề nghị nào?