آموزش چند زبانه کردن سایت با لاراول و inetriajs(vue)
معمولا برای چند زبانه کردن پروژه ها روش های مثل همی وجود داره که ما کلمات رو در دیکشنری های ترجمه قرار میدیم و اونارو فراخوانی میکنیم کانفیگ این روش در پروژه هایی که با interia بین لاراول و ویو انجام گرفته به صورت زیر هست . در ابتدا به فایل میریم و اون رو به شکل زیر تغییر میدیم : ( app/Providers/AppServiceProvider.php )
use Inertia\Inertia; ... public function boot() { Inertia::share([ 'locale' => function () { return app()->getLocale(); }, 'language' => function () { return translations( resource_path('lang/'. app()->getLocale() .'.json') ); }, ]); }
حالا نیازه که یک فایل helper بسازیم . این فایل برای برگرداندن فایل های ترجمه شده هست . برای اینکار ااز پکیج (https://github.com/browner12/helpers ) استفاده میکنیم :
composer require browner12/helpers php artisan vendor:publish --provider="browner12\helpers\HelperServiceProvider"
حالا با دستور artisan به شکل زیر فایل رو میسازیم ( در پوشه app/helper ایجاد میشه ) :
php artisan make:helper translations
محتوای فایل رو به شکل زیر تغییر میدیم :
<?php if (!function_exists('DummyFunction')) { function translations($json) { if(!file_exists($json)) { return []; } return json_decode(file_get_contents($json), true); } }
خب در قسمت روت لاراول یک روت ایجاد میکنیم و زبان رو بهش پاس میدیم :
Route::get('language/{language}', function ($language) { Session()->put('locale', $language); return redirect()->back(); })->name('language');
حالا یک میلدوار برای تغییر زبان ایجاد میکنیم و اون رو پروژه اد میکنیم
php artisan make:middleware SetLocale
محتوای اونو اینجوری میزاریم :
public function handle($request, Closure $next) { app()->setLocale(config('app.locale')); if(session()->has('locale')) { app()->setLocale(session('locale')); } return $next($request); }
بعد به فایل app/Http/Kernel.php میریم و بعد در قسمت middlewareGroups و قسمت web میدلوار جدید رو اضافه میکنیم :
\App\Http\Middleware\SetLocale::class,
حالا به پوشه resources/lang میریم و اینجا فایل های json مربوط به زبان هامونو ایجاد میکنیم مثلا en.json – fa.json – ar.json و غیره …محتوای اونا به شکل زیر باید باشه :
{ "hello":"Hello", "homePage":"Home Page", "aboutPage":"About Page", "welcome": "Hello {name}" }
{ "hello":"سلام", "homePage":"صفحه اصلی", "aboutPage":"درباره ما", "welcome": "سلام {name}" }
بعد از این مرحله ما نیاز داریم زبان های سیستم رو به سمت فرانت پاس بدیم . برای اینکار کافیه به فایل app/Http/Middleware/HandleInertiaRequests.php که وجود داره بریم و در قسمت share مثلا به شکل زیر عمل کنیم :
public function share(Request $request) { $data = array( "en", "de", "fa", "ar" ); return array_merge(parent::share($request), [ 'langlist' => $data ]); }
حالا متغیر langlist رو در هرجای پروژه که نیاز بود میتونیم سمت فرانت دریافت کنیم .
کارمون سمت لاراول تمومه . حالا به قسمت resources/js میریم .
در ابتدا داخل این پوشه یک فایل به اسم base.js میسازیم که مارو در ترجمه سمت فرانت کمک میکنه .
module.exports = { methods: { /** * Translate the given key. */ __(key, replace = {}) { var translation = this.$page.props.language[key] ? this.$page.props.language[key] : key 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); }, }, }
توجه داشته باشید بر حسب ورژن های مختلف ممکنه مثلا اون کلمات this.$page.props.language متفاوت باشه . حتما لاگ بگیرید .
حالا در فایل app.js یا main.js ( فایل اصلی پروژه سمت ویو ) باید این فایل base رو اضافه کنیم . برای اینکار مثلا به شکل زیر عمل میکنیم :
require('./bootstrap'); import { createApp, h } from 'vue'; import { createInertiaApp} from '@inertiajs/inertia-vue3'; import { InertiaProgress } from '@inertiajs/progress'; import "bootstrap/dist/css/bootstrap.min.css"; var base = require('./base'); const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel'; createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name) => require(`./Pages/${name}.vue`), setup({ el, app, props, plugin }) { return createApp({ render: () => h(app, props) }) .use(plugin) .mixin(base) .mixin({methods: { route } }) .mount(el); }, }); InertiaProgress.init({ color: '#4B5563' });
خب حالا برای تغییر زبان یک کامپونتت داخل پوشه Shared درست میکنیم به اسم LanguageSelector.vue :
<template> <div class="ml-4"> <ul id="example-1"> <li v-for="value in languagelist"> <a :href="route('language', [value])" style="cursor: pointer"> <span>{{value}} </span> </a> </li> </ul> </div> </template> <script> export default { props: ['langlist'], data() { return { languagelist: this.langlist, }; }, name: "LanguageSelector", }; </script> <style scoped> </style>
بعد ما به فایل layout سمت فرانتمون مراجعه میکنیم و زبان هایی که در سمت لاراول پاس داده بودیم دریافت میکنیم . همچنین کامپونتت مرحله قبل رو فرخوانی و اون زبانهارو بهش پاس میدیم.
<language-selector :langlist="langlist" /> .... .... .... <script> import { defineComponent } from "vue"; import LanguageSelector from "../Shared/LanguageSelector.vue"; export default defineComponent({ props: { title: String, }, components: { LanguageSelector }, computed: { langlist() { return this.$page.props.langlist; }, }, }); </script>