Skip to content

Commit 6780fed

Browse files
authored
Custom prefixes (#70)
* add support for custom prefixes for localized routes (#20) * alternatively, use the locale as the route name prefix and the custom prefix only for the URLs * minor fix: `array_key_first()` is a PHP 7.3+ function being used in a repo with support for PHP 7.1+
1 parent 6e77ffd commit 6780fed

File tree

9 files changed

+135
-5
lines changed

9 files changed

+135
-5
lines changed

config/localized-routes.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,14 @@
6868
*/
6969
'use_localizer' => false,
7070

71+
/**
72+
* Map application locale to a custom route prefix.
73+
*
74+
* 'custom_prefixes' => [
75+
* 'en' => 'english',
76+
* 'nl' => 'dutch',
77+
* ]
78+
*/
79+
'custom_prefixes' => [],
80+
7181
];

src/Controller/FallbackController.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public function __invoke()
3232
}
3333
}
3434

35-
return $this->NotFoundResponse();
35+
return $this->notFoundResponse();
3636
}
3737

3838
/**
@@ -54,7 +54,7 @@ protected function findRouteByUrl($url)
5454
*
5555
* @return \Illuminate\Http\Response
5656
*/
57-
protected function NotFoundResponse()
57+
protected function notFoundResponse()
5858
{
5959
$view = Config::get('localized-routes.404_view');
6060

src/LocalizedUrlGenerator.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,13 @@ public function generateFromRequest($locale = null, $parameters = null, $absolut
6969
$urlBuilder->setPath($this->replaceParameters($this->route->uri(), $slugs));
7070
}
7171

72+
// Map the locale string to a prefix.
73+
$prefix = data_get(Config::get('localized-routes.custom_prefixes'), $locale, $locale);
74+
7275
// If custom domains are not used and it is not a registered,
7376
// non localized route, update the locale slug in the path.
7477
if (!$this->hasCustomDomains() && ($this->is404() || $this->isLocalized())) {
75-
$urlBuilder->setSlugs($this->updateLocaleInSlugs($urlBuilder->getSlugs(), $locale));
78+
$urlBuilder->setSlugs($this->updateLocaleInSlugs($urlBuilder->getSlugs(), $prefix));
7679
}
7780

7881
if ($domain = $this->getCustomDomain($locale)) {

src/Macros/LocalizedRoutesMacro.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public static function register()
2828
$setMiddleware = $options['use_locale_middleware']
2929
?? Config::get('localized-routes.use_locale_middleware', false);
3030

31-
$notUsingDomains = is_numeric(array_key_first($locales));
31+
$notUsingDomains = is_numeric(key($locales));
3232

3333
if ($omitPrefix && $notUsingDomains) {
3434
// Move the omitted locale to the end of the array
@@ -68,10 +68,13 @@ public static function register()
6868
$attributes['domain'] = $domain;
6969
}
7070

71+
// Map the locale string to a prefix.
72+
$prefix = data_get(Config::get('localized-routes.custom_prefixes'), $locale, $locale);
73+
7174
// Prefix the URL unless the locale
7275
// is configured to be omitted.
7376
if ($domain === null && $locale !== $omitPrefix) {
74-
$attributes['prefix'] = $locale;
77+
$attributes['prefix'] = $prefix;
7578
}
7679

7780
if ($setMiddleware) {

tests/TestCase.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,18 @@ protected function setUseLocalizer($value)
115115
Config::set('localized-routes.use_localizer', $value);
116116
}
117117

118+
/**
119+
* Set the custom prefixes config option.
120+
*
121+
* @param array $prefixes
122+
*
123+
* @return void
124+
*/
125+
protected function setCustomPrefixes($prefixes)
126+
{
127+
Config::set('localized-routes.custom_prefixes', $prefixes);
128+
}
129+
118130
/**
119131
* Fake that we created a routes.php file in 'resources/lang/'
120132
* for each language with the given translations.

tests/Unit/Middleware/SetLocaleTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,26 @@ public function it_passes_the_supported_locales_to_localizer_in_the_correct_form
216216

217217
$localizer->shouldHaveReceived('setSupportedLocales')->with(['en', 'nl']);
218218
}
219+
220+
/** @test */
221+
public function it_sets_the_right_locale_with_custom_prefixes()
222+
{
223+
$this->setSupportedLocales(['en', 'nl']);
224+
$this->setCustomPrefixes(['en' => 'english', 'nl' => 'dutch']);
225+
$this->setUseLocaleMiddleware(true);
226+
227+
Route::localized(function () {
228+
Route::get('/', function () {
229+
return App::getLocale();
230+
});
231+
});
232+
233+
$response = $this->call('GET', '/english');
234+
$response->assertOk();
235+
$this->assertEquals('en', $response->original);
236+
237+
$response = $this->call('GET', '/dutch');
238+
$response->assertOk();
239+
$this->assertEquals('nl', $response->original);
240+
}
219241
}

tests/Unit/RedirectToLocalizedTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,33 @@ public function it_throws_404_and_does_not_redirect_if_no_localized_route_is_reg
7474
$this->setAppLocale('en');
7575
$this->get('missing')->assertNotFound();
7676
}
77+
78+
/** @test */
79+
public function it_redirects_to_the_localized_url_with_custom_prefixes()
80+
{
81+
$this->withoutExceptionHandling();
82+
$this->setSupportedLocales(['en', 'nl']);
83+
$this->setCustomPrefixes(['en' => 'english', 'nl' => 'dutch']);
84+
$this->setUseLocaleMiddleware(false);
85+
$this->setRedirectToLocalizedUrls(true);
86+
87+
Route::localized(function () {
88+
Route::get('/', function () {});
89+
Route::get('about', function () {});
90+
});
91+
92+
Route::fallback(\CodeZero\LocalizedRoutes\Controller\FallbackController::class);
93+
94+
$this->setAppLocale('en');
95+
$this->get('/')->assertRedirect('english');
96+
$this->get('english')->assertOk();
97+
$this->get('about')->assertRedirect('english/about');
98+
$this->get('english/about')->assertOk();
99+
100+
$this->setAppLocale('nl');
101+
$this->get('/')->assertRedirect('dutch');
102+
$this->get('dutch')->assertOk();
103+
$this->get('about')->assertRedirect('dutch/about');
104+
$this->get('dutch/about')->assertOk();
105+
}
77106
}

