Laravel Multi Language Translation using lang() Helper Tutorial

By Hardik Savani April 16, 2024 Category : Laravel Bootstrap MySql JSON Ajax

We almost project require to add multi-language support like we can change the language in our blog or website on the front end. Laravel also provide localization helper like trans(), lang() etc for multiple language support. So if you require basic translation like label changes and title etc then you should have to use laravel default localization. Laravel also provide to manage with json. you can easily change language using language code.

So, in this tutorial, i would like to show you how we can manage in back-end side in laravel 5, laravel 6, laravel 7, laravel 8, laravel 9, laravel 10 and laravel 11 and how you can use it. i will create languages table with name and language code. then we will create default en.json file on lang folder. as we know english is default language. we will create one page on back-end side and that will manage all languages key and value of json file. it is a amazing, you can see on demo and also you can download code of this tutorial.

After complete all the steps, you will get layout like as bellow example, so let's see that too.

Preview:

Step 1: Create languages table

In first step, we are going to create multi language translation. so we have to create migration for "languages" table using Laravel 5.6 php artisan command, so first fire bellow command:

php artisan make:migration php artisan make:migration create_languages_table

After this command you will find one file in following path "database/migrations" and you have to put bellow code in your migration file for create tags table.

<?php


use Illuminate\Support\Facades\Schema;

use Illuminate\Database\Schema\Blueprint;

use Illuminate\Database\Migrations\Migration;


class CreateLanguagesTable extends Migration

{

/**

* Run the migrations.

*

* @return void

*/

public function up()

{

Schema::create('languages', function (Blueprint $table) {

$table->increments('id');

$table->string('name');

$table->string('code');

$table->timestamps();

});

}


/**

* Reverse the migrations.

*

* @return void

*/

public function down()

{

Schema::dropIfExists('languages');

}

}

now you can run migration by following command:

php artisan serve

Step 2: Create Seeder for Language

So, in the second step, we need to add seeder for language table, so we will create three language by default. so let's create seeder by bellow command:

php artisan make:seeder CreateLanguages

database/seeds/CreateLanguages.php

<?php


use Illuminate\Database\Seeder;


class CreateLanguages extends Seeder

{

/**

* Run the database seeds.

*

* @return void

*/

public function run()

{

\DB::table('languages')->insert(['name' => 'English', 'code' => 'en']);

\DB::table('languages')->insert(['name' => 'Franch', 'code' => 'fr']);

\DB::table('languages')->insert(['name' => 'Italy', 'code' => 'it']);

}

}

Now you can run seeder by following command:

php artisan db:seed --class=CreateLanguages

Step 3: Add Route

In this is step we need to add routes for language translation. so open your "routes/web.php" file and add following route.

routes/web.php

Route::get('languages', 'LanguageTranslationController@index')->name('languages');

Route::post('translations/update', 'LanguageTranslationController@transUpdate')->name('translation.update.json');

Route::post('translations/updateKey', 'LanguageTranslationController@transUpdateKey')->name('translation.update.json.key');

Route::delete('translations/destroy/{key}', 'LanguageTranslationController@destroy')->name('translations.destroy');

Route::post('translations/create', 'LanguageTranslationController@store')->name('translations.create');

Route::get('check-translation', function(){

\App::setLocale('fr');

dd(__('website'));

});

Step 4: Create LanguageTranslationController Controller

Here, in this step we need to create new controller for create language translation. so create "LanguageTranslationController" controller and put bellow code:

app/Http/Controllers/LanguageTranslationController.php

<?php


namespace App\Http\Controllers;


use Illuminate\Http\Request;

use DB;

use File;


class LanguageTranslationController extends Controller

