Skip to content

Commit

Permalink
Improve config description and readme.md (#666)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
iwasherefirst2 authored and Marc Cámara committed Oct 13, 2019
1 parent 4f7e882 commit 00ed4af
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 41 deletions.
73 changes: 39 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`

Expand Down Expand Up @@ -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
<?php namespace App\Http;
Expand All @@ -170,18 +199,16 @@ class Kernel extends HttpKernel {
*/
protected $routeMiddleware = [
/**** OTHER 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
// 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(
[
Expand All @@ -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 ```
Expand Down
32 changes: 25 additions & 7 deletions src/config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand Down

0 comments on commit 00ed4af

Please sign in to comment.