tests/Unit/RouteModelBindingTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,38 @@ public function it_loads_a_route_with_a_custom_localized_route_key_based_on_the_
7878
$this->get('en/test/en-slug')->assertOk();
7979
$this->get('en/test/nl-slug')->assertNotFound();
8080
}
81+
82+
/** @test */
83+
public function it_loads_a_route_with_a_localized_route_key_with_custom_prefixes()
84+
{
85+
$this->setSupportedLocales(['en', 'nl']);
86+
$this->setCustomPrefixes(['en' => 'english', 'nl' => 'dutch']);
87+
$this->setUseLocaleMiddleware(true);
88+
89+
$model = (new Model([
90+
'slug' => [
91+
'en' => 'en-slug',
92+
'nl' => 'nl-slug',
93+
],
94+
]))->setKeyName('slug');
95+
96+
App::instance(Model::class, $model);
97+
98+
Route::middleware(['web'])->get('test/{model}', function (Model $model) {});
99+
100+
Route::localized(function () {
101+
Route::middleware(['web'])->get('test/{model}', function (Model $model) {});
102+
});
103+
104+
$this->setAppLocale('nl');
105+
106+
$this->get('test/nl-slug')->assertOk();
107+
$this->get('test/en-slug')->assertNotFound();
108+
109+
$this->get('dutch/test/nl-slug')->assertOk();
110+
$this->get('dutch/test/en-slug')->assertNotFound();
111+
112+
$this->get('english/test/en-slug')->assertOk();
113+
$this->get('english/test/nl-slug')->assertNotFound();
114+
}
81115
}

tests/Unit/UrlGeneratorTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,23 @@ public function it_allows_routes_to_be_cached()
270270
$this->get('en/route')->assertSuccessful();
271271
}
272272

273+
/** @test */
274+
public function it_maps_locales_with_custom_prefixes()
275+
{
276+
$this->setSupportedLocales(['en', 'nl', 'fr']);
277+
278+
// Set custom prefixes for all locales except "fr"
279+
$this->setCustomPrefixes(['en' => 'english', 'nl' => 'dutch']);
280+
281+
$this->registerRoute('english/route', 'en.route');
282+
$this->registerRoute('dutch/route', 'nl.route');
283+
$this->registerRoute('fr/route', 'fr.route');
284+
285+
$this->assertEquals(url('english/route'), route('en.route'));
286+
$this->assertEquals(url('dutch/route'), route('nl.route'));
287+
$this->assertEquals(url('fr/route'), route('fr.route'));
288+
}
289+
273290
/**
274291
* Cache registered routes.
275292
*

0 commit comments

Comments
 (0)