Làm cách nào để triển khai các bản dịch trong gói thiết kế của CSV? Làm thế nào để echo $ this -> __ ('Văn bản') hoạt động?


29

Tôi có một thiết kế gói thiết kế như vậy:

design/frontend/package_name/theme_name/locale/

theo đó tôi có

de_DE, en_GBv.v., theo đó tôi có translate.csvcác tệp tương ứng với các chuỗi khác nhau:"Key", "Translation"

Tôi đang cố gắng thực hiện các chuỗi khác nhau trong chủ đề của mình bằng cách sử dụng echo $this->__('Text')

Tuy nhiên, nó dường như không hoạt động (tôi chỉ thấy chuỗi bên trong ('Text')được hiển thị). Tôi nghĩ rằng tôi đang thiếu một số hiểu biết cơ bản về thời điểm Magento kéo các chuỗi từ CSV được dịch. Ai đó có thể vui lòng giải thích làm thế nào để các tập tin csv này hoạt động?


Phiên bản nào của Magento bạn đang chạy?
philwinkle

Tôi đang sử dụng Magento v: 1.7.0.2
waffl

Bạn đang gọi cái này bên ngoài một tệp mẫu magento bình thường? Có lẽ bạn cần gọi lớp người trợ giúp và biến nó thành một cái gì đó như <? Php echo Mage :: helper ('core') -> __ ('Text'); ?> Đồng thời thử bật "Dịch nội tuyến" trên Frontend trong Hệ thống> Cấu hình> Nhà phát triển
SaveTheMage

Câu trả lời:


84

TL; DR

Nếu bạn không quan tâm đến các chi tiết về cách dịch hoạt động, hãy bỏ qua nội dung đến phần
Kiểm tra xem bản dịch của bạn không hoạt động bên dưới, đặc biệt là phần phụ
Giải pháp cho Xung đột dịch thuật Mô-đun .

Tổng quan về dịch thuật Magento

Magento ưu tiên các nguồn dịch (từ cao nhất đến thấp nhất):

  1. DB ( core_translate bảng)
  2. Chủ đề translate.csv tập tin
  3. Các app/locale/*/*.csv tập tin

Làm thế nào là mảng dịch được xây dựng?

Dịch thuật mô-đun

Đầu tiên tất cả các tệp từ app/locale/*/*.csvđó được tham chiếu từ các etc/config.xmltệp mô-đun hoạt động được phân tích cú pháp. Đây là hướng dẫn của quy trình:
Giả sử Magento tìm thấy phần sau config.xml:

<!-- excerpt from Mage/Catalog/etc/config.xml -->
<frontend>
    <translate>
        <modules>
            <Mage_Catalog>
                <files>
                    <default>Mage_Catalog.csv</default>
                </files>
            </Mage_Catalog>
        </modules>
    </translate>
</frontend>

Và trong tệp đó, bản dịch sau được chỉ định cho ngôn ngữ được định cấu hình cho chế độ xem cửa hàng hiện tại:

"AAA","BBB"

Trong các trường hợp này, Magento tạo các bản ghi sau trong mảng dịch:

array(
    "AAA" => "BBB",
    "Mage_Catalog::AAA" => "BBB"
)

Giá trị thứ hai là Dịch thuật Phạm vi Mô-đun . Tên mô-đun tiền tố được lấy từ nút XML cấu hình có chứa khai báo tệp dịch.

Nếu bản dịch tương tự được quy định một lần nữa bằng một tập tin mô-đun thứ hai , ví dụ như trong Some_Module.csvbản dịch "AAA","CCC", nó sẽ không ghi đè lên các "AAA"thiết lập. Thay vào đó, nó sẽ chỉ thêm một bản ghi mới với tên mô-đun thứ hai "Some_Module::AAA" => "CCC".

Nếu chế độ nhà phát triển được kích hoạt, nó thậm chí sẽ bỏ đặt các"AAA" kỷ lục nếu nó tìm thấy một kỷ lục thứ hai với cùng một chìa khóa trong một dịch module. Điều này giúp dễ dàng phát hiện xung đột dịch mô-đun trong quá trình phát triển.

Dịch chủ đề

Thứ hai, các bản dịch được tải từ translate.csvtệp đầu tiên trong dự phòng chủ đề cho ngôn ngữ hiện tại chỉ đơn giản là thay thế các bản ghi hiện có trong mảng dịch.
Vì vậy, tiếp tục ví dụ trước, một translate.csvbản ghi "AAA","DDD"sẽ dẫn đến dữ liệu dịch sau:

array(
    "AAA" => "DDD", // This is overwritten by the translate.csv file
    "Mage_Catalog::AAA" => "BBB",
    "Some_Module::AAA" => "CCC"
)

