ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • lang, translate, locale, 다국어, global 언어 지원하기(laravel + inertia.js + nuxt 버전 추가)
    Laravel/Inertia.js 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

    댓글

Designed by Tistory.