diff --git a/ADDITIONS.md b/ADDITIONS.md
new file mode 100644
index 0000000..a5f2070
--- /dev/null
+++ b/ADDITIONS.md
@@ -0,0 +1,61 @@
+# Additional information
+
+## Installation
+
+### For Laravel 5.4 and below:
+
+For older versions of the framework, follow the steps below:
+
+Register the service provider in `config/app.php`
+
+```php
+ 'providers' => [
+ // [...]
+ Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider::class,
+ ],
+```
+
+You may also register the `LaravelLocalization` facade:
+
+```php
+ 'aliases' => [
+ // [...]
+ 'LaravelLocalization' => Mcamara\LaravelLocalization\Facades\LaravelLocalization::class,
+ ],
+```
+
+## Config
+
+### Service Providers
+
+Otherwise, you can use `ConfigServiceProviders` (check this file for more info).
+
+For example, editing the default config service provider that Laravel loads when it's installed. This file is placed in `app/providers/ConfigServicePovider.php` and would look like this:
+
+```php
+ [
+ 'ace' => array( 'name' => 'Achinese', 'script' => 'Latn', 'native' => 'Aceh' ),
+ 'ca' => array( 'name' => 'Catalan', 'script' => 'Latn', 'native' => 'catalĂ ' ),
+ 'en' => array( 'name' => 'English', 'script' => 'Latn', 'native' => 'English' ),
+ ],
+
+ 'laravellocalization.useAcceptLanguageHeader' => true,
+
+ 'laravellocalization.hideDefaultLocaleInURL' => true
+ ]);
+ }
+
+}
+```
+
+This config would add Catalan and Achinese as languages and override any other previous supported locales and all the other options in the package.
+
+You can create your own config providers and add them on your application config file (check the providers array in `config/app.php`).
diff --git a/README.md b/README.md
index c789ca3..3c899e5 100644
--- a/README.md
+++ b/README.md
@@ -8,32 +8,31 @@
Easy i18n localization for Laravel, an useful tool to combine with Laravel localization classes.
-## Collaborators
-- [Adam Nielsen (iwasherefirst2)](https://github.com/iwasherefirst2)
+The package offers the following:
-Ask [mcamara](https://github.com/mcamara) if you want to be one of them!
+ - Detect language from browser
+ - Smart redirects (Save locale in session/cookie)
+ - Smart routing (Define your routes only once, no matter how many languages you use)
+ - Translatable Routes
+ - Supports caching & testing
+ - Option to hide default locale in url
+ - Many snippets and helpers (like language selector)
## Table of Contents
- Installation
- - Composer
- - Manually
- - Laravel
-- Config
- - Config files
- - Service providers
- Usage
- - Middleware
+- Redirect Middleware
- Helpers
- - Route Model Binding
- Translated Routes
- Caching routes
-- Changelog
- Testing
- Common Issues
- POST is not working
- MethodNotAllowedHttpException
- Validation message is always in default locale
+- Collaborators
+- Changelog
- License
## Laravel compatibility
@@ -52,81 +51,60 @@ Ask [mcamara](https://github.com/mcamara) if you want to be one of them!
Install the package via composer: `composer require mcamara/laravel-localization`
-### For Laravel 5.4 and below:
-
-For older versions of the framework, follow the steps below:
-
-Register the service provider in `config/app.php`
-
-```php
- 'providers' => [
- // [...]
- Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider::class,
- ],
-```
-
-You may also register the `LaravelLocalization` facade:
-
-```php
- 'aliases' => [
- // [...]
- 'LaravelLocalization' => Mcamara\LaravelLocalization\Facades\LaravelLocalization::class,
- ],
-```
-
-## Config
+For Laravel 5.4 and below it necessary to [register the service provider](/ADDITIONS.md#for-laravel-5.4-and-below).
### Config Files
-In order to edit the default configuration (where for e.g. you can find `supportedLocales`) for this package you may execute:
+In order to edit the default configuration you may execute:
```
php artisan vendor:publish --provider="Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider"
```
-After that, `config/laravellocalization.php` will be created. Inside this file you will find all the fields that can be edited in this package.
+After that, `config/laravellocalization.php` will be created.
-### Service Providers
+The configuration options are:
-Otherwise, you can use `ConfigServiceProviders` (check this file for more info).
+ - **supportedLocales** Langauges of your app (Default: English & Spanish).
+ - **useAcceptLanguageHeader** If true, then automatically detect language from browser.
+ - **hideDefaultLocaleInURL** If true, then do not show default locale in url.
+ - **localesOrder** Sort languages in custom order.
+ - **localesMapping** Rename url locales.
+ - **utf8suffix** Allow changing utf8suffix for CentOS etc.
+ - **urlsIgnored** Ignore specific urls.
-For example, editing the default config service provider that Laravel loads when it's installed. This file is placed in `app/providers/ConfigServicePovider.php` and would look like this:
+### Register Middleware
-```php
- [
- 'ace' => array( 'name' => 'Achinese', 'script' => 'Latn', 'native' => 'Aceh' ),
- 'ca' => array( 'name' => 'Catalan', 'script' => 'Latn', 'native' => 'catalĂ ' ),
- 'en' => array( 'name' => 'English', 'script' => 'Latn', 'native' => 'English' ),
- ],
-
- 'laravellocalization.useAcceptLanguageHeader' => true,
+```php
+ true
- ]);
- }
+use Illuminate\Foundation\Http\Kernel as HttpKernel;
+class Kernel extends HttpKernel {
+ /**
+ * The application's route middleware.
+ *
+ * @var array
+ */
+ protected $routeMiddleware = [
+ /**** OTHER MIDDLEWARE ****/
+ 'localize' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
+ 'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
+ 'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
+ 'localeCookieRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleCookieRedirect::class,
+ 'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class
+ ];
}
```
-This config would add Catalan and Achinese as languages and override any other previous supported locales and all the other options in the package.
-
-You can create your own config providers and add them on your application config file (check the providers array in `config/app.php`).
-
-
## Usage
-Laravel Localization uses the URL given for the request. In order to achieve this purpose, a route group should be added into the `routes.php` file. It will filter all pages that must be localized.
+Add the following to your routes file:
```php
-// app/Http/routes.php
+// routes/web.php
Route::group(['prefix' => LaravelLocalization::setLocale()], function()
{
@@ -145,26 +123,54 @@ Route::group(['prefix' => LaravelLocalization::setLocale()], function()
```
-Once this route group is added to the routes file, a user can access all locales added into `supportedLocales` ('en' and 'es' by default, look at the config section to change that option). For example, a user can now access two different locales, using the following addresses:
+Once this route group is added to the routes file, a user can access all locales added into `supportedLocales` (`en` and `es` by default).
+For example, the above route file creates the following addresses:
```
+// Set application language to English
http://url-to-laravel/en
+http://url-to-laravel/en/test
+
+// Set application language to Spanish
http://url-to-laravel/es
+http://url-to-laravel/es/test
+
+// Set application language to English or Spanish (depending on browsers default locales)
+// if nothing found set to default locale
http://url-to-laravel
+http://url-to-laravel/test
```
+The package sets your application locale `App::getLocale()` according to your url. The locale may then be used for [Laravel's localization features](http://laravel.com/docs/localization).
+
+You may add middleware to your group like this:
-If the locale is not present in the url or it is not defined in `supportedLocales`, the system will use the application default locale or the user's browser default locale (if defined in config file).
+```php
+Route::group(
+[
+ 'prefix' => LaravelLocalization::setLocale(),
+ 'middleware' => [ 'localeSessionRedirect', 'localizationRedirect', 'localeViewPath' ]
+], function(){ //...
+});
+```
-Once the locale is defined, the locale variable will be stored in a session (if the middleware is enabled), so it is not necessary to write the /lang/ section in the url after defining it once, using the last known locale for the user. If the user accesses to a different locale this session value would be changed, translating any other page he visits with the last chosen locale.
+### Recommendations
-Template files and all locale files should follow the [Lang class](http://laravel.com/docs/5.0/localization).
+***1.***: It is **strongly** recommended to use a [redirecting middleware](#redirect-middleware).
+Urls without locale should only be used to determine browser/default locale and to redirect to the [localized url](#localized-urls).
+Otherwise, when search engine robots crawl for example `http://url-to-laravel/test` they may get different language content for each visit.
+Also having multiple urls for the same content creates a SEO duplicate-content issue.
-### Middleware
+***2.***: It is **strongly** recommended to [localize your links](#localized-urls), even if you use a redirect middleware.
+Otherwise, you will cause at least one redirect each time a user clicks on a link.
+Also, any action url from a post form must be localized, to prevent that it gets redirected to a get request.
-The packages ships with useful middleware. The behavior depends on the settings of `hideDefaultLocaleInURL`
+
+## Redirect Middleware
+
+The following redirection middleware depends on the settings of `hideDefaultLocaleInURL`
and `useAcceptLanguageHeader` in `config/laravellocalization.php`:
-#### LocaleSessionRedirect
+### LocaleSessionRedirect
Whenever a locale is present in the url, it will be stored in the session by this middleware.
@@ -175,7 +181,7 @@ In there is no locale present in the url, then this middleware will check the fo
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.
-#### LocaleCookieRedirect
+### LocaleCookieRedirect
Similar to LocaleSessionRedirect, but it stores value in a cookie instead of a session.
@@ -189,291 +195,146 @@ In there is no locale present in the url, then this middleware will check the fo
For example, if a user navigates to http://url-to-laravel/test and `de` is the current locale, it would redirect him automatically to http://url-to-laravel/de/test.
-#### LaravelLocalizationRedirectFilter
+### 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`.
-#### LaravelLocalizationViewPath
-Register this middleware to set current locale as view-base-path.
+## Helpers
-Now you can wrap your views in language-based folders like the translation files.
+This package comes with a bunch of helpers.
-`resources/views/en/`, `resources/views/fr`, ...
+### Localized URLs
+Localized URLS taken into account [route model binding]([https://laravel.com/docs/master/routing#route-model-binding]) when generating the localized route,
+aswell as the `hideDefaultLocaleInURL` and [Translated Routes](#translated-routes) settings.
-#### Register Middleware
-You may register the above middleware in the `app/Http/Kernel.php` file and in the `Route:group` like this:
+#### Get localized URL
```php
- \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
- 'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
- 'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
- 'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class
- ];
-}
+ // If current locale is Spanish, it returns `/es/test`
+ @lang('Follow this link')
```
-```php
-// routes/web.php
-
-Route::group(
-[
- 'prefix' => LaravelLocalization::setLocale(),
- 'middleware' => [ 'localeSessionRedirect', 'localizationRedirect', 'localeViewPath' ]
-],
-function()
-{
- //...
-});
-
-/** OTHER PAGES THAT SHOULD NOT BE LOCALIZED **/
-
-```
-
-### 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 ```
-localesMapping``` is needed to enable the LanguageNegotiator to correctly assign the desired locales based on HTTP Accept Language Header. Here is a quick example how to map HTTP Accept Language Header 'en-GB' to url segment 'uk':
+#### Get localized URL for an specific locale
+Get current URL in specific locale:
```php
-// config/laravellocalization.php
-
-'localesMapping' => [
- 'en-GB' => 'uk'
-],
+// Returns current url with English locale.
+{{ LaravelLocalization::getLocalizedURL('en') }}
```
-After that ```http://url-to-laravel/en-GB/a/b/c``` becomes ```http://url-to-laravel/uk/a/b/c```.
+### Get Clean routes
+
+Returns a URL clean of any localization.
```php
-LaravelLocalization::getLocalizedURL('en-GB', 'a/b/c'); // http://url-to-laravel/uk/a/b/c
-LaravelLocalization::getLocalizedURL('uk', 'a/b/c'); // http://url-to-laravel/uk/a/b/c
+// Returns /about
+{{ LaravelLocalization::getNonLocalizedURL('/es/about') }}
```
-## Helpers
-
-This package comes with some useful functions, like:
+### Get URL for an specific translation key
+Returns a route, [localized](#translated-routes) to the desired locale. If the translation key does not exist in the locale given, this function will return false.
-### Get localized url
```php
- /**
- * Returns an URL adapted to $locale or current locale.
- *
- * @param string $url URL to adapt. If not passed, the current url would be taken.
- * @param string|bool $locale Locale to adapt, false to remove locale
- *
- * @throws UnsupportedLocaleException
- *
- * @return string URL translated
- */
- public function localizeURL($url = null, $locale = null)
+// Returns /es/acerca
+{{ LaravelLocalization::getURLFromRouteNameTranslated('es', 'routes.about') }}
```
-//Should be called in a view like this:
-{{ LaravelLocalization::localizeURL('/about') }}
+### Get Supported Locales
-It returns a URL localized to the desired locale (if no locale is given, it uses current locale).
+Return all supported locales and their properties as an array.
+```php
+{{ LaravelLocalization::getSupportedLocales() }}
+```
-#### Route Model Binding
-Note that [route model binding]([https://laravel.com/docs/master/routing#route-model-binding]) is taken into account when generating the localized route.
+### Get Supported Locales Custom Order
-### Get Clean routes
+Return all supported locales but in the order specified in the configuration file. You can use this function to print locales in the language selector.
```php
-/**
- * It returns an URL without locale (if it has it)
- * Convenience function wrapping getLocalizedURL(false)
- *
- * @param string|false $url URL to clean, if false, current url would be taken
- *
- * @return stringURL with no locale in path
- */
-public function getNonLocalizedURL($url = null)
-
-//Should be called in a view like this:
-{{ LaravelLocalization::getNonLocalizedURL('/es/about') }}
+{{ LaravelLocalization::getLocalesOrder() }}
```
-It returns a URL clean of any localization.
+### Get Supported Locales Keys
-### Get URL for an specific translation key
+Return an array with all the keys for the supported locales.
```php
-/**
- * Returns an URL adapted to the route name and the locale given
- *
- * @throws UnsupportedLocaleException
- *
- * @param string|boolean $locale Locale to adapt
- * @param string $transKeyName Translation key name of the url to adapt
- * @param array $attributes Attributes for the route (only needed if transKeyName needs them)
- *
- * @return string|false URL translated
- */
-public function getURLFromRouteNameTranslated($locale, $transKeyName, $attributes = array())
-
-//Should be called in a view like this:
-{{ LaravelLocalization::getURLFromRouteNameTranslated('es', 'routes.about') }}
+{{ LaravelLocalization::getSupportedLanguagesKeys() }}
```
-It returns a route, localized to the desired locale using the locale passed. If the translation key does not exist in the locale given, this function will return false.
+### Get Current Locale
-### Get Supported Locales
+Return the key of the current locale.
```php
-/**
- * Return an array of all supported Locales
- *
- * @return array
- */
-public function getSupportedLocales()
-
-//Should be called like this:
-{{ LaravelLocalization::getSupportedLocales() }}
+{{ LaravelLocalization::getCurrentLocale() }}
```
-This function will return all supported locales and their properties as an array.
-
-### Get Supported Locales Custom Order
+### Get Current Locale Name
+Return current locale's name as string (English/Spanish/Arabic/ ..etc).
```php
-/**
- * Return an array of all supported Locales but in the order the user
- * has specified in the config file. Useful for the language selector.
- *
- * @return array
- */
-public function getLocalesOrder()
-
-//Should be called like this:
-{{ LaravelLocalization::getLocalesOrder() }}
+{{ LaravelLocalization::getCurrentLocaleName() }}
```
-This function will return all supported locales but in the order specified in the configuration file. You can use this function to print locales in the language selector.
-
-### Get Supported Locales Keys
-
-```php
-/**
- * Returns supported languages language key
- *
- * @return array keys of supported languages
- */
-public function getSupportedLanguagesKeys()
-
-//Should be called like this:
-{{ LaravelLocalization::getSupportedLanguagesKeys() }}
-```
+### Get Current Locale Direction
-This function will return an array with all the keys for the supported locales.
+Return current locale's direction as string (ltr/rtl).
-### Set Locale
```php
-/**
- * Set and return current locale
- *
- * @param string $locale Locale to set the App to (optional)
- *
- * @return string Returns locale (if route has any) or null (if route does not have a locale)
- */
-public function setLocale($locale = null)
-
-//Should be called in a view like this:
-{{ LaravelLocalization::setLocale(optional string $locale) }}
+{{ LaravelLocalization::getCurrentLocaleDirection() }}
```
-This function will change the application's current locale.
-If the locale is not passed, the locale will be determined via a cookie (if stored previously), the session (if stored previously), browser Accept-Language header or the default application locale (depending on your config file).
-The function has to be called in the prefix of any route that should be translated (see Filters sections for further information).
-### Get Current Locale
+### Get Current Locale Script
+Return the [ISO 15924](http://www.unicode.org/iso15924) code for the current locale script as a string; "Latn", "Cyrl", "Arab", etc.
```php
-/**
- * Returns current language
- *
- * @return string current language
- */
-public function getCurrentLocale()
-
-//Should be called in a view like this:
-{{ LaravelLocalization::getCurrentLocale() }}
+{{ LaravelLocalization::getCurrentLocaleScript() }}
```
-This function will return the key of the current locale.
+### Set view-base-path to current locale
-### Get Current Locale Name
+Register the middleware `LaravelLocalizationViewPath` to set current locale as view-base-path.
-```php
-/**
- * Returns current locale name
- *
- * @return string current locale name
- */
-public function getCurrentLocaleName()
-
-//Should be called in a view like this:
-{{ LaravelLocalization::getCurrentLocaleName() }}
-```
+Now you can wrap your views in language-based folders like the translation files.
+
+`resources/views/en/`, `resources/views/fr`, ...
-This function will return current locale's name as string (English/Spanish/Arabic/ ..etc).
-### Get Current Locale Direction
+### 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 ```
+localesMapping``` is needed to enable the LanguageNegotiator to correctly assign the desired locales based on HTTP Accept Language Header. Here is a quick example how to map HTTP Accept Language Header 'en-GB' to url segment 'uk':
```php
-/**
- * Returns current locale direction
- *
- * @return string current locale direction
- */
-public function getCurrentLocaleDirection()
-
-//Should be called in a view like this:
-{{ LaravelLocalization::getCurrentLocaleDirection() }}
-```
+// config/laravellocalization.php
-This function will return current locale's direction as string (ltr/rtl).
+'localesMapping' => [
+ 'en-GB' => 'uk'
+],
+```
-### Get Current Locale Script
+After that ```http://url-to-laravel/en-GB/a/b/c``` becomes ```http://url-to-laravel/uk/a/b/c```.
```php
-/**
- * Returns current locale script
- *
- * @return string current locale script
- */
-public function getCurrentLocaleScript()
-
-//Should be called in a view like this:
-{{ LaravelLocalization::getCurrentLocaleScript() }}
+LaravelLocalization::getLocalizedURL('en-GB', 'a/b/c'); // http://url-to-laravel/uk/a/b/c
+LaravelLocalization::getLocalizedURL('uk', 'a/b/c'); // http://url-to-laravel/uk/a/b/c
```
-This function will return the [ISO 15924](http://www.unicode.org/iso15924) code for the current locale script as a string; "Latn", "Cyrl", "Arab", etc.
-
## Creating a language selector
If you're supporting multiple locales in your project you will probably want to provide the users with a way to change language. Below is a simple example of blade template code you can use to create your own language selector.
@@ -491,7 +352,7 @@ If you're supporting multiple locales in your project you will probably want to
```
Here default language will be forced in getLocalizedURL() to be present in the URL even `hideDefaultLocaleInURL = true`.
-Note that Route Model Binding is supported.
+Note that Route Model Binding is supported.
## Translated Routes
@@ -656,6 +517,11 @@ public function testBasicTest()
}
```
+## Collaborators
+- [Adam Nielsen (iwasherefirst2)](https://github.com/iwasherefirst2)
+
+Ask [mcamara](https://github.com/mcamara) if you want to be one of them!
+
## Changelog
View changelog here -> [changelog](CHANGELOG.md)