Tất nhiên các bản ghi trong các translate.csvkhóa dịch mới chỉ đơn giản được thêm vào mảng.

Dịch thuật cơ sở dữ liệu

Các bản dịch từ core_translatebảng về cơ bản được hợp nhất vào mảng dịch giống như các bản dịch chủ đề.
Các khóa hiện có từ mô-đun hoặc bản dịch chủ đề được ghi đè bằng các bản ghi cơ sở dữ liệu, các khóa mới được thêm vào.

Tra cứu dịch thuật

Khi __()phương thức được gọi, trước tiên Magento tìm một bản dịch trong mảng khớp với mô-đun hiện tại.
Mô-đun hiện tại được xác định bởi tên lớp mà __()lớp được gọi. Ví dụ, trong các khối, phương thức chịu trách nhiệm trông như thế này:

// Excerpt from Mage/Core/Block/Abstract.php
public function getModuleName()
{
    $module = $this->getData('module_name');
    if (is_null($module)) {
        $class = get_class($this);
        $module = substr($class, 0, strpos($class, '_Block'));
        $this->setData('module_name', $module);
    }
    return $module;
}

Các phương thức trong Bộ trợ giúp và Bộ điều khiển hoạt động tương ứng.

Kịch bản tra cứu ví dụ

Ví dụ, giả sử $this->__('AAA')được gọi trong tệp mẫu. Nếu khối liên kết có loại Mage_Core_Block_Template, trước tiên Magento sẽ kiểm tra Mage_Core::AAAbản ghi. Nếu nó không tìm thấy nó, nó sẽ quay trở lại bản dịch cho khóa AAA.
Trong kịch bản ví dụ, điều này sẽ dẫn đến việc dịch DDD(từ translate.csvtệp).

Trong một kịch bản khác, khối liên quan có thể là Mage_Catalog_Block_Product_View. Trong trường hợp này, Magento trước tiên sẽ kiểm tra bản ghi dịch Mage_Catalog::AAAvà sẽ tìm bản dịch AAA.

Vì vậy, trong thực tế, các bản dịch phạm vi mô-đun có mức độ ưu tiên cao hơn bất kỳ bản dịch chung nào . Dịch thuật nào được sử dụng phụ thuộc vào mô-đun mà lớp gọi từ __()phương thức.

Kiểm tra xem bản dịch của bạn không hoạt động

Nếu bản dịch của bạn từ một translate.csvtệp không được sử dụng, hãy làm theo danh sách kiểm tra này:

  1. Bộ đệm dịch có bị tắt / làm mới không? (Giải pháp: xóa bộ nhớ cache)
  2. translate.csvtập tin thực sự trong dự phòng chủ đề cho các cửa hàng hiện tại? (Giải pháp: sửa cấu hình chủ đề)
  3. Có một bản ghi mâu thuẫn cho bản dịch trong core_translatebảng không? (Giải pháp: xóa bản ghi xung đột khỏi core_translate)
  4. Nếu tất cả các điểm trước đó không phải là nguyên nhân, thì phải có một bản dịch mâu thuẫn từ một mô-đun khác. (Giải pháp: xem bên dưới)

Giải pháp cho xung đột dịch thuật mô-đun

Nếu bạn tìm thấy những trường hợp cuối cùng là đúng, chỉ cần thêm bản dịch một lần thứ hai để bạn translate.csv phạm vi mô-đun của module làm bản dịch.
Trong ví dụ, nếu bạn luôn muốn AAAđược dịch là DDDthông qua bản dịch chủ đề, bạn có thể thực hiện việc này trong translate.csv:

"AAA","DDD"
"Mage_Catalog::AAA","DDD"
"Some_Module::AAA","DDD"

Trong thực tế, tôi chỉ thêm phạm vi mô-đun vào bản dịch nếu có xung đột, nghĩa là, nếu bản dịch không hoạt động.

Ghi chú bổ sung

Dịch nội tuyến

Tính năng dịch nội tuyến của Magento cũng thêm các bản dịch tùy chỉnh vào core_translatebảng bằng cách sử dụng tiền tố phạm vi mô-đun.

Khả năng tương thích ngược

Mức độ ưu tiên của các bản dịch chủ đề được sử dụng cao hơn sau đó cơ sở dữ liệu dịch lên phiên bản Magento 1.3 trở lên.

Dịch thuật XML

Magento đôi khi đánh giá translate=""lập luận trong config.xml, system.xmlvà bố trí XML để dịch các giá trị nút con.
Một lớp trình trợ giúp có thể được chỉ định trong các trường hợp đó bằng cách sử dụng module=""đối số để chỉ định mô-đun cho phạm vi dịch.
Nếu không có moduleđối số nào được chỉ định trong XML, trình core/datatrợ giúp được sử dụng để dịch các giá trị nút con.

