Named routes in Laravel 4

Saturday, January 26, 2013

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.

blog comments powered by Disqus