Implement language switcher functionality and enhance localization support: add available locales configuration, update SetLocale middleware to handle language selection via query parameters, and integrate language switcher buttons in the settings layout. Additionally, update various views to utilize translation functions for improved internationalization, ensuring consistent language support across the application.

This commit is contained in:
2025-07-29 17:04:13 +05:00
parent 0b6cbc8d9e
commit 1a3f82b22c
10 changed files with 87 additions and 16 deletions

View File

@@ -17,10 +17,15 @@ class SetLocale
*/ */
public function handle(Request $request, Closure $next): Response public function handle(Request $request, Closure $next): Response
{ {
if (Session::has('locale')) { $locale = $request->query('lang');
if ($locale && in_array($locale, config('app.available_locales'))) {
App::setLocale($locale);
Session::put('locale', $locale);
} elseif (Session::has('locale')) {
App::setLocale(Session::get('locale')); App::setLocale(Session::get('locale'));
} else { } else {
App::setLocale('en'); // Default locale App::setLocale(config('app.fallback_locale', 'en'));
} }
return $next($request); return $next($request);

View File

@@ -84,6 +84,19 @@ return [
'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'), 'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'),
/*
|--------------------------------------------------------------------------
| Application Available Locales
|--------------------------------------------------------------------------
|
| The application locales that are available for your application.
|
*/
'available_locales' => [
'en', 'ru', 'tk'
],
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Encryption Key | Encryption Key

View File

@@ -3,6 +3,7 @@
namespace Database\Seeders; namespace Database\Seeders;
use App\Models\User; use App\Models\User;
use App\Models\UserRole;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
class UsersTableSeeder extends Seeder class UsersTableSeeder extends Seeder
@@ -16,6 +17,7 @@ class UsersTableSeeder extends Seeder
'name' => 'nurmuhammet', 'name' => 'nurmuhammet',
'email' => 'nurmuhammet@mail.com', 'email' => 'nurmuhammet@mail.com',
'password' => bcrypt('payload10'), 'password' => bcrypt('payload10'),
'role' => UserRole::ADMIN,
]); ]);
} }
} }

View File

@@ -492,6 +492,15 @@
} }
}); });
// Language Switcher
$('#language-switcher button').on('click', function (e) {
$(this).addClass('active').siblings().removeClass('active');
var lang = $(this).attr('data-lang');
var currentUrl = new URL(window.location.href);
currentUrl.searchParams.set('lang', lang);
window.location.href = currentUrl.toString();
});
///============= * Custom Cursor =============\\\ ///============= * Custom Cursor =============\\\
var ball = document.getElementById("cursor-ball"); var ball = document.getElementById("cursor-ball");
var cursorText = document.getElementById("cursor-text"); var cursorText = document.getElementById("cursor-text");

View File

@@ -37,4 +37,15 @@ return [
'Manage Solutions' => 'Manage Solutions', 'Manage Solutions' => 'Manage Solutions',
'Success Section' => 'Success Section', 'Success Section' => 'Success Section',
'Settings' => 'Settings', 'Settings' => 'Settings',
]; '|' => '|',
'Gujurly Inžener logo' => 'Gujurly Inžener logo',
'Comments' => 'Comments',
'No comments yet' => 'No comments yet',
'Post Comment' => 'Post Comment',
'Required fields are marked' => 'Required fields are marked',
'Full Name' => 'Full Name',
'Title' => 'Title',
'Type your comments....' => 'Type your comments....',
'Submit Comment' => 'Submit Comment',
'Recent Blog' => 'Recent Blog',
];

View File

@@ -37,4 +37,15 @@ return [
'Manage Solutions' => 'Управление решениями', 'Manage Solutions' => 'Управление решениями',
'Success Section' => 'Раздел «Успех»', 'Success Section' => 'Раздел «Успех»',
'Settings' => 'Настройки', 'Settings' => 'Настройки',
]; '|' => '|',
'Gujurly Inžener logo' => 'Логотип Gujurly Inžener',
'Comments' => 'Комментарии',
'No comments yet' => 'Пока нет комментариев',
'Post Comment' => 'Оставить комментарий',
'Required fields are marked' => 'Обязательные поля отмечены',
'Full Name' => 'Полное имя',
'Title' => 'Заголовок',
'Type your comments....' => 'Введите ваши комментарии....',
'Submit Comment' => 'Отправить комментарий',
'Recent Blog' => 'Последние новости блога',
];

View File

@@ -37,4 +37,15 @@ return [
'Manage Solutions' => 'Çözgütleri dolandyrmak', 'Manage Solutions' => 'Çözgütleri dolandyrmak',
'Success Section' => 'Üstünlik bölümi', 'Success Section' => 'Üstünlik bölümi',
'Settings' => 'Sazlamalar', 'Settings' => 'Sazlamalar',
]; '|' => '|',
'Gujurly Inžener logo' => 'Gujurly Inžener logotipi',
'Comments' => 'Teswirler',
'No comments yet' => 'Heniz teswir ýok',
'Post Comment' => 'Teswir goşmak',
'Required fields are marked' => 'Hökmany meýdançalar bellik edilen',
'Full Name' => 'Doly ady',
'Title' => 'Ady',
'Type your comments....' => 'Teswirleriňizi ýazyň....',
'Submit Comment' => 'Teswir ibermek',
'Recent Blog' => 'Soňky bloglar',
];

View File