{

/**

* Remove the specified resource from storage.

* @return Response

*/

public function index()

{

$languages = DB::table('languages')->get();


$columns = [];

$columnsCount = $languages->count();


if($languages->count() > 0){

foreach ($languages as $key => $language){

if ($key == 0) {

$columns[$key] = $this->openJSONFile($language->code);

}

$columns[++$key] = ['data'=>$this->openJSONFile($language->code), 'lang'=>$language->code];

}

}


return view('languages', compact('languages','columns','columnsCount'));

}

/**

* Remove the specified resource from storage.

* @return Response

*/

public function store(Request $request)

{

$request->validate([

'key' => 'required',

'value' => 'required',

]);


$data = $this->openJSONFile('en');

$data[$request->key] = $request->value;


$this->saveJSONFile('en', $data);


return redirect()->route('languages');

}


/**

* Remove the specified resource from storage.

* @return Response

*/

public function destroy($key)

{

$languages = DB::table('languages')->get();


if($languages->count() > 0){

foreach ($languages as $language){

$data = $this->openJSONFile($language->code);

unset($data[$key]);

$this->saveJSONFile($language->code, $data);

}

}

return response()->json(['success' => $key]);

}


/**

* Open Translation File

* @return Response

*/

private function openJSONFile($code){

$jsonString = [];

if(File::exists(base_path('resources/lang/'.$code.'.json'))){

$jsonString = file_get_contents(base_path('resources/lang/'.$code.'.json'));

$jsonString = json_decode($jsonString, true);

}

return $jsonString;

}


/**

* Save JSON File

* @return Response

*/

private function saveJSONFile($code, $data){

ksort($data);

$jsonData = json_encode($data, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);

file_put_contents(base_path('resources/lang/'.$code.'.json'), stripslashes($jsonData));

}


/**

* Save JSON File

* @return Response

*/

public function transUpdate(Request $request){

$data = $this->openJSONFile($request->code);

$data[$request->pk] = $request->value;


$this->saveJSONFile($request->code, $data);

return response()->json(['success'=>'Done!']);

}


/**

* Remove the specified resource from storage.

* @return Response

*/

public function transUpdateKey(Request $request){

$languages = DB::table('languages')->get();


if($languages->count() > 0){

foreach ($languages as $language){

$data = $this->openJSONFile($language->code);

if (isset($data[$request->pk])){

$data[$request->value] = $data[$request->pk];

unset($data[$request->pk]);

$this->saveJSONFile($language->code, $data);

}

}

}


return response()->json(['success'=>'Done!']);

}

}

Step 5: Create Blade File

In the last step, we need to create languages.blade.php file for view. so create bellow file and put bellow code on it.

resources/views/languages.blade.php

<!DOCTYPE html>

<html>

<head>

<title>Laravel Multi Language Translation - ItSolutionStuff.com</title>

<meta name="csrf-token" content="{{ csrf_token() }}" />


<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css" />

<link href="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/css/bootstrap-editable.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>

<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/js/bootstrap-editable.min.js"></script>

</head>

<body>


<div class="container">

<h1>Laravel Multi Language Translation - ItSolutionStuff.com</h1>


<form method="POST" action="{{ route('translations.create') }}">

@csrf

<div class="row">

<div class="col-md-4">

<label>Key:</label>

<input type="text" name="key" class="form-control" placeholder="Enter Key...">

</div>

<div class="col-md-4">

<label>Value:</label>

<input type="text" name="value" class="form-control" placeholder="Enter Value...">

</div>

<div class="col-md-4">

<button type="submit" class="btn btn-success">Add</button>

</div>

</div>

</form>


<table class="table table-hover table-bordered">

<thead>

<tr>

<th>Key</th>

@if($languages->count() > 0)

@foreach($languages as $language)

<th>{{ $language->name }}({{ $language->code }})</th>

@endforeach

@endif

<th width="80px;">Action</th>

</tr>

</thead>

<tbody>

@if($columnsCount > 0)

@foreach($columns[0] as $columnKey => $columnValue)

<tr>

<td><a href="#" class="translate-key" data-title="Enter Key" data-type="text" data-pk="{{ $columnKey }}" data-url="{{ route('translation.update.json.key') }}">{{ $columnKey }}</a></td>

@for($i=1; $i<=$columnsCount; ++$i)

<td><a href="#" data-title="Enter Translate" class="translate" data-code="{{ $columns[$i]['lang'] }}" data-type="textarea" data-pk="{{ $columnKey }}" data-url="{{ route('translation.update.json') }}">{{ isset($columns[$i]['data'][$columnKey]) ? $columns[$i]['data'][$columnKey] : '' }}</a></td>

@endfor

<td><button data-action="{{ route('translations.destroy', $columnKey) }}" class="btn btn-danger btn-xs remove-key">Delete</button></td>

</tr>

@endforeach

@endif

</tbody>

</table>

</div>


<script type="text/javascript">

$.ajaxSetup({

headers: {

'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')

}

});


$('.translate').editable({

params: function(params) {

params.code = $(this).editable().data('code');

return params;

}

});


$('.translate-key').editable({

validate: function(value) {

if($.trim(value) == '') {

return 'Key is required';

}

}

});


$('body').on('click', '.remove-key', function(){

var cObj = $(this);


if (confirm("Are you sure want to remove this item?")) {

$.ajax({

url: cObj.data('action'),

method: 'DELETE',

success: function(data) {

cObj.parents("tr").remove();

alert("Your imaginary file has been deleted.");

}

});

}


});

</script>


</body>

</html>

Now we are ready to run above example. you can also download code and check demo from bellow button.

I hope it can help you....

Shares