Thêm thông tin

Tôi thú nhận rằng tôi đã trình bày một số chi tiết về quy trình dịch thuật Magento trong bài viết này, nhưng chỉ vì tôi không muốn có quá nhiều thông tin.

  • Một số chi tiết kỹ thuật trong khi mảng dịch được xây dựng
  • Khả năng sử dụng các tệp dịch bổ sung cho các mô-đun
  • Lưu trữ phạm vi xem core_translatehồ sơ
  • Ưu và nhược điểm sử dụng các phương pháp dịch thuật khác nhau

Vui lòng hỏi một câu hỏi riêng nếu cần thêm thông tin.


1
OK, tôi vô cùng xin lỗi tất cả mọi người, nhưng một người khác đã bật bộ đệm mà không cho tôi biết ... Có lẽ là lúc tôi bắt đầu làm việc với các bản dịch. Thở dài. Thông tin này cực kỳ hữu ích cho sự hiểu biết của tôi về quá trình dịch thuật trong Magento. Rất cám ơn, điều này chắc chắn trả lời tất cả các câu hỏi tôi có về cách thức __()hoạt động của chức năng.
waffl

Một tổng quan khá tốt về kiến ​​trúc dịch thuật của Magento cũng có thể được tìm thấy ở đây: gist.github.com/antonmakarenko/7538216
thdoan

@Vinai, câu trả lời tuyệt vời. Nó thực sự giúp tôi giải quyết vấn đề dịch thuật, tôi đã đăng một câu hỏi lên đây . Đáng ngạc nhiên là Mage_Tax đã mâu thuẫn với các bản dịch của chủ đề của tôi, điều này dường như trái ngược với cách Magento có nghĩa là ưu tiên các bản dịch
Holly

14

Nguồn dịch

Các bản dịch được hợp nhất từ ​​các nguồn khác nhau: Bản dịch mô-đun từ các tệp XML tương ứng, bản dịch chủ đề từtranslate.csv chủ đề hiện tại và bản dịch nội tuyến từ cơ sở dữ liệu.

Các bản dịch có thể là mô-đun cụ thể (chỉ hợp lệ trong một mô-đun), đó luôn là trường hợp cho các bản dịch nội tuyến và tùy chọn cho các bản dịch chủ đề. Để đạt được điều này, bạn phải xác định chúng với tiền tố mô-đun trong transl.csv:

"Mage_Catalog::Add to cart","In die Einkaufstüte legen"

Các bản dịch từ các mô-đun (như Mage_Catalog.csv) chỉ là mô-đun cụ thể, nếu CHẾ ĐỘ PHÁT TRIỂN được bật. Mặt khác, bản dịch cho mô-đun được tải đầu tiên được sử dụng trên toàn cầu cho tất cả các mô-đun không có bản dịch riêng cho văn bản.

Tôi đã tập hợp một biểu đồ cho thấy cách mỗi văn bản từ các nguồn khác nhau được hợp nhất trong mảng dịch:

Hợp nhất dịch data là mảng dịch

Trường hợp Evil Edge

Nếu chuỗi dịch bằng với chuỗi chưa được dịch, bản dịch bị bỏ qua. Thoạt nghe có vẻ như tối ưu hóa hữu ích, nhưng theo cách này, bạn không thể dễ dàng dịch một chuỗi không thay đổi trong một mô-đun và thay đổi trong một mô-đun khác, bởi vì bản dịch đã thay đổi sẽ là bản duy nhất và trở thành toàn cầu.

Tra cứu dịch thuật

Đối với mô-đun dịch nào được tra cứu, phụ thuộc vào mô-đun của lớp, theo đó phương thức __()đã được gọi. Sau đó, việc tra cứu trong mảng dịch như sau:

Tra cứu dịch thuật data là mảng dịch

Định nghĩa phạm vi

Có khả năng thay đổi mô-đun cho một lớp, điều này đặc biệt hữu ích cho các khối và người trợ giúp. Thực hành tốt nhất là luôn luôn đặt tên mô-đun một cách rõ ràng khi viết lại một lớp lõi. Cách thức hoạt động, khác nhau giữa Người trợ giúp, Khối và Người điều khiển (kể từ Magento CE 1.9.1)

Ví dụ cho khối:

class IntegerNet_AwesomeModule_Block_Catalog_Product extends Mage_Catalog_Block_Product
{
    public function getModuleName()
    {
        return 'Mage_Catalog';
    }
}

Đối với các khối, bạn cũng có thể đặt module_nametham số trong bố cục XML:

<block type="integernet_awesomemodule/catalog_product" name="test" module_name="Mage_Catalog" />

Ví dụ cho người trợ giúp:

class IntegerNet_AwesomeModule_Helper_Catalog extends Mage_Catalog_Helper_Data
{
    protected $_moduleName = 'Mage_Catalog';
}

Đối với bộ điều khiển lối vào, bạn có thể đặt thuộc tính _realModuleName, cho bộ điều khiển quản trị viên, _usedModuleName(yay cho tính nhất quán)

Phương pháp dịch thuật khác

Trong các tệp XML (config.xml, system.xml, layout), bạn có thể chỉ định nếu các nút nên được dịch với translatethuộc tính. Bạn cũng nên thêm modulethuộc tính để chỉ định phạm vi, nhưng ở đây giá trị phải là bí danh của người trợ giúp , không phải tên mô-đun như trên.

<one_column module="page" translate="label">
    <label>1 column</label>
    <template>page/1column.phtml</template>
    <layout_handle>page_one_column</layout_handle>
    <is_default>1</is_default>
</one_column>

Trong JavaScript, bạn có thể sử dụng Translatorđối tượng có sẵn trên toàn cầu:

Translator.translate('Please wait, loading...');

nhưng bạn phải làm cho các bản dịch mà bạn muốn sử dụng trong JavaScript có sẵn cho đối tượng người dịch. Điều này được thực hiện thông qua jstranslator.xmlcác tập tin trong các etcthư mục của các mô-đun.

<?xml version="1.0"?>
<jstranslator>
    <loading translate="message" module="core">
        <message>Please wait, loading...</message>
    </loading>
</jstranslator>

loadingcó thể là bất kỳ chuỗi nào nhưng phải là duy nhất trên toàn cầu. Các thuộc tính translatemoduleđược sử dụng như trong các tệp XML khác. Giá trị messagevà bản dịch của nó được thêm vào đối tượng Trình dịch JS.

Xử lý sự cố

Ngay cả khi bạn biết tất cả các quy tắc phức tạp, đôi khi thật khó để biết lý do tại sao một số bản dịch lại hoạt động như vậy (hoặc không hoạt động). Để làm cho điều này dễ dàng hơn, tôi đã phát triển một mô-đun "Gợi ý dịch thuật" cho biết các bản dịch đến từ đâu:

Lấy nó ở đây: https://github.com/schmengler/TranslationH gợi ý

Ảnh chụp màn hình: Gợi ý dịch thuật


Dựa trên các bài đăng trên blog của tôi và các slide về chủ đề:


2
Tôi hy vọng tôi không spam bằng cách đề cập rằng mô-đun Yireo EmailOverride miễn phí của tôi sẽ cho phép các tệp mô-đun CSV tùy chỉnh cũng được đặt trong chủ đề. Không chỉ dịch.csv.
Jisse Reitsma

6

Bạn đã xóa bộ nhớ cache của bạn?

Hệ thống của bạn có được đặt ở vị trí của tệp bạn đang kiểm tra không?

Magento có thể tìm thấy tệp mà nó đang tìm khi tải bản dịch chủ đề không (một số tạm thời var_dump; thoát; các câu lệnh sẽ giúp ích.

#File: app/code/core/Mage/Core/Model/Translate.php
protected function _loadThemeTranslation($forceReload = false)
{
    $file = Mage::getDesign()->getLocaleFileName('translate.csv');
    $this->_addData($this->_getFileData($file), false, $forceReload);
    return $this;
}

_getTranslatedStringPhương thức có thể tìm thấy những gì nó đang tìm kiếm trong mảng dữ liệu không?

#File: app/code/core/Mage/Core/Model/Translate.php
protected function _getTranslatedString($text, $code)
{
    $translated = '';
    if (array_key_exists($code, $this->getData())) {
        $translated = $this->_data[$code];
    }
    elseif (array_key_exists($text, $this->getData())) {
        $translated = $this->_data[$text];
    }
    else {
        $translated = $text;
    }
    return $translated;
}

Không có bộ nhớ cache nào đang hoạt động, tôi không chắc hệ thống của mình có được đặt thành ngôn ngữ không, nhưng các bản dịch hoạt động trong các tệp mẫu nhất định phù hợp (bằng cách thay đổi cửa hàng). Ví dụ: một chuỗi trong tôi translate.csvdịch đúng /app/design/frontend/package_name/default/template/catalog/product/view.phtmlnhưng không phải trong/app/design/frontend/package_name/default/template/page/html/topmenu.phtml
waffl

Bạn đã đúng, ai đó bật bộ nhớ cache mà không cho tôi biết. Rất tiếc, lời xin lỗi của tôi và cảm ơn bạn đã thông tin!
waffl

3
@waffl Không cần phải xin lỗi - Tôi nghĩ rằng mọi nhà phát triển Magento đều làm điều đó ít nhất một lần một tuần.
Alan Storm
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.