12/08/2018, 15:11

Giải pháp đa ngôn ngữ với Json File trong Laravel 5.4

Thông thường nêu chúng ta dùng đa ngôn ngữ thì thường dùng phần locale default của Laravel 5.x. Là định nghĩa các text cần translate trong các file được đặt ở resources/lang/en/example.php. Nhưng nếu gặp các site có lượng request truy cập nhiều thì đòi hỏi việc translate này cần được optimize hơn. ...

Thông thường nêu chúng ta dùng đa ngôn ngữ thì thường dùng phần locale default của Laravel 5.x. Là định nghĩa các text cần translate trong các file được đặt ở resources/lang/en/example.php. Nhưng nếu gặp các site có lượng request truy cập nhiều thì đòi hỏi việc translate này cần được optimize hơn. Hiểu hơn về điều này nên Laravel 5.4 đã giúp chúng ta bằng cách định nghĩa file ngôn ngữ theo định dạng JSON.

I/ Hướng dẫn cài đặt file ngôn ngữ theo định dạng JSON của Laravel 5.4 hỗ trợ Trước hết các bạn hãy tham khảo document của Laravel 5

  • Tạo fle json và đặt ở đường dẫn sau. resources/lang/en.json
  • Trong file này bạn định nghĩa các key cần translate theo format json nhé. Ví dụ:
{
    "create": "Create",
    "update" : "Update",
    "delete" : "Delete"
}
  • Tiếp theo, để đọc được file json này thì Laravel 5.4 đã hỗ trợ helper __().
function __($key = null, $replace = [], $locale = null)
    {
        return app('translator')->getFromJson($key, $replace, $locale);
    }
  • Như các bạn thấy các param trên của helper, để translate text create thì bạn chỉ cần pass text đã định nghĩa trong file json
__('create');
__('update');
__('delete')
  • Nếu các bạn muốn truyền tham số cho text cần translate thì làm như sau:
  1. Định nghĩa trong file JSON lang (resources/lang/en.json)
{
    "read": "Read :param"
}
  1. Trong code gọi bằng cách.
__('read', ['param' => 'Card']);

Về mặt lý thuyết thì chúng ta có thể translate với file JSON này một cách dễ dàng. Nhưng, có một điểm yếu là helper này chỉ có thể translate dạng key: value. Tức là, value bắt buộc phải là string. Nếu value là object thì helper __() không thể translate được. Để giải quyết vấn đề này thì mình qua mục tiếp theo nhé.

II. Translate với file value là object.

  • Như mình đã nói ở trên, thì để translate value là một object thì mình có 1 thủ thuật là xây dựng 1 helper để đọc data từ file JSON lang.
/**
 * Translate string from key
 *
 * @param string $key
 * @param array $params
 * @param string $locale, default is en (english)
 * @return string was translated
 */
if (!function_exists('translate')) {
    function translate($key, $params = [], $locale = 'en') {
        $filePath = resource_path('/lang/' . $locale . '.json');

        if (!is_readable($filePath)) {
            return false;
        }

        $fileJson = file_get_contents($filePath);
        $result = json_decode($fileJson, true);
        $partKeys = explode('.', $key);

        foreach ($partKeys as $partKey) {
            if (!isset($result[$partKey])) {
                return $key;
            }
            $result = $result[$partKey];
        }

        if (!empty($params)) {
            foreach ($params as $key => $value) {
                $result = str_replace(':' . $key, $value, $result);
            }
        }

        return $result;
    }
}

  • Giả sử chúng ta cần translate text với cấu trúc sau.
{
"other_error": {
    "invalid": ":param is invalid value"
  }
}
  • Với helper trên thì chúng ta làm hoàn toàn tương tự với helper __() của Laravel 5.4
translate('other_error.invalid', ['param' => 'ABC']);

Tham khảo: https://laravel.com/docs/5.4/localization https://laravel-news.com/json-based-translations

0