2016-12-21 136 views
7

我正在使用由英語和荷蘭語組成的語言的下拉列表。Laravel更改語言環境不工作

<form class="" action="{{url('/locale')}}" method="post"> 
      Locale: 
       <select class="" name="locale" onchange="this.form.submit()"> 

       <option value="en" >English</option> 
       <option value="du" >Dutch</option> 
       </select> 
      </form> 

然後,這是我的routes.php文件,

Route::post('/locale', function(){ 

    \App::setLocale(Request::Input('locale')); 

    return redirect()->back(); 
}); 

而且它不工作。

在我的項目,路徑是這樣的

resources/ 
/du 
    navigation.php 
/en 
    /navigation.php 

從荷蘭(DU) 'navigation.php'

<?php 
return [ 
    "home" => 'Home-test-dutch', 
]; 

,爲英語(EN) 'navigation.php'

<?php 
return [ 
    "home" => 'Home', 
]; 
+0

setLocale不是持久的,所以改變它然後重定向會使其成爲默認值。期待使用會話(或數據庫)和中間件來爲用戶做出永久性更改。我應該注意到,如果這是一個面向公衆的網站,你應該爲不同的語言使用不同的網址。 – Devon

回答

1

App::setLocale()是不是永久性的。 我有一個類似的問題之前,所以我創建了一箇中間件:

<?php 

namespace App\Http\Middleware; 

use Closure; 

class SetLocale 
{ 
    /** 
     * Handle an incoming request. 
     * 
     * @param \Illuminate\Http\Request $request 
     * @param \Closure $next 
     * @return mixed 
     */ 
    public function handle($request, Closure $next) 
    { 
     if (strpos($request->getHttpHost(), 'fr.') === 0) { 
      \App::setLocale('fr'); 
     } else { 
      \App::setLocale('en'); 
     } 
     return $next($request); 
    } 
} 

我註冊這個中間件中app\Http\Kernel

protected $middlewareGroups = [ 
    'web' => [ 
     // ... 
     \App\Http\Middleware\SetLocale::class, 
     // ... 
    ] 
]; 

該腳本適用於兩個領域:http://example.org(en)和http://fr.example.org(FR )。作爲中間件,每次請求都會調用它,所以根據url始終將語言環境設置爲正確的語言環境。

我的路線看起來像:

Route::group(['domain' => 'fr.' . config('app.root-domain')], function() { 
    Route::get('a-propos', '[email protected]'); 
    // ... 
} 
Route::group(['domain' => config('app.root-domain')], function() { 
    Route::get('about', '[email protected]'); 
    // ... 
} 

所以用正確的語言環境響應:

而且我用的是同一個控制器和相同查看,只有2個不同的路線+全球中間件。

希望它會幫助,不知道它是最好的解決方案BTW。此解決方案無需sessio,它與域和/或路由相匹配。它擁有超過基於會話的解決方案的一些優點:

  • 由於會話使用(「神奇」的語言切換)
  • 你可以重寫你的路由沒有可能的錯誤。法國用戶可能希望在他們的網址中看到「/ mon-panier」和英文用戶「/ my-cart」。
  • 在谷歌(SEO)更好的索引,因爲你可以有相關內容的國家真正的指數。
  • 我在生產中使用它!

它可能有它的缺點。

+0

此解決方案僅適用於多個域名 – Froxz

+1

@Froxz,是的,但對於搜索引擎優化目的,您不希望爲面向公衆的網站提供來自同一網址的不同語言。您不一定需要不同的子域名,不同的前綴或其他可能的工作。 – Devon

+0

@Froxz它可以很容易地適應簡單的路線沒有子域,只需更改中間件邏輯。 –

8

App::setLocale()不是持久性的,它僅爲當前請求設置語言環境。你可以做的是:

Route::post('/locale', function(){ 

    session(['my_locale' => Request::Input('locale')]); 

    return redirect()->back(); 
}); 

這將設置session key當前用戶 後,我們將需要一個Middleware檢測區域

<?php namespace App\Http\Middleware; 

use Closure; 
use Illuminate\Http\Request; 
use Illuminate\Foundation\Application; 

class Language { 

    public function __construct(Application $app, Request $request) { 
     $this->app = $app; 
     $this->request = $request; 
    } 

    /** 
    * Handle an incoming request. 
    * 
    * @param \Illuminate\Http\Request $request 
    * @param \Closure $next 
    * @return mixed 
    */ 
    public function handle($request, Closure $next) 
    { 
     $this->app->setLocale(session('my_locale', config('app.locale'))); 

     return $next($request); 
    } 

} 

這將讓會話,如果是空,將回退到您的應用配置中設置的默認語言環境。

打開app\Http\Kernel.php 並添加此行:

protected $middleware = [ 
    \App\Http\Middleware\Language::class, 
]; 

隨着全球middlware或者只是網絡。 希望它幫助你有一個想法,它是如何工作

方案№2 在您的網站應用程序配置

'available_locale' => ['fr', 'gr', 'ja'], 

內創建一個所有可用的語言環境的array中間件裏面,我們將查詢的網址第一段en fr gr cy,如果這部分是available_locales_array我們設置的地點

public function handle($request, Closure $next) 
{ 
     if(in_array($request->segment(1), config('app.available_locales_array'))){ 
      $this->app->setLocale($request->segment(1)); 
     }else{ 
      $this->app->setLocale(config('app.locale')); 
     } 

     return $next($request); 
} 

您將東東d修改app\Providers\RouteServiceProvider設置所有路線的前綴。這樣你就可以訪問它們domain.comdomain.com/fr/French language 查找:mapWebRoutes 這添加到它:

if(in_array($request->segment(1), config('app.available_locales_array'))){ 
    $locale = $request->segment(1); 
}else{ 
    $locale = null; 
} 
Route::group([ 
    'middleware' => 'web', 
    'namespace' => $this->namespace, 
    'prefix' => $locale 
], function ($router) { 
    require base_path('routes/web.php'); 
}); 

這將與國信的所有路線,如「FR克CY」前綴除EN非重複的內容,所以最好不添加到available_locales_array