2016-11-23 57 views
0

我想向我的網站添加多語言支持,但我不知道如何最好地實現它。 Laravel文檔(https://laravel.com/docs/5.3/localization)非常少見,因此我已經做了一些研究,但似乎每個人都使用不同的解決方案,並且正在使用其中包含語言的URL - 例如example.com/en/pagename如何使用SESSION向Laravel 5.3添加多語言

我想要一個沒有語言標記的URL架構。事情是這樣的:example.com/pagename

現在,根據用戶的語言,該URL應譯爲:

example.com/pagename (english) example.com/seitenname (german)

最初的語言應該通過瀏覽器設置/語言檢測。用戶還應該有選擇在提供的語言之間切換。

在我的網站上,用戶可以註冊一個帳戶。他將能夠將他的首選語言保存在數據庫中 - 比如users中的表pref_lang。爲了在這種情況下保持簡單,它只是一個像「en」(英語)或「德」(德語)的字符串。

翻譯的路線很容易通過創建這樣的語言文件:

// resources/lang/de/routes.php 

return array(
    'contact' => 'kontakt', 
    'pagename' => 'seitenname' 
); 

...,一個用於EN:

// resources/lang/en/routes.php 

return array(
    'contact' => 'contact', 
    'pagename' => 'pagename' 
); 

......這樣的路線,例如combinded:

// routes/web.php 

Route::get('/', function() { 
    return view('pages.dashboard'); 
}); 

Route::get('/{contact}', function() { 
    return view('pages.contact'); 
}); 

Route::get('/{pay2gether-system}', function() { 
    return view('pages.pagename'); 
}); 

現在只是一個問題,我如何創建這樣一個「語言切換」按鈕,將語言從瀏覽器設置/切換操作或從SESSION中的數據庫中獲取數據,以及如何將其重用爲HTML <a href="#">標記中的路由和URL?

回答

1

我這樣做了幾次,這很容易完成。按照下面的步驟,如果您有任何其他問題,請隨時詢問。

  1. users表中創建一個language列。這是我過去設置的方式,$table->string('language')->default('en');
  2. 創建一個新的中間件來檢測語言更改,例如:SetLanguage
  3. 將中間件添加到app\Http\Kernel.php中的web中間件組的底部。
  4. 將以下內容粘貼到handle方法中。

    if ($request->has('language')) { 
        if (auth()->user()) { 
         auth()->user()->language = $request->language; 
         auth()->user()->save(); 
        } 
        App::setLocale($request->language); 
    } elseif (auth()->user()) { 
        App::setLocale(auth()->user()->language); 
    } 
    return $next($request); 
    
  5. 創建一個服務提供商,並在您config/app.php註冊,並在引導方法粘貼下面的代碼。

    view()->composer('template.name', function($view) { 
        $languages = []; 
        $folders = File::directories(base_path('resources/lang/')); 
        foreach ($folders as $folder) { 
         $languages[] = str_replace('\\', '', last(explode('/',$folder))); 
        } 
        $view->with('languages', $languages); 
    }); 
    
  6. 現在您的template.name.blade.php你可以通過在你的應用程序中可用的語言循環。

在您的下拉菜單中,您應該使用{{ url('/') . '?language=' . $language }}作爲循環時的鏈接。您可以將language鍵更改爲其他名稱,但如果這樣做了,則還必須在中間件中更改它。

+0

謝謝,但Laravel從瀏覽器中讀取第一個/默認語言,如果它尚未設置在數據庫中,它在哪裏?這是缺少,或?另外:我不想像'{{url('/')那樣存儲語言。 '?language ='。 $ language}}',但在cookie/session中。這不可能嗎? – user2966991

+0

數據庫中有一個默認值,它被設置爲'en'。你可以改變它到任何你想要的。 – tomirons

0

我會做一些在中間件:

public function handle($request, Closure $next) 
{ 
    if ($request->has('language')) { 
     $path = $request->path(); 
     $locale = $request->get('language'); 

     # save locale 
     Cookie::queue(Cookie::make(
      'language', $locale, 1440 // 24h 
     )); 

     # set locale 
     \App::setLocale($locale); 

     return redirect($path)->withCookie(cookie('language')); 
    } 

    if ($locale = $request->cookie('language')) { 
     \App::setLocale($locale); 
    } 

    return $next($request); 
} 

現在的供應商:

public function boot() 
{ 
    View::composer('template.name', function($view) { 
     $directory = base_path('resources/lang/'); 
     $languages = \File::directories($directory); 
     $view->with('languages', array_map('basename', $languages)); 
    }); 
} 

並在視圖:

<ul class="dropdown-menu" role="menu"> 
    @foreach ($languages as $lang) 
     <li> 
      <a href="{{ url()->current() . '/?language=' . $lang }}" title="">{{ $lang }}</a> 
     </li> 
    @endforeach 
</ul> 

我不能,如果十分確定這是一個最好的解決方案...也許有更多Laravel經驗的人可以向我們展示另一種解決方案

+0

儘管如此,代碼優化並不是問題的關鍵。你是指另一個答案?這還不夠清楚。 –