Laravel translate
các phiên bản laravel đã hộ trợ chúng ta đa ngôn ngữ bằng các config trong thư mục resources/lang. Mình đã kiểm tra các nguồn của Laravel và phát hiện ra rằng các bản dịch Laravel được tải dưới dạng JSON từ các translation file và sau đó được chuyển sang view Blade. Trong Blade, nó sẽ assign các biến global config đó ra ngôn ngữ tương ứng.
Muốn tải ra tất cả các bản dịch từ /resources/lang chúng ta chỉ cần tìm hiểu cách tải ra bản JSON rồi echo đống language đó dưới dạng JSON với 1 tên biến là const _translations. từ đó các file js sẽ lấy thông tin từ config trên.
Cách tải các bản language thành JSON
Chúng ta có sử dụng các công cụ có sẵn của laravel như provider và Cache. Cụ thể:
Trước hết, hãy tạo một provider trong laravel
<?php
namespace App\Providers;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\ServiceProvider;
class TranslationServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
Cache::rememberForever('translations', function () {
$translations = collect();
foreach (['en', 'vi'] as $locale) { // suported locales
$translations[$locale] = [
'php' => $this->phpTranslations($locale),
'json' => $this->jsonTranslations($locale),
];
}
return $translations;
});
}
private function phpTranslations($locale)
{
$path = resource_path("lang/$locale");
return collect(File::allFiles($path))->flatMap(function ($file) use ($locale) {
$key = ($translation = $file->getBasename('.php'));
return [$key => trans($translation, [], $locale)];
});
}
private function jsonTranslations($locale)
{
$path = resource_path("lang/$locale.json");
if (is_string($path) && is_readable($path)) {
return json_decode(file_get_contents($path), true);
}
return [];
}
}
Đăng ký provider vừa tạo
trong file config/app.php, ta đăng ký để provider được chạy bằng cách:
'providers' => [
// your other providers
App\Providers\TranslationServiceProvider::class,
],
Quăng cái nùi JSON vào script biến config
<script>
window._locale = '{{ app()->getLocale() }}';
window._translations = {!! cache('translations') !!};
</script>
nếu bạn không thích sử dụng cache bạn cũng có thể dùng view share như bài viết này:
Sharing data đến tất cả các view trong laravel php - view share
Ngoài ra, nếu bạn muốn viết code clean hơn bạn có thể tìm hiểu về package i18n trong JS kết hợp với laravel. nhưng về mặt lý thuyết là bạn luôn cần tạo ra 1 object JSON nhé.