如何使用SESSION向Laravel 5.3添加多语言

问题描述:

我想向我的网站添加多语言支持,但我不知道如何最好地实现它。 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. 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

我会做一些在中间件:

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

尽管如此,代码优化并不是问题的关键。你是指另一个答案?这还不够清楚。 –