Skip to content

Commit d47230c

Browse files
authored
Add support for a fallback locale (#71)
1 parent dc2c33b commit d47230c

File tree

5 files changed

+106
-1
lines changed

5 files changed

+106
-1
lines changed

README.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ I know you can get punished for this, but you are one of the hopes of those inno
3030
## 🧩 Features
3131

3232
- [Automatically register](#-register-routes) a route for each locale.
33-
- Use [URL slugs or custom domains](#%EF%B8%8F-supported-locales) (or subdomains).
33+
- Use [URL slugs or custom domains](#-supported-locales) (or subdomains).
3434
- Optionally [omit the locale slug from the URL for your main locale](#%EF%B8%8F-omit-slug-for-main-locale).
3535
- Optionally [translate each segment](#-translate-routes) in your URI's.
3636
- [Generate localized route URL's](#-generate-route-urls) using the `route()` helper.
@@ -90,6 +90,14 @@ Alternatively, you can use a different domain or subdomain for each locale by co
9090
],
9191
```
9292

93+
#### ☑️ Fallback Locale
94+
95+
When provided, this will be used as the fallback locale when a locale provided in the `route()` helper is not present in the list of supported locales.
96+
97+
```php
98+
'fallback_locale' => 'en',
99+
```
100+
93101
#### ☑️ Omit Slug for Main Locale
94102

95103
Specify your main locale if you want to omit its slug from the URL:
@@ -378,6 +386,18 @@ $url = route('en.about', [], true, 'nl'); // /nl/about
378386
> If you do, you will always need to specify a locale to get the URL, because non-localized routes always have priority
379387
> when using the `route()` function.
380388
389+
If the locale parameter for the `route()` helper is not a supported locale, and the route does not exist, a `RouteNotFoundException` will be thrown.
390+
391+
A fallback locale can be provided in the config file. When provided, if the locale parameter for the `route()` helper is not a supported locale, the fallback locale will be used instead.
392+
393+
```php
394+
// when `fallback_locale` is set to "en"
395+
// and supported locales are "en" and "nl"
396+
397+
$url = route('about', [], true, 'nl'); // /nl/about
398+
$url = route('about', [], true, 'wk'); // /en/about
399+
```
400+
381401
### 🚌 Redirect to Routes
382402

383403
Laravel's `Redirector` uses the same `UrlGenerator` as the `route()` function behind the scenes.

config/localized-routes.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
*/
88
'supported-locales' => [],
99

10+
/**
11+
* The fallback locale to use when a provided locale is not supported.
12+
*/
13+
'fallback_locale' => null,
14+
1015
/**
1116
* If you have a main locale and don't want
1217
* to prefix it in the URL, specify it here.

src/UrlGenerator.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ public function route($name, $parameters = [], $absolute = true, $locale = null)
5454
// as a prefix for the route name.
5555
$locale = $locale ?: $currentLocale;
5656

57+
// Check if the locale is supported
58+
if (!in_array($locale, config('localized-routes.supported-locales'))) {
59+
// Use a fallback locale if provided
60+
if (config('localized-routes.fallback_locale')) {
61+
$locale = config('localized-routes.fallback_locale');
62+
}
63+
}
64+
5765
// Normalize the route name by removing any locale prefix.
5866
// We will prepend the applicable locale manually.
5967
$baseName = $this->stripLocaleFromRouteName($name);

tests/TestCase.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@ protected function setSupportedLocales($locales)
6767
Config::set('localized-routes.supported-locales', $locales);
6868
}
6969

70+
/**
71+
* Set the fallback locale config option.
72+
*
73+
* @param string $locale
74+
*
75+
* @return void
76+
*/
77+
protected function setFallbackLocale($locale): void
78+
{
79+
Config::set('localized-routes.fallback_locale', $locale);
80+
}
81+
7082
/**
7183
* Set the 'omit_url_prefix_for_locale' config option.
7284
*

tests/Unit/HelpersFileTest.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
namespace CodeZero\LocalizedRoutes\Tests\Unit;
4+
5+
use CodeZero\LocalizedRoutes\Tests\TestCase;
6+
use Illuminate\Support\Facades\Route;
7+
use Symfony\Component\Routing\Exception\RouteNotFoundException;
8+
9+
class HelpersFileTest extends TestCase
10+
{
11+
/** @test */
12+
function it_returns_localized_routes_with_locale_argument(): void
13+
{
14+
$this->setSupportedLocales(['en', 'nl']);
15+
$this->setAppLocale('en');
16+
17+
Route::localized(function () {
18+
Route::get('route')->name('route');
19+
});
20+
21+
$this->assertEquals(url('en/route'), route('route', [], true, null));
22+
$this->assertEquals(url('en/route'), route('route', [], true, 'en'));
23+
$this->assertEquals(url('nl/route'), route('route', [], true, 'nl'));
24+
}
25+
26+
/** @test */
27+
function it_throws_when_route_helper_locale_is_unsupported(): void
28+
{
29+
$this->setSupportedLocales(['en', 'nl']);
30+
$this->setAppLocale('en');
31+
32+
Route::localized(function () {
33+
Route::get('route')->name('route');
34+
});
35+
36+
if ($this->app->version() < 6) {
37+
$this->expectExceptionMessage('Route [wk.route] not defined.');
38+
} else {
39+
$this->expectException(RouteNotFoundException::class);
40+
}
41+
42+
route('route', [], true, 'wk');
43+
}
44+
45+
/** @test */
46+
function it_uses_fallback_locale_when_route_helper_locale_is_unsupported(): void
47+
{
48+
$this->setSupportedLocales(['en', 'nl']);
49+
$this->setAppLocale('en');
50+
$this->setFallbackLocale('en');
51+
52+
Route::localized(function () {
53+
Route::get('route')->name('route');
54+
});
55+
56+
$this->assertEquals(url('en/route'), route('route', [], true, 'en'));
57+
$this->assertEquals(url('nl/route'), route('route', [], true, 'nl'));
58+
$this->assertEquals(url('en/route'), route('route', [], true, 'wk'));
59+
}
60+
}

0 commit comments

Comments
 (0)