Sau một số nghiên cứu về chủ đề translate trong laravel ra file js, tôi phát hiện ra rằng không có giải pháp hiện có nào best practice cả. Nên tôi đề xuất giải pháp sau

Làm thế nào để sử dụng translations trong laravel vào js

2021-03-02 1485 lượt xem

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é. 

bài viết trong chủ đề