?Talamanca = My medicine! | https://goo.gl/ceaBN7
استفاده از فایل های ترجمه لاراول در جاوا اسکریپت
اگه براتون سوال شده چجوری توی فایل های جاوا اسکریپت از قابلیت translation لاراول بهره ببرید، این نوشته رو واسه شما (هرچند نه چندان خوب) مینویسم. این کد جاوا اسکریپت قراره فقط ترجمه های ساده رو انجام بده و همه ی امکانات رو نداره (مثل Pluralization) ولی کار من یکی باهاش راه میفته.
در نهایت هم میگم چجوری میتونین توی vue js از ترجمه ها استفاده کنین.
اول از همه یه پروژه جدید حاضر میکنم و قابلیت چند زبانه شدن رو با استفاده از آدرس دهی فراهم میکنم به این شکل
http://test/fa/hello
نسخه فارسی سایت
http://test/en/hello
نسخه انگلیسی سایت
این قابلیت رو به کمک یه میدل ویر پیاده سازی میکنم.
اول از همه یه فایل کانفیگ ایجاد میکنم و اسمش رو میذارم translation.php و لیست زبان های قابل پشتیبانی در سایت رو توی اون مینویسم
<?php
return [
'locales' => [
'fa' => 'فارسی',
'en' => 'English'
],
];
و میدل ویر مورد نظر رو مینویسم.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\App;
class SetLocale
{
public function handle($request, Closure $next)
{
$locale = $request->segment(1);
if (in_array($locale, array_keys(config('translation.locales')))) {
App::setLocale($locale);
}
return $next($request);
}
}
بعد میدل ویر رو توی گروپ web توی Kernel.php اضافه میکنم.
'web' => [
...
\App\Http\Middleware\SetLocale::class,
]
یه کنترلر جدید میسازم و اسمش رو مثلا میزارم
IndexController
و یه متد
index
بهش اضافه میکنم به این شکل
class IndexController extends Controller
{
public function index()
{
return view('home');
}
}
و روت هام رو هم به این شکل تعریف میکنم.
Route::redirect('/', '/'.config("app.locale"));
foreach (array_keys(config('translation.locales')) as $loc) {
Route::prefix($loc)->name($loc.".")->group(function () {
Route::get('/', 'IndexController@index');
});
}
نکته در مورد روت: اگه چنانچه زبانی اضافه کردین یا حذف کردین وقتی که روت ها کش شده هستش. باید از اول کش رو انجام بدین.
یه گروه جدید ترنسلیشن ایجاد میکنم و مثلا اسمش رو میذارم home.
این مقدار ها رو داخلش قرار میدم.
برای فارسی (resources/lang/fa/home.php):
<?php
return [
'laravel_is_awesome' => 'لاراول فوق العادس',
'make_something' => 'یه چیز :param بساز',
'awesome' => 'فوق العاده',
];
برای انگلیسی (resources/lang/en/home.php):
<?php
return [
'laravel_is_awesome' => 'Laravel is awesome',
'make_something' => 'Make something :param',
'awesome' => 'awesome',
];
و در نهایت ویو home رو این شکلی مینویسم.
<!DOCTYPE html>
<html lang="{{ App::getLocale() }}">
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<h1>@lang('home.laravel_is_awesome')</h1>
<h3>@lang('home.make_something', ['param' => trans("home.awesome")])</h3>
</body>
</html>
اینم از نتیجه کار تا اینجا.
خب حالا میرم سراغ اصل مطلب. من میخوام همین رو به صورت یه alert و توی جاوا اسکریپت نمایش بدم.
برای شروع یه روت میسازم که انگار شبیه یه فایل جاواسکریپت هست.
Route::redirect('/', '/'.config("app.locale"));
foreach (array_keys(config('translation.locales')) as $loc) {
Route::prefix($loc)->name($loc.".")->group(function () {
Route::get('/', 'IndexController@index');
Route::get('generated-asset.js', 'IndexController@generatedAsset')->name('generated_asset');// روت جدید
});
}
تابع generatedAsset لازمه که یه آبجکت جاوا اسکریپت ایجاد کنه که ما بتونیم از طریق پارامتری که داریم مقدار مورد نظرمون رو پیدا کنیم و نمایش بدیم.
برای شروع نیاز داریم گروه های ترجمه ها رو بشناسیم برای این کار من یه مقدار جدید توی کانفیگ translation ایجاد میکنم به این شکل.
'groups' => [
'auth',
'pagination',
'passwords',
'validation',
'home'
]
این آرایه مشخص میکنه برامون کدوم گروه ها قابل دسترس باشن در جاوا اسکریپت.
کنترلر رو به این شکل مینویسم.
public function generatedAsset()
{
$groups = [];
foreach (config('translation.groups') as $group) {
$groups[$group] = trans($group);
}
return response()
->view("generated_asset", compact("groups"))
->header("Content-Type", "text/javascript");
}
حالا ویو generated_asset رو به این شکل مینویسم.
var ___jtrans = @json($groups);
خب حالا باید یه همچین چیزی داشته باشیم.
حالا میخام یه تابع بهش اضافه کنم که شبیه trans خود لاراول عمل کنه.
پس ویو رو به این شکل کامل ترش میکنم.
var ___jtrans = @json($groups);
function jtrans(key, parameters)
{
if (parameters === undefined) {
parameters = {};
}
var out = __jtransHelper(key, parameters, ___jtrans, '');
for(var parameter in parameters){
out = out.replace(new RegExp("\:"+parameter), parameters[parameter]);
}
return out;
}
function __jtransHelper(key, parameters, __data, previous_key)
{
var key_array = key.split(".");
var this_group = key_array[0];
key_array = key_array.splice(1, key_array.length-1);
var searchingKey = key_array.join('.');
if( typeof __data[this_group] !== 'undefined' ) {
if(searchingKey.length>0){
return __jtransHelper(searchingKey, parameters, __data[this_group], previous_key+(previous_key.length>0?'.':'')+this_group);
} else {
return __data[this_group];
}
}
return previous_key+'.'+this_group;
}
خب حالا برای تست کردن میخام یه کار کنم طرف وقتی روی هر کدوم از جملات توی صفحه اصلی کلیک کرد همون توی یه alert نشون داده بشه. فایل جاوا اسکریپت جدا نمیسازم فقط میخام تست کنم ولی در اصل هدف ساخت همچین چیزی اینه که توی کد جاوا اسکریپت به شکل جدا استفاده کرد.
این خطوط کد رو به کد ویو صفحه اصلی اضافه میکنم.
<script src="{{ route(App::getLocale().'.generated_asset') }}"></script>
<script>
document.querySelector("h1").addEventListener("click", function(){
alert(jtrans("home.laravel_is_awesome"));
});
document.querySelector("h3").addEventListener("click", function(){
alert(jtrans("home.make_something", {'param': jtrans("home.awesome")}));
});
</script>
حتما آدرس فایل ترجمه رو قبل از آدرس فایل های اختصاصیتون قرار بدین.
حالا روی هر کدوم از متن ها کلیک کنین شاهد نمایش ترجمه اون به صورت آلرت خواهید بود!
استفاده از ترجمه های لاراول در Vue
به نظرم ویو خیلی خفنه! حالا میخام چیزی که تا اینجا ساختیم رو توی یه کامپوننت Vue استفاده کنم برای اینکار یه پلاگین خیلی ساده میسازم و ازش استفاده میکنم پس لازمه از قبل بدونین چه شکلی واسه ویو میشه پلاگین ساخت و استفاده کرد.
اول یه فایل js ایجاد میکنم و مثلا اسمش رو میذارم LaravelTranslation.js و محتویات زیر رو درونش مینویسم.
var LaravelTranslation = {};
LaravelTranslation.install = function (Vue, options) {
Vue.prototype.jtrans = jtrans;
Vue.filter("trans", jtrans);
};
export default LaravelTranslation;
من دو سینتکس مختلف رو برای استفاده داخل template vue آماده کردم.
اول:
{{ "home.laravel_is_awesome"|trans }}
این روش استفاده از فیلتر هست و به نظرم جذابه! و روش دوم:
{{ jtrans("home.laravel_is_awesome") }}
اینم با استفاده از متد البته متد حتما باید باشه شاید یه جای دیگه توی کد هاتون به جز template بهش احتیاج داشته باشین.
برای ادامه توی app.js این پلاگین رو به Vue اضافه میکنم.
import Vue from 'vue';
import LaravelTranslation from './LaravelTranslation';
Vue.use(LaravelTranslation);
Vue.component('example-component', require('./components/ExampleComponent.vue'));
const app = new Vue({
el: '#app'
});
و حالا کامپوننت ExampleComponent این شکلی اصلاح میکنم.
<template>
<div>
<h2>Example Component</h2>
{{ jtrans("home.laravel_is_awesome") }}<br>
{{ jtrans("home.make_something", {'param': jtrans("home.awesome")}) }}<br>
<br><br>
Using filters:<br>
{{ "home.laravel_is_awesome"|trans }}<br>
{{ "home.make_something"|trans({'param': jtrans("home.awesome")}) }}<br>
<br><br><br>
</div>
</template>
<script>
export default {
}
</script>
و در نهایت آدرس فایل اسکریپت رو بعد کامپایل با mix به صفحه اصلی اضافه میکنم.
<script src="/js/app.js"></script>
و داخل صفحه ی اصلی این کد رو اضافه میکنم.
<div id="app">
<example-component></example-component>
</div>
و اینم نتیجه کار
سورس کد هم اینجاست: https://github.com/amir9480/laravel-js-localization-example
حرف آخر : روز خوبی داشته باشین. :)
مطلبی دیگر از این انتشارات
تایپ اسکریپت از صفر تا نیم
مطلبی دیگر از این انتشارات
جاوا اسکریپت چه جوری کار میکنه؟ دل و روده ی V8 engine و ۵ تا نکته در مورد کد بهینه نوشتن
مطلبی دیگر از این انتشارات
نام گذاری اصولی کلاسهای CSS با متد BEM