Laravel/Inertia.js

lang, translate, locale, 다국어, global 언어 지원하기(laravel + inertia.js + nuxt 버전 추가)

짱구를왜말려? 2022. 10. 29. 13:03
반응형
SMALL

* nuxt 버전은 blueprep.com (모의고사) 참고 (아래 글도 남겨놓긴함)

# What?

inerita.js에서 laravel lang 사용하는법

 

# How?

1. 일단 lang 폴더 밑에 en, ko 등 지원하고자하는 나라별 php 언어파일 만들기

 

2. 파일시스템 설정하기

@ filesystems.php

'disks' => [
    'languages' => [
        'driver' => 'local',
        'root' => base_path('resources/lang'),
    ],
],

 

3. 언어파일 php를 json으로 변환해줄 명령어 만들기

@ app/Console/Commands/CreateJsonTranslationFileCommand.php

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;

class CreateJsonTranslationFileCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'translation:generate-json';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'This commands go through en lang files and creates en.json file';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $storage = Storage::disk('languages');
        $directories = $storage->directories();
        foreach ($directories as $directory) {
            $files = $storage->allFiles($directory);
            $array = [];
            foreach ($files as $file) {
                //do not include "api" directory, because api is only for API calls
                if (str_starts_with($file, $directory.'/api')) {
                    continue;
                }
                $baseName = str_replace('.php', '', basename($file));
                $contents = require $storage->path($file);
                $array[$baseName] = $contents;
            }

            $filePath = sprintf('%s.json', $directory);
            $storage->put($filePath, json_encode($array, JSON_PRETTY_PRINT));
        }

        $this->info('Files generated');

        return 0;
    }
}

@ helpers/helpers.php(루트 바로 밑에 생성)

<?php


function translations($json)
{
    if (!file_exists($json)) {
        return [];
    }

    return json_decode(file_get_contents($json), true);
}

@ composer.json

...
"autoload": {
    "files": [
        "helpers/helpers.php"
    ]
}
...
composer dump-autoload

 

4. inertia에 데이터 공유하기

@ HandleInertiaRequests.php

public function share(Request $request)
{
    return array_merge(parent::share($request), [
        'locale' => function () {
            return app()->getLocale();
        },
        'language' => function () {
            return translations(
                resource_path('lang/'. app()->getLocale() .'.json')
            );
        },
    ]);
}

 

5. vue에서 사용할 번역모듈 만들기

@ resources/js/translation.js

module.exports = {
    methods: {
        /**
         * Translate the given key.
         */
        __(key, replace = {}) {
            keys = key.split('.');
            var translation = this.$page.props.language;
            keys.forEach(function(keyTmp){
                 translation = translation[keyTmp]
                    ? translation[keyTmp]
                    : keyTmp
            });

            Object.keys(replace).forEach(function (key) {
                translation = translation.replace(':' + key, replace[key])
            });

            return translation
        },

        /**
         * Translate the given key with basic pluralization.
         */
        __n(key, number, replace = {}) {
            var options = key.split('|');

            key = options[1];
            if(number == 1) {
                key = options[0];
            }

            return tt(key, replace);
        },
    },
}

 

6. Vue mixin으로 추가하기

@ app.js

...

import Vue from 'vue';

...

Vue.mixin(require("./translation"));

createInertiaApp({
   ...
});

 

7. 만들어둔 php 언어파일 json으로 변환하기

php artisan translation:generate-json

 

8. vue에서 써보기

@ Login.vue

<template>
    <div class="area-login">
        {{__("model.404")}}
    </div>


</template>
<script>

import {Link} from "@inertiajs/inertia-vue";
import Back from "../../Components/Back";

export default {
 	methods: {
    	test() {
        	console.log(this.$page.props.language.model["404"]);
        }
    }
}
</script>

 

# Nuxt 버전

1. 백엔드 처리

- 미들웨어 만들기

@ LanguageMiddleware

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;

class LanguageMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        if($request->hasHeader("Language"))
            App::setLocale($request->header("Language"));
            
        return $next($request);
    }
}

@ Kernel.php

 protected $routeMiddleware = [
        ...
        "language" =>  LanguageMiddleware::class,
    ];

@ api.php

Route::middleware("language")->group(function(){

});

2. 프론트 처리

 

- 언어파일 만들기

static / translations / translation.js

export const translation = {
  en: {
    "테스트" : "TEST",
 
  },
  ko: {
  	"테스트" : "테스트"
  }
}

 

- 프론트쪽에서 기본 언어 캐치 처리하기 

@ default.vue

    mounted() {
        let language = navigator.language || navigator.userLanguage;

        if(this.$auth.user)
            language = this.$auth.user.data.language;

        this.$store.commit("setLanguage", language.includes("ko") ? 'ko' : 'en');

        this.$axios.post("/api/languages", {
            language: language
        });

    }

@ store/index.js

export const state = () => ({

    language: "ko",

})

export const mutations = {


    setLanguage (state, data){
        state.language = data;
    },

}

export const actions = {

}

- axios 플러그인 header에 language 고정으로 넣기

@ plugins/axios.js

export default function ({ $axios, redirect, store }) {
    $axios.onRequest((config) => {
        config.headers.common['Language'] = store.state.language;
    });
}

- 플러그인 만들기

@ plugins/translate.js

import {translation} from "/static/translations/translation.js";

export default function (context, inject) {
    const {store} = context;

    const translate = (word) => {
        let result = translation[store.state.language][word];

        if(!result)
            result = word;

        return result;
    }

    inject('translate', translate);
}

@ nuxt.config.js

 plugins: [
        {
            src: "~plugins/translate.js",
            src: "~plugins/axios.js",
        },
    ],

 

- 실제 사용할 때

this.$translate('fuck');
LIST