@@ -12,6 +12,14 @@
<button data-mode="dark-mode">{{ __('Dark') }}</button> <button data-mode="dark-mode">{{ __('Dark') }}</button>
</div> </div>
</div> </div>
<div class="switch__tab-area-item">
<h5>{{ __('Language') }}</h5>
<div class="switch__tab-area-item-button type-language" id="language-switcher">
<button class="{{ app()->getLocale() == 'en' ? 'active' : '' }}" data-lang="en">EN</button>
<button class="{{ app()->getLocale() == 'ru' ? 'active' : '' }}" data-lang="ru">RU</button>
<button class="{{ app()->getLocale() == 'tk' ? 'active' : '' }}" data-lang="tk">TK</button>
</div>
</div>
</div> </div>
</div> </div>
<!-- Dark Light End --> <!-- Dark Light End -->

View File

@@ -9,8 +9,8 @@
<div class="breadcrumb__area-content"> <div class="breadcrumb__area-content">
<h2>{{ $news->title }}</h2> <h2>{{ $news->title }}</h2>
<ul> <ul>
<li><a href="{{ route('home') }}">Home</a><i class="fa-regular fa-angle-right"></i></li> <li><a href="{{ route('home') }}">{{ __('Home') }}</a><i class="fa-regular fa-angle-right"></i></li>
<li><a href="{{ route('news.index') }}">News</a><i class="fa-regular fa-angle-right"></i></li> <li><a href="{{ route('news.index') }}">{{ __('News') }}</a><i class="fa-regular fa-angle-right"></i></li>
<li>{{ $news->title }}</li> <li>{{ $news->title }}</li>
</ul> </ul>
</div> </div>
@@ -39,7 +39,7 @@
</div> </div>
</div> </div>
<div class="blog__details-area-comment mt-40"> <div class="blog__details-area-comment mt-40">
<h3 class="mb-30">Comments ({{ $news->comments->count() }})</h3> <h3 class="mb-30">{{ __('Comments') }} ({{ $news->comments->count() }})</h3>
@forelse ($news->comments as $comment) @forelse ($news->comments as $comment)
<div class="blog__details-area-comment-item"> <div class="blog__details-area-comment-item">
<div class="blog__details-area-comment-item-comment"> <div class="blog__details-area-comment-item-comment">
@@ -54,35 +54,35 @@
</div> </div>
</div> </div>
@empty @empty
<p>No comments yet</p> <p>{{ __('No comments yet') }}</p>
@endforelse @endforelse
</div> </div>
<div class="blog__details-area-contact mt-60"> <div class="blog__details-area-contact mt-60">
<h3>Post Comment</h3> <h3>{{ __('Post Comment') }}</h3>
<p>Required fields are marked</p> <p>{{ __('Required fields are marked') }}</p>
<div class="blog__details-area-contact-form"> <div class="blog__details-area-contact-form">
<form action="{{ route('comments.store', $news->slug) }}" method="POST"> <form action="{{ route('comments.store', $news->slug) }}" method="POST">
@csrf @csrf
<div class="row"> <div class="row">
<div class="col-sm-6 mt-25"> <div class="col-sm-6 mt-25">
<div class="blog__details-area-contact-form-item contact-item"> <div class="blog__details-area-contact-form-item contact-item">
<input type="text" name="author_name" placeholder="Full Name" required="required"> <input type="text" name="author_name" placeholder="{{ __('Full Name') }}" required="required">
</div> </div>
</div> </div>
<div class="col-sm-6 mt-25"> <div class="col-sm-6 mt-25">
<div class="blog__details-area-contact-form-item contact-item"> <div class="blog__details-area-contact-form-item contact-item">
<input type="text" name="title" placeholder="Title" required="required"> <input type="text" name="title" placeholder="{{ __('Title') }}" required="required">
</div> </div>
</div> </div>
<div class="col-sm-12 mt-25"> <div class="col-sm-12 mt-25">
<div class="blog__details-area-contact-form-item contact-item"> <div class="blog__details-area-contact-form-item contact-item">
<textarea name="message" placeholder="Type your comments...."></textarea> <textarea name="message" placeholder="{{ __('Type your comments....') }}"></textarea>
<input type="hidden" name="news_id" value="{{ $news->id }}"> <input type="hidden" name="news_id" value="{{ $news->id }}">
</div> </div>
</div> </div>
<div class="col-lg-12 mt-25"> <div class="col-lg-12 mt-25">
<div class="blog__details-area-contact-form-item"> <div class="blog__details-area-contact-form-item">
<button class="build_button" type="submit">Submit Comment<i class="flaticon-right-up"></i></button> <button class="build_button" type="submit">{{ __('Submit Comment') }}<i class="flaticon-right-up"></i></button>
</div> </div>
</div> </div>
</div> </div>
@@ -95,7 +95,7 @@
<div class="all__sidebar"> <div class="all__sidebar">
<div class="all__sidebar-item"> <div class="all__sidebar-item">
<h4>Recent Blog</h4> <h4>{{ __('Recent Blog') }}</h4>
<div class="all__sidebar-item-post dark_image"> <div class="all__sidebar-item-post dark_image">
@foreach($recentNews as $news) @foreach($recentNews as $news)
<div class="post__item"> <div class="post__item">

View File

@@ -53,5 +53,6 @@ Route::get('privacy-and-policy', [LegalPageController::class, 'privacy'])->name(
// Language Switcher // Language Switcher
Route::get('locale/{locale}', function ($locale) { Route::get('locale/{locale}', function ($locale) {
Session::put('locale', $locale); Session::put('locale', $locale);
return redirect()->back(); return redirect()->back();
})->name('locale.switch'); })->name('locale.switch');