1

我正在使用 Mcamara Laravel/localization ( https://github.com/mcamara/laravel-localization ),如果 URL 中不存在用于 SEO 的默认语言,我想重定向到默认语言。

如果我去 www.mydomain.com,它应该重定向到 www.mydomain.com/en。如果我去 www.mydomain.com/something,它应该重定向到 www.mydomain.com/en/something。

我想重定向以避免与 www.mydomain.com 和 www.mydomain.com/en 重复的内容,因为它们是相同的内容和相同的语言。我不想要两个具有相同内容的 URL。如果您的默认语言是“en”,那么您在 www.mydomain.com 和 www.mydomain.com/en/ 上的内容相同

我该如何做这个重定向?.htaccess 或路由文件?

我无法配置它。谢谢!

4

2 回答 2

3

我从未使用过 mcamara/laravel-localization 包,但我想您可以创建一个简单的路由来检测何时未在 URL 中设置语言并重定向到默认语言。

像这样的东西:

Route::get('/', function(){
    return Redirect::to(Config::get('app.default_language'));  
});

但我建议你设置一个 cookie,这样当用户切换到不同的语言时,你会保留这种语言,如果用户返回主页“/”,你会重定向到这种语言而不是默认语言。

根据 OP 评论更新:

如果要重定向所有不包含语言的路由,则需要执行类似的操作:

应用程序/filters.php:

App::before(function($request){

  $params = explode('/', Request::path());

  if(count($params) >= 1){

    $language = $params[0];
    $languages = Config::get('app.languages'); //Available languages in your app ex.: array('en', 'fr', 'es')

    if(!in_array($language, $languages)){

      $default_language = Config::get('app.default_language');

      return Redirect::to($default_language.'/'.Request::path());
    }
  } 
});

注意:我没有尝试代码,仅供参考。

于 2013-10-14T19:41:38.740 回答
2

这个答案的灵感来自@FR6,他的答案很旧,并没有涵盖所有问题,所以我做了另一个实现。

我用在 laravel 8.0 中测试的中间件和路由分组处理了这个问题

在你的路由文件web.php 中分组所有需要本地化参数的路由

Route::group([
    'prefix' => '{locale}',
    'middleware' => 'setLocale'
], function() {
    // put your routes here
    Route::get('/welcome', function(){
       return "Hello";
    });
});
// add this so when you call route('...') you don't get the error "parameter 'locale' is not set"
// this is required because all laravel's default auth routes won't add the 'locale' parameter
\Illuminate\Support\Facades\URL::defaults(['locale' => app('locale-for-client')]);

// redirect the home page route to a specific locale
Route::get('/', function () {
    return redirect(app('locale-for-client'));
});

创建中间件SetLocalephp artisan make:middleware SetLocale

app\Middleware\SetLocale.php中,如果在给定的 url 上找不到语言环境,我们将重定向到正确的路由

public function handle(Request $request, Closure $next)
    {
        $url_lang = $request->segment(1);
        if($url_lang !== 'api') {
            if (!in_array($url_lang, config('app.locales'), true)) {
                return redirect(app('locale-for-client') . '/' . request()->path());
            }
            app()->setLocale($url_lang);
        }
        return $next($request);
    }

在app\Http\Kernel.php中注册中间件

protected $routeMiddleware = [
        ...
        'setLocale' => \App\Http\Middleware\SetLocale::class,
    ];

AppServiceProvider中,我们将定义回退语言。在我的实现中,我使用客户端 cookie 和浏览器定义的语言环境来获取客户端语言环境。

    public function register()
    {
         $this->app->singleton('locale-for-client', function(){
            $seg = request()->segment(1);
            if(in_array($seg, config('app.locales'), true))
            {
                // if the current url already contains a locale return it
                return $seg;
            }
            if(!empty(request()->cookie('locale')))
            {
                // if the user's 'locale' cookie is set we want to use it
                $locale = request()->cookie('locale');
            }else{
                // most browsers now will send the user's preferred language with the request
                // so we just read it
                $locale = request()->server('HTTP_ACCEPT_LANGUAGE');
                $locale = substr($locale, 0, 2);
            }
            if(in_array($locale, config('app.locales'), true))
            {
                return $locale;
            }
            // if the cookie or the browser's locale is invalid or unknown we fallback
            return config('app.fallback_locale');
        });
    }

接下来想在config\app.php 中设置你的语言环境

    'locales' => ['en', 'ar', 'fr'],
    'locales_text_display' => ['en' => 'English', 'ar' => 'العربية', 'fr' => 'Français'],
    'fallback_locale' => 'en',

可选的

由于您已经设置了应用程序区域设置,现在您可能希望让客户根据需要更改他们的区域设置。

  1. 创建一个控制器php artisan make:controller AppLocaleController
  2. 在控制器 AppLocaleController中创建方法更新
public function update()
{
   if(in_array(request('locale'), config('app.locales'), true))
   {
      // using cookie('locale', request('locale')) will encrypt the cookie
      // manually set the cookie
      header("Set-Cookie:locale=".request('locale').";Max-Age=300000;path=/");
      return redirect(url('/'));
   }
   abort(400);
}
  1. 注册控制器路由
Route::post('/api/setLocale', [\App\Http\Controllers\AppLanguageController::class, 'update'])
    ->name('locale.update');
于 2021-03-26T13:45:35.270 回答