Skip to content

Commit 5f52765

Browse files
committed
Support custom route keys with Route::localizedUrl()
1 parent 4e112f4 commit 5f52765

File tree

2 files changed

+61
-4
lines changed

2 files changed

+61
-4
lines changed

src/LocalizedUrlGenerator.php

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ protected function prepareParameters($locale, $parameters)
370370

371371
foreach ($parameters as $key => $parameter) {
372372
if ($parameter instanceof UrlRoutable) {
373-
$parameters[$key] = $this->getLocalizedRouteKey($parameter, $locale);
373+
$parameters[$key] = $this->getLocalizedRouteKey($key, $parameter, $locale);
374374
}
375375
}
376376

@@ -390,24 +390,47 @@ protected function getRouteParameters()
390390
/**
391391
* Get the localized route key from a model.
392392
*
393+
* @param string $key
393394
* @param \Illuminate\Contracts\Routing\UrlRoutable $model
394395
* @param string $locale
395396
*
396397
* @return string
397398
*/
398-
protected function getLocalizedRouteKey(UrlRoutable $model, $locale)
399+
protected function getLocalizedRouteKey($key, UrlRoutable $model, $locale)
399400
{
400401
$originalLocale = App::getLocale();
401402

402403
App::setLocale($locale);
403404

404-
$routeKey = $model->getRouteKey();
405+
$bindingField = $this->getBindingFieldFor($key, $model);
406+
$routeKey = $model->$bindingField;
405407

406408
App::setLocale($originalLocale);
407409

408410
return $routeKey;
409411
}
410412

413+
/**
414+
* Get the binding field for the current route.
415+
*
416+
* The binding field is the custom route key that you can define in your route:
417+
* Route::get('path/{model:key}')
418+
* If you did not use a custom key, use the default route key.
419+
*
420+
* @param string|int $key
421+
* @param \Illuminate\Contracts\Routing\UrlRoutable $model
422+
*
423+
* @return string|null
424+
*/
425+
protected function getBindingFieldFor($key, UrlRoutable $model)
426+
{
427+
if (App::version() < 7) {
428+
return $model->getRouteKeyName();
429+
}
430+
431+
return $this->route->bindingFieldFor($key) ?: $model->getRouteKeyName();
432+
}
433+
411434
/**
412435
* Get the locale that should be omitted in the URI path.
413436
*

tests/Unit/Macros/LocalizedUrlMacroTest.php

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
class LocalizedUrlMacroTest extends TestCase
1717
{
1818
/** @test */
19-
public function it_generates_urls_with_localized_route_keys_for_the_current_route_using_route_model_binding()
19+
public function it_generates_urls_with_default_localized_route_keys_for_the_current_route_using_route_model_binding()
2020
{
2121
$this->withoutExceptionHandling();
2222
$this->setSupportedLocales(['en', 'nl']);
@@ -49,6 +49,40 @@ public function it_generates_urls_with_localized_route_keys_for_the_current_rout
4949
], $response->original);
5050
}
5151

52+
/** @test */
53+
public function it_generates_urls_with_custom_localized_route_keys_for_the_current_route_using_route_model_binding()
54+
{
55+
$this->withoutExceptionHandling();
56+
$this->setSupportedLocales(['en', 'nl']);
57+
58+
$model = (new Model([
59+
'slug' => [
60+
'en' => 'en-slug',
61+
'nl' => 'nl-slug',
62+
],
63+
]))->setKeyName('id');
64+
65+
App::instance(Model::class, $model);
66+
67+
Route::localized(function () {
68+
Route::get('route/{model:slug}', function (Model $model) {
69+
return [
70+
'current' => Route::localizedUrl(),
71+
'en' => Route::localizedUrl('en'),
72+
'nl' => Route::localizedUrl('nl'),
73+
];
74+
})->middleware(['web']);
75+
});
76+
77+
$response = $this->call('GET', '/en/route/en-slug');
78+
$response->assertOk();
79+
$this->assertEquals([
80+
'current' => url('/en/route/en-slug'),
81+
'en' => url('/en/route/en-slug'),
82+
'nl' => url('/nl/route/nl-slug'),
83+
], $response->original);
84+
}
85+
5286
/** @test */
5387
public function you_can_implement_an_interface_and_let_your_model_return_custom_parameters_with_route_model_binding()
5488
{

0 commit comments

Comments
 (0)