diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a05b4f8..907433ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file, in reverse - [#132](https://github.com/zendframework/zend-expressive/pull/132) adds `Zend\Expressive\Router\ZendRouter`, replacing `Zend\Expressive\Router\Zf2Router`. -- [#139](https://github.com/zendframework/zend-expressive/pull/134) adds: +- [#139](https://github.com/zendframework/zend-expressive/pull/139) adds: - `Zend\Expressive\Template\TemplateRendererInterface`, replacing `Zend\Expressive\Template\TemplateInterface`. - `Zend\Expressive\Template\PlatesRenderer`, replacing @@ -18,6 +18,16 @@ All notable changes to this project will be documented in this file, in reverse `Zend\Expressive\Template\Twig`. - `Zend\Expressive\Template\ZendViewRenderer`, replacing `Zend\Expressive\Template\ZendView`. +- [#133](https://github.com/zendframework/zend-expressive/pull/133) adds a + stipulation to `Zend\Expressive\Router\RouterInterface` that `addRoute()` + should *aggregate* `Route` instances only, and delay injection until `match()` + and/or `generateUri()` are called; all shipped routers now follow this. This + allows manipulating `Route` instances before calling `match()` or + `generateUri()` — for instance, to inject options or a name. +- [#133](https://github.com/zendframework/zend-expressive/pull/133) re-instates + the `Route::setName()` method, as the changes to lazy-inject routes means that + setting names and options after adding them to the application now works + again. ### Deprecated @@ -28,7 +38,7 @@ All notable changes to this project will be documented in this file, in reverse - [#132](https://github.com/zendframework/zend-expressive/pull/132) removes `Zend\Expressive\Router\Zf2Router`, renaming it to `Zend\Expressive\Router\ZendRouter`. -- [#139](https://github.com/zendframework/zend-expressive/pull/134) removes: +- [#139](https://github.com/zendframework/zend-expressive/pull/139) removes: - `Zend\Expressive\Template\TemplateInterface`, renaming it to `Zend\Expressive\Template\TemplateRendererInterface`. - `Zend\Expressive\Template\Plates`, renaming it to diff --git a/doc/book/router/interface.md b/doc/book/router/interface.md index 85fb802b..4e531dd1 100644 --- a/doc/book/router/interface.md +++ b/doc/book/router/interface.md @@ -17,11 +17,27 @@ use Zend\Expressive\Exception; interface RouterInterface { /** + * Add a route. + * + * This method adds a route against which the underlying implementation may + * match. Implementations MUST aggregate route instances, but MUST NOT use + * the details to inject the underlying router until `match()` and/or + * `generateUri()` is called. This is required to allow consumers to + * modify route instances before matching (e.g., to provide route options, + * inject a name, etc.). + * * @param Route $route */ public function addRoute(Route $route); /** + * Match a request against the known routes. + * + * Implementations will aggregate required information from the provided + * request instance, and pass them to the underlying router implementation; + * when done, they will then marshal a `RouteResult` instance indicating + * the results of the matching operation and return it to the caller. + * * @param Request $request * @return RouteResult */ @@ -92,6 +108,13 @@ class Route */ public function getPath(); + /** + * Set the route name. + * + * @param string $name + */ + public function setName($name); + /** * @return string */ diff --git a/doc/book/router/uri-generation.md b/doc/book/router/uri-generation.md index ed77c54b..10692ee3 100644 --- a/doc/book/router/uri-generation.md +++ b/doc/book/router/uri-generation.md @@ -25,6 +25,13 @@ the name: $app->get('/foo', $middleware); // "foo^GET" ``` + Alternately, these methods return a `Route` instance, and you can set the + name on it: + + ```php + $app->get('/foo', $middleware)->setName('foo'); // "foo" + ``` + - If you call `route()` and specify a list of HTTP methods accepted, the name will be the literal path, followed by a caret (`^`), followed by a colon (`:`)-separated list of the uppercase HTTP method names, in the order in which @@ -34,6 +41,14 @@ the name: $app->route('/foo, $middleware', ['GET', 'POST']); // "foo^GET:POST" ``` + Like the HTTP-specific methods, `route()` also returns a `Route` instance, + and you can set the name on it: + + ```php + $route = $app->route('/foo, $middleware', ['GET', 'POST']); // "foo^GET:POST" + $route->setName('foo'); // "foo" + ``` + Clearly, this can become difficult to remember. As such, Expressive offers the ability to specify a custom string for the route name as an additional, optional argument to any of the above: @@ -44,6 +59,15 @@ $app->get('/foo/:id', $middleware, 'foo-item'); // 'foo-item' $app->route('/foo', $middleware, ['GET', 'POST'], 'foo-collection'); // 'foo-collection' ``` +As noted above, these methods also return `Route` instances, allowing you to +set the name after-the-fact; this is particularly useful with the `route()` +method, where you may want to omit the HTTP methods if any HTTP method is +allowed: + +```php +$app->route('/foo', $middleware)->setName('foo'); // 'foo' +``` + We recommend that if you plan on generating URIs for given routes, you provide a custom name. diff --git a/src/Router/Route.php b/src/Router/Route.php index 9f433eca..e561fc9e 100644 --- a/src/Router/Route.php +++ b/src/Router/Route.php @@ -102,6 +102,16 @@ public function getPath() return $this->path; } + /** + * Set the route name. + * + * @param string $name + */ + public function setName($name) + { + $this->name = (string) $name; + } + /** * @return string */ diff --git a/src/Router/RouterInterface.php b/src/Router/RouterInterface.php index 31f3f44a..ea6abe0e 100644 --- a/src/Router/RouterInterface.php +++ b/src/Router/RouterInterface.php @@ -22,9 +22,10 @@ interface RouterInterface * * This method adds a route against which the underlying implementation may * match. Implementations MUST aggregate route instances, but MUST NOT use - * the details to inject the underlying router until `match()` is called. - * This is required to allow consumers to modify route instances before - * matching (e.g., to provide route options, inject a name, etc.). + * the details to inject the underlying router until `match()` and/or + * `generateUri()` is called. This is required to allow consumers to + * modify route instances before matching (e.g., to provide route options, + * inject a name, etc.). * * @param Route $route */