From 00ed4af3633076e98dc58d317125b7f17d3c64f4 Mon Sep 17 00:00:00 2001 From: Adam Nielsen <1765602+iwasherefirst2@users.noreply.github.com> Date: Sun, 13 Oct 2019 12:19:29 +0200 Subject: [PATCH] Improve config description and readme.md (#666) * Improve config description and readme.md Many issues show that it is difficult to understand how `hideDefaultLocaleInURL` and `useAcceptLanguageHeader` work, especially how the middleware will effect them and if they are used in combination. Also the description of hideDefaultLocaleInURL was outdated in the config file. This commit is an attempt to be more clear about these configuration setup and the behaviour of the associated middleware. * Minor adjustments to Readme.md --- README.md | 73 +++++++++++++++++++++++-------------------- src/config/config.php | 32 ++++++++++++++----- 2 files changed, 64 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 1800f2a..43d69bf 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,9 @@ Easy i18n localization for Laravel, an useful tool to combine with Laravel local Install the package via composer: `composer require mcamara/laravel-localization` -In Laravel 5.5, the service provider and facade will automatically get registered. For older versions of the framework, follow the steps below: +### For Laravel 5.4 and below: + +For older versions of the framework, follow the steps below: Register the service provider in `config/app.php` @@ -151,11 +153,38 @@ Template files and all locale files should follow the [Lang class](http://larave ### Middleware -Moreover, this package includes a middleware object to redirect all "non-localized" routes to the corresponding "localized". +The packages ships with useful middleware. The behavior depends on the settings of `hideDefaultLocaleInURL` +and `useAcceptLanguageHeader` in `config/laravellocalization.php`: + +#### LocaleSessionRedirect + +Whenever a locale is present in the url, it will be stored in the session by this middleware. + +In there is no locale present in the url, then this middleware will check the following + + - If no locale is saved in session and `useAcceptLanguageHeader` is set to true, compute locale from browser and redirect to url with locale. + - If a locale is saved in session redirect to url with locale, unless its the default locale and `hideDefaultLocaleInURL` is set to true. + +For example, if a user navigates to http://url-to-laravel/test and `en` is the current locale, it would redirect him automatically to http://url-to-laravel/en/test. + +#### LaravelLocalizationRedirectFilter + +When the default locale is present in the url and `hideDefaultLocaleInURL` is set to true, then the middleware redirects to the url without locale. + +For example, if `es` is the default locale, then http://url-to-laravel/es/test would be redirected to http://url-to-laravel/test and the`App::getLocale()` would be +set to `es`. -So, if a user navigates to http://url-to-laravel/test and the system has this middleware active and 'en' as the current locale for this user, it would redirect (302) him automatically to http://url-to-laravel/en/test. This is mainly used to avoid duplicate content and improve SEO performance. +#### LaravelLocalizationViewPath -To do so, you have to register the middleware in the `app/Http/Kernel.php` file like this: +Register this middleware to set current locale as view-base-path. + +Now you can wrap your views in language-based folders like the translation files. + +`resources/views/en/`, `resources/views/fr`, ... + +#### Register Middleware + +You may register the above middleware in the `app/Http/Kernel.php` file and in the `Route:group` like this: ```php \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class, - 'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class, - 'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class, - 'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class - // REDIRECTION MIDDLEWARE + 'localize' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class, + 'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class, + 'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class, + 'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class ]; } ``` - ```php -// app/Http/routes.php +// routes/web.php Route::group( [ @@ -190,35 +217,13 @@ Route::group( ], function() { - /** ADD ALL LOCALIZED ROUTES INSIDE THIS GROUP **/ - Route::get('/', function() - { - return View::make('hello'); - }); - - Route::get('test',function(){ - return View::make('test'); - }); + //... }); /** OTHER PAGES THAT SHOULD NOT BE LOCALIZED **/ ``` -In order to activate it, you just have to attach this middleware to the routes you want to be accessible localized. - -If you want to hide the default locale but always show other locales in the url, switch the `hideDefaultLocaleInURL` config value to true. Once it's true, if the default locale is en (english) all URLs containing /en/ would be redirected to the same url without this fragment '/' but maintaining the locale as en (English). - -When `hideDefaultLocaleInURL` and `useAcceptLanguageHeader` are both set to true,then the language negotiation using the Accept-Language header will only occur while the session('locale') is empty. After negotiation, the session('locale') will be set accordingly and will not be called again. - -### Set current locale as view-base-path - -To set the current locale as view-base-path, simply register the localeViewPath-middlware in your Kernel.php, like it is descriped above. - -Now you can wrap your views in language-based folders like the translation files. - -`resources/views/en/`, `resources/views/fr`, ... - ### Map your own custom lang url segments As you can modify the supportedLocales even by renaming their keys, it is possible to use the string ```uk``` instead of ```en-GB``` to provide custom lang url segments. Of course, you need to prevent any collisions with already existing keys and should stick to the convention as long as possible. But if you are using such a custom key, you have to store your mapping to the ```localesMapping``` array. This ``` diff --git a/src/config/config.php b/src/config/config.php index c433863..e33e448 100644 --- a/src/config/config.php +++ b/src/config/config.php @@ -297,26 +297,44 @@ //'ko' => ['name' => 'Korean', 'script' => 'Hang', 'native' => '한국어', 'regional' => 'ko_KR'], ], - // Negotiate for the user locale using the Accept-Language header if it's not defined in the URL? + // Requires middleware `LaravelSessionRedirect.php`. + // + // Automatically determine locale from browser (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) + // on first call if it's not defined in the URL. Redirect user to computed localized url. + // For example, if users browser language is `de`, and `de` is active in the array `supportedLocales`, + // the `/about` would be redirected to `/de/about`. + // + // The locale will be stored in session and only be computed from browser + // again if the session expires. + // // If false, system will take app.php locale attribute 'useAcceptLanguageHeader' => true, - // If LaravelLocalizationRedirectFilter is active and hideDefaultLocaleInURL - // is true, the url would not have the default application language + // If `hideDefaultLocaleInURL` is true, then a url without locale + // is identical with the same url with default locale. + // For example, if `en` is default locale, then `/en/about` and `/about` + // would be identical. // - // IMPORTANT - When hideDefaultLocaleInURL is set to true, the unlocalized root is treated as the applications default locale "app.locale". - // Because of this language negotiation using the Accept-Language header will NEVER occur when hideDefaultLocaleInURL is true. + // If in addition the middleware `LaravelLocalizationRedirectFilter` is active, then + // every url with default locale is redirected to url without locale. + // For example, `/en/about` would be redirected to `/en`. + // It is recommended to use `hideDefaultLocaleInURL` only in + // combination with the middleware `LaravelLocalizationRedirectFilter` + // to avoid duplicate content (SEO). // + // If `useAcceptLanguageHeader` is true, then the first time + // the locale will be determined from browser and redirect to that language. + // After that, `hideDefaultLocaleInURL` behaves as usual. 'hideDefaultLocaleInURL' => false, // If you want to display the locales in particular order in the language selector you should write the order here. //CAUTION: Please consider using the appropriate locale code otherwise it will not work //Example: 'localesOrder' => ['es','en'], 'localesOrder' => [], - + // If you want to use custom lang url segments like 'at' instead of 'de-AT', you can use the mapping to tallow the LanguageNegotiator to assign the descired locales based on HTTP Accept Language Header. For example you want ot use 'at', so map HTTP Accept Language Header 'de-AT' to 'at' (['de-AT' => 'at']). 'localesMapping' => [], - + // Locale suffix for LC_TIME and LC_MONETARY // Defaults to most common ".UTF-8". Set to blank on Windows systems, change to ".utf8" on CentOS and similar. 'utf8suffix' => env('LARAVELLOCALIZATION_UTF8SUFFIX', '.UTF-8'),