【问题标题】:What's the best logic for switching language in Laravel?在 Laravel 中切换语言的最佳逻辑是什么?
【发布时间】:2016-07-17 20:41:56
【问题描述】:

我正在使用 Laravel 本地化来提供两种不同的语言。我已经设置了所有路径,mydomain.com/en/bla 提供英语并存储“en”会话变量,mydomain.com/he/bla 提供希伯来语并存储“he”会话变量。但是,我想不出一种体面的方式来提供语言切换链接。这将如何运作?

【问题讨论】:

  • 嗨,本杰明,我正试图为我正在用希伯来语和英语(使用 Laravel 3)构建的网站做这件事。您在问题中说您已经设置了所有路径。我想知道您是否可以帮助我了解如何正确设置路径或将我指向某个网站或论坛帖子。谢谢!
  • @Jonathan 这是一个早期版本,我很确定它可以正常工作:bitbucket.org/benjaminrh/gidonim-laravel。只需忽略糟糕的代码;)

标签: php localization laravel


【解决方案1】:

我已经通过将它添加到 routes.php 中的 before 过滤器解决了我的问题:

// Default language ($lang) & current uri language ($lang_uri)
$lang = 'he';
$lang_uri = URI::segment(1);

// Set default session language if none is set
if(!Session::has('language'))
{
    Session::put('language', $lang);
}

// Route language path if needed
if($lang_uri !== 'en' && $lang_uri !== 'he')
{
    return Redirect::to($lang.'/'.($lang_uri ? URI::current() : ''));
}
// Set session language to uri
elseif($lang_uri !== Session::get('language'))
{
    Session::put('language', $lang_uri);
}

// Store the language switch links to the session
$he2en = preg_replace('/he\//', 'en/', URI::full(), 1);
$en2he = preg_replace('/en\//', 'he/', URI::full(), 1);
Session::put('he2en', $he2en);
Session::put('en2he', $en2he);

