# Laravel'de çok dilli (i18n) uygulama

> Laravel'de çok dilli destek eklemek için dil dosyalarını düzenlemek, metinleri koddan ayırmak ve dil geçişini yönetmek üzerine pratik notlar.

- Yayın: 2018-09-02
- Kategori: Web Geliştirme
- Etiketler: Laravel
- Okuma süresi: 3 dk okuma
- Kaynak: https://www.muhammetsafak.com.tr/blog/laravelde-cok-dilli-i18n-uygulama/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
Bir projeye sonradan birden fazla dil desteği eklemek, baştan tasarlanmış olana kıyasla çok daha zahmetli. Bunu bir önceki projede yaşadım: Türkçe yazılmış metinler doğrudan Blade şablonlarının içindeydi; ikinci dil eklemek istediğimizde her görünüm dosyasını taramak zorunda kaldık. Bu deneyimden sonra yeni projelerde i18n (uluslararasılaştırma) desteğini baştan ekliyorum.

## Laravel'de dil sistemi nasıl çalışır?

Laravel, dil dosyalarını `resources/lang` dizininde saklar. Her dil için ayrı bir alt klasör açılır: `resources/lang/tr`, `resources/lang/en` gibi. Bu klasörlerin içinde PHP dosyaları yer alır; her dosya bir anahtar/değer dizisi döndürür:

```
resources/lang/
├── tr/
│   ├── auth.php
│   ├── validation.php
│   └── messages.php
└── en/
    ├── auth.php
    ├── validation.php
    └── messages.php
```

`messages.php` içeriği şöyle görünebilir:

```php
<?php

return [
    'welcome'    => 'Hoş geldiniz',
    'logout'     => 'Çıkış Yap',
    'save'       => 'Kaydet',
    'not_found'  => ':name adında bir kayıt bulunamadı.',
];
```

İngilizce karşılığı `resources/lang/en/messages.php`:

```php
<?php

return [
    'welcome'    => 'Welcome',
    'logout'     => 'Log Out',
    'save'       => 'Save',
    'not_found'  => 'No record found with the name :name.',
];
```

## Blade şablonlarında kullanmak

Görünüm dosyalarında `__()` yardımcı fonksiyonu ya da `@lang` direktifini kullanıyorsunuz:

```blade
<h1>{{ __('messages.welcome') }}</h1>
<button>{{ __('messages.save') }}</button>
```

Ya da parametre geçirirken:

```blade
<p>{{ __('messages.not_found', ['name' => $username]) }}</p>
```

Laravel `:name` gibi yer tutucuları otomatik olarak değiştiriyor.

## Uygulama dilini ayarlamak

Aktif dil `App::setLocale()` ile belirleniyor. Bunu bir middleware içinde yapmak temiz bir yol:

```php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\App;

class SetLocale
{
    public function handle($request, Closure $next)
    {
        $locale = $request->user()
            ? $request->user()->locale
            : session('locale', config('app.locale'));

        App::setLocale($locale);

        return $next($request);
    }
}
```

Bu middleware `app/Http/Kernel.php`'ye eklendikten sonra her istekte dil otomatik olarak ayarlanıyor.

## Dil geçişi

Kullanıcının dil tercihini değiştirmesine izin vermek için basit bir rota yeterli:

```php
<?php

Route::get('/language/{locale}', function (string $locale) {
    if (!in_array($locale, ['tr', 'en'])) {
        abort(404);
    }

    session(['locale' => $locale]);

    return redirect()->back();
})->name('language.switch');
```

Görünümde:

```blade
<a href="{{ route('language.switch', 'tr') }}">Türkçe</a>
<a href="{{ route('language.switch', 'en') }}">English</a>
```

Giriş yapmış kullanıcılar için seçimi `users` tablosuna kaydetmek daha kalıcı bir çözüm; yalnızca session kullananlar için bu yeterli.

Burada küçük bir tuzak var: kullanıcı tarayıcı sekmesini kapatıp yeniden açtığında, oturum sona erdiyse dil varsayılana dönüyor. Giriş yapılmış hesaplarda tercih mutlaka veritabanına kaydedilmeli; session yalnızca oturumsuz ziyaretçiler için yeterli.

## JSON dil dosyaları

Laravel 5.4 ile birlikte JSON formatında dil dosyası desteği geldi. Çok sayıda basit metin için anahtarı doğrudan cümle olarak kullanmayı tercih eden bu yaklaşım da var:

```json
{
  "Welcome": "Hoş geldiniz",
  "Log Out": "Çıkış Yap"
}
```

Kullanımı biraz farklı:

```php
__('Welcome') // 'tr' locale aktifse 'Hoş geldiniz' döndürür
```

Küçük projeler için bu yöntem pratik. Büyüyen projelerde key-based PHP dosyaları daha sürdürülebilir çünkü anahtarlar değişmeden metinler güncellenebiliyor.

## Doğrulama mesajlarını çevirmek

Laravel'in [dahili doğrulama mesajları](/blog/laravel-ile-form-dogrulama-validation-pratigi) da dil dosyalarında yer alıyor. `resources/lang/tr/validation.php` dosyasını Türkçe mesajlarla doldurduğunuzda form hataları otomatik olarak Türkçe görünüyor. Bu dosyaları elle yazmak yerine topluluk tarafından hazırlanmış Türkçe çeviri paketlerinden yararlanabilirsiniz; Composer aracılığıyla projeye eklenebilir hâlde mevcut.

Dikkat ettiğim bir nokta: projeye özel hata mesajları için bu genel dosyaya eklemek yerine FormRequest sınıflarının `messages()` metodunu kullanmak daha temiz. Genel doğrulama dil dosyası çok büyümeye başlarsa neyin kendi tanımladığınız mesaj olduğunu bulmak güçleşiyor.

## Tarih ve sayı biçimlendirmesi

Çok dilli bir uygulamada dil dosyaları yeterli değil; tarih ve sayı biçimlendirmesi de yerelleştirilmeli. Carbon kütüphanesi locale desteğiyle birlikte geliyor:

```php
<?php

Carbon::setLocale('tr');
echo $event->starts_at->diffForHumans(); // "3 saat önce" yerine yerel ifade
```

Sayı biçimlendirmesi için PHP'nin `NumberFormatter` sınıfı ya da basit bir yardımcı fonksiyon kullanılabilir.

## Sonuç

Çok dilli destek baştan eklendiğinde ek yük küçük; metinleri doğrudan yazı olarak değil, dil dosyasındaki anahtar olarak yazmaya alışmak yeterli. Sonradan eklendiğinde ise bütün görünüm dosyalarını taramak gerekiyor. Projeye ileride ikinci dil eklenme ihtimali varsa — ve çoğu zaman var — bu alışkanlığı baştan edinmek zamanı eriyor.
