Manage localized routes and use translatable models in a Laravel app.
- Automatically register the routes for each locale you wish to support.
- Optionally remove the locale slug from the URL for your main language.
- Generate localized route URLs using the
trans_route()
helper. - Allow routes to be cached.
- PHP >= 7.4
- Laravel >= 8.x
You can install this package using Composer.
composer require sertxudeveloper/laravel-translatable
First you should publish the configuration file.
php artisan vendor:publish --tag='trans-config'
After running this command, you will now find a translatable.php`` file in the
config` folder.
You can set the locales availables in your application. The localized routes will be registered with all of these locales.
'locales' => ['es', 'en', 'it'],
The fallback locale should be the one that not require to be translated.
'fallback_locale' => 'es',
You can also hide the fallback locale from the URL prefix.
"hide_fallback_locale" => true,
All the routes you want lo localize should be registered inside the Route::localized
closure.
// Not Localized
Route::get('home', [HomeController::class, 'index'])->name('home');
// Localized
Route::localized(function () {
Route::get('blog', [BlogController::class, 'index'])->name('blog')
Route::get('{slug}', [PageController::class, 'index'])->name('page')
});
// Not Localized
Route::get('about', [AboutController::class, 'index'])->name('about');
Inside this closure you can use Route Groups such as Middlewares, Namespaces or even Sub-Domain Routing. This closure will prepend the locale to the route's URI and name.
This will be the result of the viewed configuration examples.
URI | Name | Locale |
---|---|---|
/home | home | es - en - it |
--- | --- | --- |
/blog | blog | es |
/es/blog | es.blog | es |
/en/blog | en.blog | en |
/it/blog | it.blog | it |
--- | --- | --- |
/{slug} | page | es |
/es/{slug} | es.page | es |
/en/{slug} | en.page | en |
/it/{slug} | it.page | it |
--- | --- | --- |
/about | about | es - en - it |
Beware that you don't register the same URL twice when omitting the locale. You can't have a localized /about route and also register a non-localized /about route in this case. The same idea applies to the / (root) route! Also note that the route names still have the locale prefix.
You should use the trans_route
helper in order to get the requested route localized. To this helper you can pass a route name or a route url, in booth cases it will be localized.
trans_route($name, $parameters = [], $absolute = false, $locale = null)
If you pass only the route it will be localized using the current locale ('en'
).
trans_route('blog') // /en/blog
You can also pass params to the helper.
trans_route('page', ['help']) // /en/help
The third param is a boolean to make it absolute or not.
trans_route('page', ['help'], true) // https://yourdomain.test/en/help
trans_route('page', ['help'], false) // /en/help
The last param is used for specify the locale to use.
trans_route('blog', [], false, 'it') // /it/blog
If you're building a dropdown or similar with links to change the locale of the application, you should use the switch_to_locale
helper.
switch_to_locale('en') // Changes to 'en' locale without changing the route
You can to customize the name of the translations tables.
'table_suffix' => '_translations'
The usage of this value will be the following one. If you have the model Page
with the trait HasTranslations
and the model table is pages
.
This package will look up for the translations at the table page_translations
. Always the model table followed by the table suffix in the config file.
The translations tables should contain the translatable fields from the model, the id, a column locale
to specify the language saved, created_at
and updated_at
.
The column deleted_at
should never be in the translations table, regardless the models is softDeleted
or not.
As you can see in the following example,
id | name | slug | excerpt | body | image | status | created_at | updated_at |
---|---|---|---|---|---|---|---|---|
int | varchar | varchar | varchar | text | varchar | enum | datetime | datetime |
id | locale | name | excerpt | body | created_at | updated_at |
---|---|---|---|---|---|---|
int | varchar(2) | varchar | varchar | text | datetime | datetime |
In order to get a translated attribute you should use the getTranslated
method.
$post = Post::find(1);
echo $post->getTranslated('name');
In production, you can safely cache your routes per usual.
php artisan route:cache
Copyright © 2022 Sertxu Developer