【讨论】:

    【解决方案2】:

    这是我最初在 laravel 论坛上发布的帖子,但可能对其他人有帮助,所以我也将其发布在这里。

    我在为我的应用程序构建一个简单的语言切换器时遇到了一些麻烦,而且论坛上的信息有点旧(一些帖子),所以我制作了这段简单的代码,它可以让你在你的应用程序上更改语言变得超级容易即时应用。

    我的视图中的语言字符串如下:

    {{ __('languagefile.the_language_string'); }}
    

    我得到带有 URL 的语言,我认为这是最好的方式,它也有利于 seo 和人们共享的链接。示例:

    www.myapp.com/fi/support (Finnish)
    www.myapp.com/en/support (English)
    www.myapp.com/sv/support (Swedish)
    

    好的,所以问题是我想要一种简单的方法来即时更改语言,而不必弄乱会话和 cookie。以下是我的制作方法:

    在您的库文件夹中创建一个名为 chooselang.php

    的库

    在里面插入这段代码:

    class Chooselang extends HTML {
        /**
         * Generate a Language changer link.
         *
         * <code>
         *      // Generate a link to the current location,
         *      // but still change the site langauge on the fly
         *      // Change $langcode to desired language, also change the Config::set('application.language', 'YOUR-LANG-HERE')); to desired language
         *      // Example
         *      echo Chooselang::langslug(URI::current() , $langcode = 'Finnish' . Config::set('application.language', 'fi'));
         * </code>
         *
         * @param  string  $url
         * @param  string  $langcode
         * @param  array   $attributes
         * @param  bool    $https
         * @return string
         */
    
        public static function langslug($url, $langcode = null, $attributes = array(), $https = null)
        {
            $url = URL::to($url, $https);
    
            if (is_null($langcode)) $langcode = $url;
    
            return '<a href="'.$url.'"'.static::attributes($attributes).'>'.static::entities($langcode).'</a>';
        }
    
    }
    

    在此之后,您就可以生成您的 url 切换器 URL:s。只需像添加任何其他 Blade 链接一样添加它们。

    示例如何生成芬兰语、瑞典语和英语的链接(使用 Blade)

      {{ Chooselang::langslug(URI::current() , $langcode = 'Fin' . Config::set('application.language', 'fi')); }}
      {{ Chooselang::langslug(URI::current() , $langcode = 'Swe' . Config::set('application.language', 'sv')); }}
      {{ Chooselang::langslug(URI::current() , $langcode = 'Eng' . Config::set('application.language', 'en')); }}
    

    上面将生成始终在当前页面上的 URL:s,并将 lang slug 更改为您想要的。这样,语言就会更改为您想要的语言,并且用户自然会停留在同一页面上。默认语言 slug 永远不会添加到 url。

    生成的 url 看起来像:

    <a href="http://localhost/laravel/public/support">Fin</a>
    <a href="http://localhost/laravel/public/sv/support">Swe</a>
    <a href="http://localhost/laravel/public/en/support">Eng</a>
    

    PS。如果您将这些链接添加到您的主模板文件中,这些链接将特别有用。

    【讨论】:

    • 你为什么使用 {{ __('languagefile.the_language_string'); }} ,我认为使用翻译 trans() 或 Lang::get 。
    • 是的,我相信它也可以。这个答案来自 Laravel 3 天,所以我不确定你当时是不是一个 Lang:: Facade...
    • 对于来自 google 的任何人,在带有 Laravel 4 的 Blade 文件中,您可以使用 @lang('file.String') 简写,相当于说 {{ Lang::get('file.String ') }}
    【解决方案3】:

    你可以有一个 Route to hand 语言更改,例如:

    Route::get('translate/(:any)', 'translator@set');

    然后在translator 控制器中的set 操作中可以更改会话,具体取决于通过 URL 传递的语言代码。

    您也可以使用

    更改配置设置

    Config::set('application.language', $url_variable');

    控制器示例 - translate.php

    public function action_set($url_variable)
    {
         /* Your code Here */
    }
    

    【讨论】:

    • 就是这样。我目前的解决方案与stormpat's answer 几乎相同,只是我使用中间件。我不想使用默认语言复制内容,不得不向每个控制器添加构造,并且 url 生成变得更加困难。您也可以使用它来传递语言代码作为参数。谢谢。
    【解决方案4】:

    如果您想使用包进行本地化,以防将来的用户使用 https://github.com/mcamara/laravel-localization 有一个很棒的包。它易于安装,并且有很多助手。

    【讨论】:

      【解决方案5】:

      这个问题仍然出现在 Google 搜索中,所以如果您使用的是 Laravel 4 或 5,以及 mcamara/laravellocalization,这就是答案。

      <ul>
          <li class="h5"><strong><span class="ee-text-dark">{{ trans('common.chooselanguage') }}:</span></strong> </li>
              @foreach(LaravelLocalization::getSupportedLocales() as $localeCode => $properties)
                  <li>
                     <a rel="alternate" hreflang="{{$localeCode}}" href="{{LaravelLocalization::getLocalizedURL($localeCode) }}">
                         <img src="/img/flags/{{$localeCode}}.gif" /> {{{ $properties['native'] }}}
                     </a>
                 </li>
              @endforeach
      </ul>
      

      请注意,此示例显示标志(在 public/img/flags/{{locale}}.gif 中),要使用它,您需要一些 .css,但您可以修改它以显示文本,如果您想要……

      仅供参考。 mcamara/laravellocalization 文档有示例和很多帮助程序,因此请查看 github 上的文档。 (https://github.com/mcamara/laravel-localization)

      【讨论】:

        【解决方案6】:

        尝试使用 Session 的。像这样的东西:

        控制器:

         class Language_Controller extends Base_Controller {
        
                function __construct(){
                    $this->action_set();
                    parent::__construct();
                }
        
               private function checkLang($lang = null){
                 if(isset($lang)){
                   foreach($this->_Langs as $k => $v){
                     if(strcmp($lang, $k) == 0) $Check = true;
                   }
               }
                return isset($Check) ? $Check : false;
               }
        
               public function action_set($lang = null){
                if(isset($lang) && $this->checkLang($lang)){
                    Session::put('lang', $lang);
                    $this->_Langs['current'] = $lang;
                    Config::set('application.language', $lang);
                } else {
                    if(Session::has('lang')){
                        Config::set('application.language', Session::get('lang'));
                        $this->_Langs['current'] = Session::get('lang');
                    } else {
                        $this->_Langs['current'] = $this->_Default;
                    }
                }
                return Redirect::to('/');
            }
        }
        

        在 Route.php 中:

        Route::get('lang/(:any)', 'language@set');
        

        【讨论】:

          【解决方案7】:

          我一直是这样的:

          $languages = Config::get('lang.languages'); //returns array('hrv', 'eng')
          
          $locale = Request::segment(1); //fetches first URI segment
          
          //for default language ('hrv') set $locale prefix to "", otherwise set it to lang prefix
          if (in_array($locale, $languages) && $locale != 'hrv') {
              App::setLocale($locale);
          } else {
              App::setLocale('hrv');
              $locale = null;
          }
          
          // "/" routes will be default language routes, and "/$prefix" routes will be routes for all other languages
          Route::group(array('prefix' => $locale), function() {
          
              //my routes here
          
          });
          

          来源:http://forumsarchive.laravel.io/viewtopic.php?pid=35185#p35185

          【讨论】:

          • 最简单的方法。
          【解决方案8】:

          我正在做的事情包括两个步骤: 我正在创建一个包含以下字段的语言表:

          标识 |姓名 |蛞蝓

          其中包含例如语言所需的数据

          1 |希腊语 | gr

          2 |英语 | zh

          3 |荷兰语 |去

          我在下面的代码中使用的语言模型是指该表。

          所以,在我的 routes.php 中,我有类似的内容:

          //get the first segment of the url
          $slug = Request::segment(1);   
          $requested_slug = "";
          
          //I retrieve the recordset from the languages table that has as a slug the first url segment of request
          $lang = Language::where('slug', '=', $slug)->first();
          
          //if it's null, the language I will retrieve a new recordset with my default language
          $lang ? $requested_slug = $slug :  $lang = Language::where('slug', '=', **mydefaultlanguage**')->first();
          
          //I'm preparing the $routePrefix variable, which will help me with my forms
          $requested_slug == ""? $routePrefix = "" : $routePrefix = $requested_slug.".";
          
          //and I'm putting the data in the in the session
          Session::put('lang_id', $lang->id);
          Session::put('slug', $requested_slug);
          Session::put('routePrefix', $routePrefix );
          Session::put('lang', $lang->name);
          

          然后我可以使用请求的 slug 作为前缀来编写路由...

          Route::group(array('prefix' =>  $requested_slug), function()
          {
              Route::get('/', function () {
                  return "the language here is gonna be: ".Session::get('lang');
              });
          
              Route::resource('posts', 'PostsController');
              Route::resource('albums', 'AlbumsController');
          });
          

          这可行,但每当我的应用程序中的路线发生变化时,此代码都会向数据库询问语言。 我不知道我怎么能,如果我应该,找出一种机制来检测路由是否更改为另一种语言。

          希望有所帮助。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-01-28
            • 2011-04-17
            • 2010-10-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多