Named routes in Laravel 4
I've been doing some work with PHP & Laravel 4, and had an idea to make naming routes a bit nicer syntactically. Currently, to name a route you wrap the 2nd parameter in an array and add an item with an 'as' key, as in:
Route::get('user/profile', array('as' => 'profile', function(){// code here..}));
I think it'd be more natural to set the name using a method on the route (similar to adding a where() condition) , something like:
Route::get('user/profile', function(){// code here..}) ->named('profile');
After a bit of poking around, I found this could be done fairly easily with a couple small additions to Route and Router to allow for renaming a route:
--- a/vendor/laravel/framework/src/Illuminate/Routing/Route.php Fri Jan 25 15:35:04 2013 -0600 +++ b/vendor/laravel/framework/src/Illuminate/Routing/Route.php Sat Jan 26 16:37:08 2013 -0600 @@ -411,4 +411,16 @@ return $this; } -} + /** + * Change the name for this route. + * + * @param string $name New Name + * @return Illuminate\Routing\Route + */ + public function named($name) + { + $this->router->rename($this, $name); + + return $this; + } +} \ No newline at end of file diff -r 50adf81e2f0f vendor/laravel/framework/src/Illuminate/Routing/Router.php --- a/vendor/laravel/framework/src/Illuminate/Routing/Router.php Fri Jan 25 15:35:04 2013 -0600 +++ b/vendor/laravel/framework/src/Illuminate/Routing/Router.php Sat Jan 26 16:37:08 2013 -0600 @@ -1159,4 +1159,21 @@ $this->container = $container; } + /** + * Change the name of a route + * + * @param $route + * @param $name + * @return void + */ + public function rename($route, $name) + { + foreach($this->routes->getIterator() as $n => $r) { + if ($r === $route) { + $this->routes->remove($n); + $this->routes->add($name, $r); + return; + } + } + } }
It's not the most efficient thing in the world to be iterating over all the previous routes. A small optimization would be to check the last-added route first, in the example usage that'd be the one you're renaming. But to do that would require also patching Symfony's RouteCollection
class.