我想根据所选语言创建具有许多翻译路由的应用程序.我曾经描述过3 methods of creating URLs in multilingual websites岁.

In this case it should be the first method from mentioned topic so:

  1. 我有一种默认语言
  2. I can have many other languages
  3. Current language should be calculated only by URL (without cookies/sessions) to make it really friendly also for search engines
  4. For default language there should be no prefix in URL, for other languages should be language prefix after domain
  5. Each part of url should be translated according to the current language.

假设我已经设置了默认语言pl和其他两种语言enfr.我只有3页-主页,联系页面和关于页面.

网站的URL应该是这样的:

/
/[about]
/[contact]
/en
/en/[about]
/en/[contact]
/fr
/fr/[about]
/fr/[contact]

whereas [about] and [contact] should be translated according to selected language, for example in English it should be left contact but for Polish it should be kontakt and so on.

如何做到尽可能简单?

推荐答案

First step:

Go to app/lang directory and create here translations for your routes for each language. You need to create 3 routes.php files - each in separate language directory (pl/en/fr) because you want to use 3 languages

For Polish:

<?php

// app/lang/pl/routes.php

return array(

    'contact' => 'kontakt',
    'about'   => 'o-nas'
);

英语:

<?php

// app/lang/en/routes.php

return array(
    'contact' => 'contact',
    'about'   => 'about-us'
);

对于法语:

<?php

// app/lang/fr/routes.php

return array(
    'contact' => 'contact-fr',
    'about'   => 'about-fr'
);

Second step:

Go to app/config/app.php file.

You should find line:

'locale' => 'en',

and change it into language that should be your primary site language (in your case Polish):

'locale' => 'pl',

You also need to put into this file the following lines:

/**
 * List of alternative languages (not including the one specified as 'locale')
 */
'alt_langs' => array ('en', 'fr'),

/**
 *  Prefix of selected locale  - leave empty (set in runtime)
 */
'locale_prefix' => '',

alt_langs config中,您可以设置其他语言(在您的示例enfr中),它们应该与第一步创建带有翻译的文件时的文件名相同.

And locale_prefix is the prefix for your locale. You wanted no prefix for your default locale so it's set to empty string. This config will be modified in runtime if other language than default will be selected.

Third step

转到你的app/routes.php文件并放入他们的内容(这是app/routes.php文件的全部内容):

<?php

// app/routes.php

/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the Closure to execute when that URI is requested.
|
*/


/*
 *  Set up locale and locale_prefix if other language is selected
 */
if (in_array(Request::segment(1), Config::get('app.alt_langs'))) {

    App::setLocale(Request::segment(1));
    Config::set('app.locale_prefix', Request::segment(1));
}


/*
 * Set up route patterns - patterns will have to be the same as in translated route for current language
 */
foreach(Lang::get('routes') as $k => $v) {
    Route::pattern($k, $v);
}


Route::group(array('prefix' => Config::get('app.locale_prefix')), function()
{
    Route::get(
        '/',
        function () {
            return "main page - ".App::getLocale();
        }
    );


    Route::get(
        '/{contact}/',
        function () {
            return "contact page ".App::getLocale();
        }
    );



    Route::get(
        '/{about}/',
        function () {
            return "about page ".App::getLocale();

        }
    );

});

As you see first you check if the first segment of url matches name of your languages - if yes, you change locale and current language prefix.

Then in tiny loop, you set requirements for your all route names (you mentioned that you want have about and contact translated in URL) so here you set them as the same as defined in routes.php file for current language.

最后,您创建的路由组的前缀将与您的语言相同(对于默认语言,它将是空的),在组内您只需创建路径,但这些参数aboutcontact被视为variables,所以您使用{about}{contact}语法.

You need to remember that in that case {contact} in all routes will be checked if it's the same as you defined it in first step for current language. If you don't want this effect and want to set up routes manually for each route using where, there's alternative app\routes.php file without loop where you set contact and about separately for each route:

<?php

// app/routes.php

/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the Closure to execute when that URI is requested.
|
*/

/*
 *  Set up locale and locale_prefix if other language is selected
 */
if (in_array(Request::segment(1), Config::get('app.alt_langs'))) {

    App::setLocale(Request::segment(1));
    Config::set('app.locale_prefix', Request::segment(1));
}


Route::group(array('prefix' => Config::get('app.locale_prefix')), function()
{
    Route::get(
        '/',
        function () {
            return "main page - ".App::getLocale();
        }
    );


    Route::get(
        '/{contact}/',
        function () {
            return "contact page ".App::getLocale();
        }
    )->where('contact', Lang::get('routes.contact'));



    Route::get(
        '/{about}/',
        function () {
            return "about page ".App::getLocale();

        }
    )->where('about', Lang::get('routes.about'));


});

Fourth step:

你没有提到它,但是还有一件事你可以考虑.如果有人使用url /en/something,而something不是正确的路由,我认为最好的解决方案是重定向.但是你不应该重定向到/,因为它是默认语言,而是/en.

So now you can open app/start/global.php file and create here 301 redirection for unknown urls:

// app/start/global.php

App::missing(function()
{
   return Redirect::to(Config::get('app.locale_prefix'),301);
});

Laravel相关问答推荐

spatie 包 laravel-tags 在迁移中没有 down() 函数是有原因的吗

laravel Eloquent 模型更新事件未触发

未捕获的 TypeError:Vue.component 不是函数

如何在 Laravel Passport 中获取刷新令牌?

Laravel 5 控制台( artisan )命令单元测试

Laravel 5 make:控制器在应用程序文件夹而不是控制器文件夹中创建控制器

未找到 PHP 5.4 和 Laravel 类Memcached

找不到列:1054字段列表中的未知列0-Laravel-我的代码中的任何地方都没有0列

为什么客户凭证应该与 Laravel Passport 中的用户相关联?

Laravel 5.4 有时验证规则不起作用

命令未定义异常

防止 Eloquent 查询上的模型水合

在 Laravel 5 控制器中找不到类App\Http\Controllers\DB

如何使用 Laravel 测试授权重定向?

在 Laravel 中结合 AND/OR Eloquent的查询

Carbon解析到 ISO8601

Laravel 5 - 从控制器级别的所有请求对象中删除参数

Laravel 用户能力

如何判断 Laravel 集合是否为空?

count() 参数必须是数组或在 laravel 中实现可数的对象