2009-11-20 40 views
11

Trong php (hoặc có thể là gettext nói chung), gettext làm gì khi nó thấy một biến thành nội dung động?Gettext xử lý nội dung động như thế nào?

Tôi có 2 trường hợp cần lưu ý.

1) Giả sử tôi có <?=$user1?> poked John <?=$user2?>. Có thể bằng ngôn ngữ nào đó thứ tự của các từ khác nhau. Gettext xử lý như thế nào? (không, tôi không xây dựng facebook, đó chỉ là một ví dụ)

2) Giả sử tôi lưu trữ một số danh mục trong cơ sở dữ liệu. Họ hiếm khi, nhưng chúng được lưu trữ trong một cơ sở dữ liệu. Điều gì sẽ xảy ra nếu tôi làm <?php echo gettext($data['name']); ?>? Tôi cũng muốn các dịch giả dịch các tên danh mục đó, nhưng nó có phải được thực hiện trong chính cơ sở dữ liệu không?

Cảm ơn

+1

Độc giả của câu hỏi này cũng có thể quan tâm đến "Cách chỉ định biến số đặt hàng trong tệp gettext .po?": Http://stackoverflow.com/questions/13979962/how-to -specify-ordered-variables-in-gettext-po-files – Ryan

Trả lời

19

Tùy chọn tốt nhất của bạn là sử dụng hàm spritf(). Sau đó, bạn sẽ sử dụng ký pháp printf để xử lý nội dung động trong chuỗi của bạn. Đây là một chức năng tôi tìm thấy trên đây một thời gian trước đây để xử lý việc này một cách dễ dàng cho bạn:

function translate() 
{ 
    $args = func_get_args(); 
    $num = func_num_args(); 
    $args[0] = gettext($args[0]); 

    if($num <= 1) 
     return $args[0]; 

    return call_user_func_array('sprintf', $args); 

} 

Bây giờ ví dụ 1, bạn sẽ muốn thay đổi chuỗi để:

%s poked %s 

mà bạn sẽ đầu vào vào hàm translate() như sau:

<?php echo translate('%s poked %s', $user1, $user2); ?> 

Bạn sẽ phân tích tất cả hàm translate() bằng poEdit. và sau đó dịch chuỗi "% s poked% s" sang bất kỳ ngôn ngữ nào bạn muốn, mà không sửa đổi các phần giữ chỗ chuỗi % s. Chúng sẽ được thay thế khi đầu ra bởi hàm translate() với user1 và user2 tương ứng. Bạn có thể đọc thêm về sprintf() trong Hướng dẫn sử dụng PHP để có các tập quán nâng cao hơn.

Đối với số 2. Bạn sẽ cần phải tạo một tệp tĩnh mà poEdit có thể phân tích cú pháp chứa các tên danh mục. Ví dụ: "misctranslations.php":

<?php 

_('Cars'); 
_('Trains'); 
_('Airplanes'); 

Sau đó có poEdit parse misctranslations.php. Sau đó, bạn có thể xuất bản dịch tên danh mục bằng cách sử dụng <?php echo gettext($data['name']); ?>

+4

Trường hợp 1 có thể được xử lý dễ dàng hơn: ' '. Bạn không cần một hàm phụ và poedit sẽ vẫn phân tích chuỗi ký tự tốt như bất kỳ chuỗi nào khác. – DanMan

+1

Nếu bạn đang dịch "% s poked% s" làm cách nào bạn có thể trao đổi tên của hai người dùng khi cả hai đều được đánh dấu bằng cùng một trình giữ chỗ? Trong một số ngôn ngữ, chủ đề này đi trước đối tượng. – bdsl

4

Để xây dựng một chút về những gì Mark nói ... vấn đề duy nhất với giải pháp trên là danh sách tĩnh phải luôn được duy trì bằng tay và nếu bạn thêm một chuỗi mới trước tất cả những người khác hoặc bạn hoàn toàn thay đổi một chuỗi hiện có, phần mềm bạn sử dụng để dịch có thể làm xáo trộn các chuỗi mới và bạn có thể mất một số bản dịch.

Tôi thực sự viết một bài báo về vấn đề này (quá ít thời gian để hoàn thành nó bất cứ lúc nào sớm!) Nhưng câu trả lời đề xuất của tôi đi một cái gì đó như thế này:

gettext cho phép bạn lưu trữ các số dòng rằng chuỗi xuất hiện trong mã bên trong tệp .po. Nếu bạn thay đổi chuỗi hoàn toàn, trình soạn thảo .po sẽ biết rằng chuỗi không phải là mới nhưng nó là một chuỗi cũ (nhờ vào số dòng).

Giải pháp của tôi cho điều này là viết một tập lệnh đọc cơ sở dữ liệu và tạo một tệp tĩnh với tất cả các chuỗi gettext. Sự khác biệt lớn đối với giải pháp của Mark là có khóa chính (chúng ta hãy gọi nó là ID) trên cơ sở dữ liệu khớp với số dòng trong tệp mới. Trong trường hợp đó, nếu bạn thay đổi hoàn toàn một bản dịch gốc, các dòng vẫn giống nhau và phần mềm dịch của bạn sẽ nhận ra các chuỗi.

Tất nhiên có thể có trình chỉnh sửa .po mới hơn và thông minh hơn ngoài đó, nhưng ít nhất nếu bạn đang gặp rắc rối với các chuỗi mới hơn thì điều này sẽ giải quyết chúng.

2 xu của tôi.

1

@Julian

Tôi nghĩ cách tiếp cận của bạn sẽ không hoạt động tốt trong thực tế. Hãy tưởng tượng, bạn di chuyển một số chức năng trên mã. Số dòng sẽ khác nhau, tên tệp có thể khác nhau.

Tôi nghĩ cách thông minh duy nhất để quản lý việc thay đổi id dịch sẽ là tìm các id tương tự trong tệp .po của bạn. Trình chỉnh sửa có thể hiển thị đề xuất cho việc hợp nhất văn bản dịch mới với văn bản hiện có, nếu chúng rất giống nhau và không có chuỗi dịch trong số dòng đã lưu trong mã của bạn.

1

Nếu bạn có một nơi nào đó trong mã của mình: <?=sprintf(_('%s poked %s'), $user1, $user2)?> và một trong các ngôn ngữ của bạn cần trao đổi các đối số rất đơn giản. Chỉ cần dịch mã của bạn như thế này: msgid "%s poked %s" msgstr "%2$s translation_of_poked %1$s"

Các vấn đề liên quan